Compare commits

..

45 Commits
v1.17 ... v1.18

Author SHA1 Message Date
0056ccce26 Version number 2014-12-10 23:40:25 +00:00
486506e37f Update README.md 2014-12-10 23:39:48 +00:00
e9e0e36f98 New and better Set[Next]Window(Pos|Size|Collapsed) API.
Removed rarely useful SetNewWindowDefaultPos() in favor of new API.
2014-12-10 19:22:30 +00:00
3399890a84 Added ImGuiWindowFlags_NoSavedSettings flag + Fixed overlay example app. 2014-12-10 17:13:45 +00:00
2a3bff9a82 Comments 2014-12-10 16:56:11 +00:00
09bacfbe18 OpenGL example: allow resizing window. 2014-12-10 15:27:40 +00:00
cca5f473ca Clarified comment 2014-12-08 17:18:20 +00:00
6523fb263d OpenGL3 example: fixed mouse handling. 2014-12-08 17:15:08 +00:00
bdb2344db0 ImGuiStorage helper can store float + added functions to get pointer to data. Exposed ImGui::GetId() - may be misleading? 2014-12-08 17:14:54 +00:00
0a0769227d Added Travis CI build banner. 2014-12-07 10:17:39 +00:00
6252b26af2 Update README.md 2014-12-07 10:15:34 +00:00
987188d437 Fix Clang warning with offsetof() macro? Added -Wall in OpenGL 3 example. 2014-12-07 09:58:45 +00:00
71e20680db Setup Travis CI integration with Clang + -Wall in Makefiles 2014-12-07 09:48:01 +00:00
bb20065be0 Setup Travis CI integration
Getting there!
2014-12-06 23:30:38 +00:00
fec067d033 Setup Travis CI integration
More libs needed
2014-12-06 23:27:40 +00:00
2eb837ea86 Setup Travis CI integration
Different PPA source
2014-12-06 23:23:57 +00:00
857a4e364c Setup Travis CI integration
Yes please
2014-12-06 23:21:05 +00:00
2599849e9c Setup Travis CI integration
Trying again with a PPA for glfw3-dev
2014-12-06 23:17:30 +00:00
da1b8f7e46 Setup Travis CI integration
Argh.
2014-12-06 23:06:04 +00:00
0687af2ce5 Setup Travis CI integration
Failing to get glfw3 for ubuntu, trying osx/gcc
2014-12-06 23:01:41 +00:00
1d45478637 Setup Travis CI integration
Argh.
2014-12-06 21:06:00 +00:00
1bfb59174a Setup Travis CI integration
Apt-get update needed..
2014-12-06 21:04:25 +00:00
83575a464f Setup Travis CI integration
Forgot sudo. Removing apt-get update, probably works without.
2014-12-06 21:01:00 +00:00
3e83de58b5 Setup Travis CI integration 2014-12-06 20:59:14 +00:00
2b0d8447e3 Setup Travis CI integration
Testing
2014-12-06 20:56:34 +00:00
d553cd96b0 Setup Travis CI integration
Testing.
2014-12-06 20:50:27 +00:00
30ee2fed2b Merge branch 'master' of https://github.com/ocornut/imgui 2014-12-06 20:43:13 +00:00
036ed3ea93 OpenGL3 example: unregistered mouse callback for mouse click-release faster than frame interval. 2014-12-06 20:43:08 +00:00
123691023b Merge pull request #94 from emoon/master
Clang warning fixes
2014-12-06 12:59:22 +00:00
317dab5269 Clang warning fixes 2014-12-06 13:49:46 +01:00
e43cd6e97f Added IMGUI_INCLUDE_IMGUI_USER_H 2014-12-05 23:09:43 +00:00
a5cc2e4161 Fixed InputInt() writing to output when it doesn't need to, which break with large int due to int<>float conversions. Added todo note. 2014-12-05 12:34:14 +00:00
6b16424faf Comments. 2014-12-04 11:54:49 +00:00
d133831909 In-code FAQ: added comment about reading WantCaptureMouse / WantCaptureKeyboard 2014-12-04 11:42:13 +00:00
2e5b81627f Examples: DirectX11: moved shader to be close to its usage location, 2014-12-03 18:46:13 +00:00
52b5376d9b Examples: OpenGL3: cleaned up to match features of OpenGL2 example 2014-12-03 18:40:28 +00:00
b02eed3e49 Examples: adding title to the top of each examples. Cleaning up file headers. 2014-12-03 18:29:46 +00:00
90b4ff13fb Ignore list. 2014-12-03 18:19:48 +00:00
6c9edb6db0 Examples: removed LICENSE file from MSVC project. 2014-12-03 18:19:05 +00:00
860cf578f5 Added ImGuiWindowFlags_NoScrollWithMouse flag.
ButtonBehaviour test hovering of CurrentRootWindow (vs CurrentWindow, different for child-windows). This is intentionally meant to fix grabbing the lower-right resize grip when lower-right corner has a child-window, but may be the overall right-er test. Testing out.
2014-12-03 18:17:10 +00:00
e0dc8ac910 Merge pull request #93 from olivierchatry/master
Added OpenGL programmable-pipeline example.
2014-12-03 18:15:42 +00:00
2f176033c6 fixed indentation mix, removed some unused code, updated different callback using the example_opengl code. 2014-12-03 19:11:23 +01:00
a8d2bc69ed added opengl3 sample, mix from @ocornut and @thelinked 2014-12-03 18:37:07 +01:00
63ff0ad0ff Examples: OpenGL: fix accessing libraries via ProjectDir instead of SolutionDir 2014-12-03 12:00:03 +00:00
d31623061f ImVector: private -> protected 2014-12-03 11:56:40 +00:00
21 changed files with 1017 additions and 225 deletions

3
.gitignore vendored
View File

@ -11,6 +11,9 @@ examples/directx11_example/ipch/*
examples/opengl_example/Debug/*
examples/opengl_example/Release/*
examples/opengl_example/ipch/*
examples/opengl3_example/Debug/*
examples/opengl3_example/Release/*
examples/opengl3_example/ipch/*
*.opensdf
*.sdf
*.suo

17
.travis.yml Normal file
View File

@ -0,0 +1,17 @@
language: cpp
os:
- linux
compiler:
- gcc
- clang
before_install:
- if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libglew-dev libxrandr-dev libxi-dev libxxf86vm-dev; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glew && brew install glfw3; fi
script:
- make -C examples/opengl_example
- make -C examples/opengl3_example

View File

@ -1,13 +1,22 @@
ImGui
=====
[![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui)
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies. It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
After ImGui is setup in your engine, you can use it like in this example:
ImGui is self-contained within 4 files that you can easily copy and compile into your application/engine:
- imgui.cpp
- imgui.h
- imconfig.h (empty by default, user-editable)
- stb_textedit.h
Your code passes mouse/keyboard inputs and settings to ImGui (see example applications for more details). After ImGui is setup, you can use it like in this example:
![screenshot of sample code alongside its output with ImGui](/web/code_sample_01.png?raw=true)
@ -39,6 +48,10 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
Frequently Asked Question
-------------------------
<b>Where is example code?</b>
The bulk of actual ImGui usage code is contained within the ImGui::ShowTestWindow() function. It covers most featurse of ImGui so you can read its source code and call the function itself to see its output. Ready-to-go example applications covering different versions of OpenGL/DirectX are provided in the examples/ folder.
<b>How do you use ImGui on a platform that may not have a mouse or keyboard?</b>
I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running you can seamlessly use your PC input devices from a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.

View File

@ -75,9 +75,6 @@
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -30,9 +30,4 @@
<Filter>sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -1,3 +1,5 @@
// ImGui - standalone example application for DirectX 11
#include <windows.h>
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // for .png loading
@ -11,9 +13,6 @@
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
extern const char* vertexShader; // Implemented at the bottom
extern const char* pixelShader;
static HWND hWnd;
static ID3D11Device* g_pd3dDevice = NULL;
static ID3D11DeviceContext* g_pd3dDeviceImmediateContext = NULL;
@ -220,6 +219,34 @@ HRESULT InitDeviceD3D(HWND hWnd)
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(c0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL);
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return E_FAIL;
@ -250,6 +277,22 @@ HRESULT InitDeviceD3D(HWND hWnd)
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = texture0.Sample(sampler0, input.uv);\
return input.col * out_col;\
}";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL);
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return E_FAIL;
@ -545,7 +588,7 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
@ -561,47 +604,3 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
return 0;
}
static const char* vertexShader = "\
cbuffer vertexBuffer : register(c0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
static const char* pixelShader = "\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = texture0.Sample(sampler0, input.uv);\
return input.col * out_col;\
}";

View File

@ -78,9 +78,6 @@
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{ac86c4ce-1d96-47a9-9ace-f8970c3bd485}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="imgui">
<UniqueIdentifier>{a82cba23-9de0-45c2-b1e3-2eb1666702de}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -28,9 +28,4 @@
<Filter>imgui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -1,3 +1,5 @@
// ImGui - standalone example application for DirectX 9
#include <windows.h>
#include "../../imgui.h"
@ -328,7 +330,7 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}

View File

@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx11_example", "directx11_example\directx11_example.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl3_example", "opengl3_example\opengl3_example.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -25,6 +27,10 @@ Global
{9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.Build.0 = Debug|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.ActiveCfg = Release|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.ActiveCfg = Debug|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.Build.0 = Debug|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.ActiveCfg = Release|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,52 @@
#
# Cross Platform Make file
#
# Compatible with Ubuntu 14.04.1 and Mac OS X
#
#
# if you using Mac OS X:
# You should install glew via homebrew
# brew install glew
# Also you'll need glfw
# http://www.glfw.org
#
#CXX = g++
OBJS = main.o
OBJS += ../../imgui.o
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
CXXFLAGS += -Wall
LIBS = `pkg-config --static --libs glfw3` -lGLEW
endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/lib
LIBS += -lglew -lglfw3
CXXFLAGS = -I../../ -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -Wall
# CXXFLAGS += -D__APPLE__
endif
.cpp.o:
$(CXX) $(CXXFLAGS) -c -o $@ $<
all:imgui_example
@echo Build complete for $(ECHO_MESSAGE)
imgui_example:$(OBJS)
$(CXX) -o imgui_example $(OBJS) $(CXXFLAGS) $(LIBS)
clean:
rm $(OBJS)

View File

@ -0,0 +1,388 @@
// ImGui - standalone example application for OpenGL 3, using programmable pipeline
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif
#include "../../imgui.h"
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // stb_image.h for PNG loading
// Glfw/Glew
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
static GLFWwindow* window;
static GLuint fontTex;
static bool mousePressed[2] = { false, false };
// Shader variables
static int shader_handle, vert_handle, frag_handle;
static int texture_location, ortho_location;
static int position_location, uv_location, colour_location;
static size_t vbo_max_size = 20000;
static unsigned int vbo_handle, vao_handle;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.0f or 0.5f
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
if (cmd_lists_count == 0)
return;
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
// Setup texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fontTex);
// Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
const float ortho_projection[4][4] =
{
{ 2.0f/width, 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/-height, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ -1.0f, 1.0f, 0.0f, 1.0f },
};
glUseProgram(shader_handle);
glUniform1i(texture_location, 0);
glUniformMatrix4fv(ortho_location, 1, GL_FALSE, &ortho_projection[0][0]);
// Grow our buffer according to what we need
size_t total_vtx_count = 0;
for (int n = 0; n < cmd_lists_count; n++)
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
size_t neededBufferSize = total_vtx_count * sizeof(ImDrawVert);
if (neededBufferSize > vbo_max_size)
{
vbo_max_size = neededBufferSize + 5000; // Grow buffer
glBufferData(GL_ARRAY_BUFFER, neededBufferSize, NULL, GL_STREAM_DRAW);
}
// Copy and convert all vertices into a single contiguous buffer
unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!buffer_data)
return;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao_handle);
int cmd_offset = 0;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
int vtx_offset = cmd_offset;
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vtx_offset += pcmd->vtx_count;
}
cmd_offset = vtx_offset;
}
// Restore modified state
glBindVertexArray(0);
glUseProgram(0);
glDisable(GL_SCISSOR_TEST);
glBindTexture(GL_TEXTURE_2D, 0);
}
static const char* ImImpl_GetClipboardTextFn()
{
return glfwGetClipboardString(window);
}
static void ImImpl_SetClipboardTextFn(const char* text)
{
glfwSetClipboardString(window, text);
}
// GLFW callbacks to get events
static void glfw_error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (action == GLFW_PRESS && button >= 0 && button < 2)
mousePressed[button] = true;
}
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
}
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
ImGuiIO& io = ImGui::GetIO();
if (action == GLFW_PRESS)
io.KeysDown[key] = true;
if (action == GLFW_RELEASE)
io.KeysDown[key] = false;
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
}
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
{
if (c > 0 && c < 0x10000)
ImGui::GetIO().AddInputCharacter((unsigned short)c);
}
// OpenGL code based on http://open.gl tutorials
void InitGL()
{
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
exit(1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
glfwSetMouseButtonCallback(window, glfw_mouse_button_callback);
glfwSetScrollCallback(window, glfw_scroll_callback);
glfwSetCharCallback(window, glfw_char_callback);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
const GLchar *vertex_shader =
"#version 330\n"
"uniform mat4 ortho;\n"
"in vec2 Position;\n"
"in vec2 UV;\n"
"in vec4 Colour;\n"
"out vec2 Frag_UV;\n"
"out vec4 Frag_Colour;\n"
"void main()\n"
"{\n"
" Frag_UV = UV;\n"
" Frag_Colour = Colour;\n"
" gl_Position = ortho*vec4(Position.xy,0,1);\n"
"}\n";
const GLchar* fragment_shader =
"#version 330\n"
"uniform sampler2D Texture;\n"
"in vec2 Frag_UV;\n"
"in vec4 Frag_Colour;\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = Frag_Colour * texture( Texture, Frag_UV.st);\n"
"}\n";
shader_handle = glCreateProgram();
vert_handle = glCreateShader(GL_VERTEX_SHADER);
frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vert_handle, 1, &vertex_shader, 0);
glShaderSource(frag_handle, 1, &fragment_shader, 0);
glCompileShader(vert_handle);
glCompileShader(frag_handle);
glAttachShader(shader_handle, vert_handle);
glAttachShader(shader_handle, frag_handle);
glLinkProgram(shader_handle);
texture_location = glGetUniformLocation(shader_handle, "Texture");
ortho_location = glGetUniformLocation(shader_handle, "ortho");
position_location = glGetAttribLocation(shader_handle, "Position");
uv_location = glGetAttribLocation(shader_handle, "UV");
colour_location = glGetAttribLocation(shader_handle, "Colour");
glGenBuffers(1, &vbo_handle);
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &vao_handle);
glBindVertexArray(vao_handle);
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
glEnableVertexAttribArray(position_location);
glEnableVertexAttribArray(uv_location);
glEnableVertexAttribArray(colour_location);
glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(colour_location, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void InitImGui()
{
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = 1.0f / 60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.5f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
// Load font texture
glGenTextures(1, &fontTex);
glBindTexture(GL_TEXTURE_2D, fontTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
stbi_image_free(tex_data);
}
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup resolution (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
// Setup time step
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels
mouse_y *= (float)display_h / h;
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
// Start the frame
ImGui::NewFrame();
}
// Application code
int main(int argc, char** argv)
{
InitGL();
InitImGui();
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = 0;
mousePressed[0] = mousePressed[1] = false;
glfwPollEvents();
UpdateImGui();
static bool show_test_window = true;
static bool show_another_window = false;
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show frame rate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui::Render();
glfwSwapBuffers(window);
}
// Cleanup
if (vao_handle) glDeleteVertexArrays(1, &vao_handle);
if (vbo_handle) glDeleteBuffers(1, &vbo_handle);
glDetachShader(shader_handle, vert_handle);
glDetachShader(shader_handle, frag_handle);
glDeleteShader(vert_handle);
glDeleteShader(frag_handle);
glDeleteProgram(shader_handle);
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9}</ProjectGuid>
<RootNamespace>opengl3_example</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\opengl_example\glfw\include;$(ProjectDir)..\opengl_example\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(ProjectDir)..\opengl_example\glfw\lib-msvc100;$(ProjectDir)..\opengl_example\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\opengl_example\glfw\include;$(ProjectDir)..\opengl_example\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(ProjectDir)..\opengl_example\glfw\lib-msvc100;$(ProjectDir)..\opengl_example\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{20b90ce4-7fcb-4731-b9a0-075f875de82d}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{f18ab499-84e1-499f-8eff-9754361e0e52}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\stb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -11,7 +11,7 @@
# http://www.glfw.org
#
CXX = g++
#CXX = g++
OBJS = main.o
OBJS += ../../imgui.o
@ -22,6 +22,7 @@ UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
CXXFLAGS += -Wall
LIBS = `pkg-config --static --libs glfw3` -lGLEW
endif
@ -32,11 +33,9 @@ ifeq ($(UNAME_S), Darwin) #APPLE
LIBS += -L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/lib
LIBS += -lglew -lglfw3
CXXFLAGS = -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -I../../
CXXFLAGS = -I../../ -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -Wall
# CXXFLAGS += -D__APPLE__
endif
.cpp.o:

View File

@ -1,25 +1,22 @@
// ImGui - standalone example application for OpenGL 2, using fixed pipeline
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#include <Windows.h>
#endif
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // for .png loading
#include "../../imgui.h"
// glew & glfw
#include "../../imgui.h"
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // stb_image.h for PNG loading
// Glfw/Glew
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#ifdef _MSC_VER
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
static GLFWwindow* window;
static GLuint fontTex;
static bool mousePressed[2] = { false, false };
static ImVec2 mousePosScale(1.0f, 1.0f);
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
@ -63,9 +60,9 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
{
const ImDrawList* cmd_list = cmd_lists[n];
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, col)));
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col)));
int vtx_offset = 0;
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
@ -142,7 +139,6 @@ void InitGL()
if (!glfwInit())
exit(1);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
@ -155,15 +151,7 @@ void InitGL()
void InitImGui()
{
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
mousePosScale.x = (float)display_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates.
mousePosScale.y = (float)display_h / h;
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
@ -230,6 +218,13 @@ void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup resolution (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
// Setup time step
static double time = 0.0f;
const double current_time = glfwGetTime();
@ -240,7 +235,9 @@ void UpdateImGui()
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x * mousePosScale.x, (float)mouse_y * mousePosScale.y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels
mouse_y *= (float)display_h / h;
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
@ -296,7 +293,7 @@ int main(int argc, char** argv)
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
@ -308,7 +305,9 @@ int main(int argc, char** argv)
glfwSwapBuffers(window);
}
// Cleanup
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -41,11 +41,11 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)\glfw\include;$(SolutionDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)\glfw\include;$(ProjectDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ProjectDir)\glfw\lib-msvc100;$(ProjectDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
@ -56,13 +56,13 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)\glfw\include;$(SolutionDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)\glfw\include;$(ProjectDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ProjectDir)\glfw\lib-msvc100;$(ProjectDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
@ -77,9 +77,6 @@
<ClInclude Include="..\..\stb_textedit.h" />
<ClInclude Include="..\shared\stb_image.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -31,9 +31,4 @@
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -20,6 +20,9 @@
//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
//#define IMGUI_INCLUDE_IMGUI_USER_INL
//---- Include imgui_user.h at the end of imgui.h
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
/*
#define IM_VEC2_CLASS_EXTRA \

328
imgui.cpp
View File

@ -1,4 +1,4 @@
// ImGui library v1.17 wip
// ImGui library v1.18
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui
@ -36,6 +36,7 @@
- limited layout features, intricate layouts are typically crafted in code
- occasionally use statically sized buffers for string manipulations - won't crash, but some long text may be clipped
END-USER GUIDE
==============
@ -58,6 +59,7 @@
- ESCAPE to revert text to its original value
- You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)
PROGRAMMER GUIDE
================
@ -105,12 +107,17 @@
// swap video buffer, etc.
}
- after calling ImGui::NewFrame() you can read back 'ImGui::GetIO().WantCaptureMouse' and 'ImGui::GetIO().WantCaptureKeyboard' to tell
if ImGui wants to use your inputs. so typically can hide the mouse inputs from the rest of your application if ImGui is using it.
API BREAKING CHANGES
====================
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
- 2014/12/10 (1.18) removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver)
- 2014/11/28 (1.17) moved IO.Font*** options to inside the IO.Font-> structure.
- 2014/11/26 (1.17) reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility
- 2014/11/07 (1.15) renamed IsHovered() to IsItemHovered()
@ -122,6 +129,7 @@
- 2014/08/30 (1.09) moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite
- 2014/08/28 (1.09) changed the behavior of IO.PixelCenterOffset following various rendering fixes
TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS
============================================
@ -179,6 +187,7 @@
- tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
- tip: read the ShowTestWindow() code for more example of how to use ImGui!
ISSUES & TODO-LIST
==================
@ -193,7 +202,8 @@
- main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- scrollbar: use relative mouse movement when first-clicking inside of scroll grab box.
- scrollbar: make the grab visible and a minimum size for long scroll regions
- input number: optional range min/max
!- input number: very large int not reliably supported because of int<>float conversions.
- input number: optional range min/max for Input*() functions
- input number: holding [-]/[+] buttons should increase the step non-linearly
- input number: use mouse wheel to step up/down
- layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper.
@ -757,16 +767,21 @@ struct ImGuiState
ImVector<ImGuiWindow*> CurrentWindowStack;
ImGuiWindow* FocusedWindow; // Will catch keyboard inputs
ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredWindowExcludingChilds; // Will catch mouse inputs (for focus/move only)
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
ImGuiID HoveredId;
ImGuiID ActiveId;
ImGuiID ActiveIdPreviousFrame;
bool ActiveIdIsAlive;
float SettingsDirtyTimer;
ImVector<ImGuiIniData*> Settings;
ImVec2 NewWindowDefaultPos;
ImVector<ImGuiColMod> ColorModifiers;
ImVector<ImGuiStyleMod> StyleModifiers;
ImVec2 SetNextWindowPosVal;
ImGuiSetCondition SetNextWindowPosCond;
ImVec2 SetNextWindowSizeVal;
ImGuiSetCondition SetNextWindowSizeCond;
bool SetNextWindowCollapsedVal;
ImGuiSetCondition SetNextWindowCollapsedCond;
// Render
ImVector<ImDrawList*> RenderDrawLists;
@ -794,10 +809,15 @@ struct ImGuiState
CurrentWindow = NULL;
FocusedWindow = NULL;
HoveredWindow = NULL;
HoveredWindowExcludingChilds = NULL;
HoveredRootWindow = NULL;
ActiveIdIsAlive = false;
SettingsDirtyTimer = 0.0f;
NewWindowDefaultPos = ImVec2(60, 60);
SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
SetNextWindowPosCond = 0;
SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
SetNextWindowSizeCond = 0;
SetNextWindowCollapsedVal = false;
SetNextWindowCollapsedCond = 0;
SliderAsInputTextId = 0;
ActiveComboID = 0;
memset(Tooltip, 0, sizeof(Tooltip));
@ -830,6 +850,9 @@ struct ImGuiWindow
bool SkipItems; // == Visible && !Collapsed
int AutoFitFrames;
bool AutoFitOnlyGrows;
int SetWindowPosAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowPos() call is allowed with this particular flag.
int SetWindowSizeAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowSize() call is allowed with this particular flag.
int SetWindowCollapsedAllowFlags; // bit ImGuiSetCondition_*** specify if SetWindowCollapsed() call is allowed with this particular flag.
ImGuiDrawContext DC;
ImVector<ImGuiID> IDStack;
@ -837,8 +860,9 @@ struct ImGuiWindow
int LastFrameDrawn;
float ItemWidthDefault;
ImGuiStorage StateStorage;
float FontWindowScale; // Scale multipler per-window
float FontWindowScale; // Scale multiplier per-window
ImDrawList* DrawList;
ImGuiWindow* RootWindow;
// Focus
int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
@ -849,7 +873,7 @@ struct ImGuiWindow
int FocusIdxTabRequestNext; // "
public:
ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size);
ImGuiWindow(const char* name);
~ImGuiWindow();
ImGuiID GetID(const char* str);
@ -914,46 +938,66 @@ static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::
return first;
}
int* ImGuiStorage::Find(ImU32 key)
int ImGuiStorage::GetInt(ImU32 key, int default_val) const
{
ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
if (it == Data.end() || it->key != key)
return default_val;
return it->val_i;
}
float ImGuiStorage::GetFloat(ImU32 key, float default_val) const
{
ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
if (it == Data.end() || it->key != key)
return default_val;
return it->val_f;
}
int* ImGuiStorage::GetIntPtr(ImGuiID key, int default_val)
{
ImVector<Pair>::iterator it = LowerBound(Data, key);
if (it == Data.end())
return NULL;
if (it->key != key)
return NULL;
return &it->val;
if (it == Data.end() || it->key != key)
it = Data.insert(it, Pair(key, default_val));
return &it->val_i;
}
int ImGuiStorage::GetInt(ImU32 key, int default_val)
float* ImGuiStorage::GetFloatPtr(ImGuiID key, float default_val)
{
int* pval = Find(key);
if (!pval)
return default_val;
return *pval;
ImVector<Pair>::iterator it = LowerBound(Data, key);
if (it == Data.end() || it->key != key)
it = Data.insert(it, Pair(key, default_val));
return &it->val_f;
}
// FIXME-OPT: We are wasting time because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place.
// FIXME-OPT: Wasting CPU because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place.
// However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed.
void ImGuiStorage::SetInt(ImU32 key, int val)
{
ImVector<Pair>::iterator it = LowerBound(Data, key);
if (it != Data.end() && it->key == key)
if (it == Data.end() || it->key != key)
{
it->val = val;
Data.insert(it, Pair(key, val));
return;
}
else
it->val_i = val;
}
void ImGuiStorage::SetFloat(ImU32 key, float val)
{
ImVector<Pair>::iterator it = LowerBound(Data, key);
if (it == Data.end() || it->key != key)
{
Pair pair_key;
pair_key.key = key;
pair_key.val = val;
Data.insert(it, pair_key);
Data.insert(it, Pair(key, val));
return;
}
it->val_f = val;
}
void ImGuiStorage::SetAllInt(int v)
{
for (size_t i = 0; i < Data.size(); i++)
Data[i].val = v;
Data[i].val_i = v;
}
//-----------------------------------------------------------------------------
@ -1073,15 +1117,14 @@ void ImGuiTextBuffer::append(const char* fmt, ...)
//-----------------------------------------------------------------------------
ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size)
ImGuiWindow::ImGuiWindow(const char* name)
{
Name = ImStrdup(name);
ID = GetID(name);
IDStack.push_back(ID);
PosFloat = default_pos;
Pos = ImVec2((float)(int)PosFloat.x, (float)(int)PosFloat.y);
Size = SizeFull = default_size;
PosFloat = Pos = ImVec2(0.0f, 0.0f);
Size = SizeFull = ImVec2(0.0f, 0.0f);
SizeContentsFit = ImVec2(0.0f, 0.0f);
ScrollY = 0.0f;
NextScrollY = 0.0f;
@ -1092,6 +1135,8 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si
SkipItems = false;
AutoFitFrames = -1;
AutoFitOnlyGrows = false;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCondition_Always | ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver;
LastFrameDrawn = -1;
ItemWidthDefault = 0.0f;
FontWindowScale = 1.0f;
@ -1210,20 +1255,24 @@ void* ImGui::MemRealloc(void* ptr, size_t sz)
static ImGuiIniData* FindWindowSettings(const char* name)
{
ImGuiState& g = GImGui;
for (size_t i = 0; i != g.Settings.size(); i++)
{
ImGuiIniData* ini = g.Settings[i];
if (ImStricmp(ini->Name, name) == 0)
return ini;
}
return NULL;
}
static ImGuiIniData* AddWindowSettings(const char* name)
{
ImGuiIniData* ini = (ImGuiIniData*)ImGui::MemAlloc(sizeof(ImGuiIniData));
new(ini) ImGuiIniData();
ini->Name = ImStrdup(name);
ini->Collapsed = false;
ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
ini->Size = ImVec2(0,0);
g.Settings.push_back(ini);
GImGui.Settings.push_back(ini);
return ini;
}
@ -1280,6 +1329,8 @@ static void LoadSettings()
char name[64];
ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1);
settings = FindWindowSettings(name);
if (!settings)
settings = AddWindowSettings(name);
}
else if (settings)
{
@ -1310,7 +1361,7 @@ static void SaveSettings()
for (size_t i = 0; i != g.Windows.size(); i++)
{
ImGuiWindow* window = g.Windows[i];
if (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
continue;
ImGuiIniData* settings = FindWindowSettings(window->Name);
settings->Pos = window->Pos;
@ -1445,7 +1496,7 @@ void ImGui::NewFrame()
}
g.HoveredWindow = FindHoveredWindow(g.IO.MousePos, false);
g.HoveredWindowExcludingChilds = FindHoveredWindow(g.IO.MousePos, true);
g.HoveredRootWindow = FindHoveredWindow(g.IO.MousePos, true);
// Are we using inputs? Tell user so they can capture/discard them.
g.IO.WantCaptureMouse = (g.HoveredWindow != NULL) || (g.ActiveId != 0);
@ -1474,8 +1525,11 @@ void ImGui::NewFrame()
else
{
// Scroll
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * scroll_lines;
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
{
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * scroll_lines;
}
}
}
@ -1521,7 +1575,7 @@ void ImGui::Shutdown()
g.RenderDrawLists.clear();
g.FocusedWindow = NULL;
g.HoveredWindow = NULL;
g.HoveredWindowExcludingChilds = NULL;
g.HoveredRootWindow = NULL;
for (size_t i = 0; i < g.Settings.size(); i++)
{
g.Settings[i]->~ImGuiIniData();
@ -1993,13 +2047,6 @@ void ImGui::SetTooltip(const char* fmt, ...)
va_end(args);
}
// Position new window if they don't have position setting in the .ini file. Rarely useful (used by the sample applications).
void ImGui::SetNewWindowDefaultPos(const ImVec2& pos)
{
ImGuiState& g = GImGui;
g.NewWindowDefaultPos = pos;
}
float ImGui::GetTime()
{
return GImGui.Time;
@ -2021,7 +2068,7 @@ static ImGuiWindow* FindWindow(const char* name)
void ImGui::BeginTooltip()
{
ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.9f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_Tooltip);
ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.9f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_Tooltip);
}
void ImGui::EndTooltip()
@ -2035,7 +2082,7 @@ void ImGui::BeginChild(const char* str_id, ImVec2 size, bool border, ImGuiWindow
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_ChildWindow;
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
const ImVec2 content_max = window->Pos + ImGui::GetContentRegionMax();
const ImVec2 cursor_pos = window->Pos + ImGui::GetCursorPos();
@ -2069,6 +2116,7 @@ void ImGui::EndChild()
{
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow);
if (window->Flags & ImGuiWindowFlags_ComboBox)
{
ImGui::End();
@ -2087,7 +2135,10 @@ void ImGui::EndChild()
}
}
// Push a new ImGui window to add widgets to. This can be called multiple times with the same window to append contents
// Push a new ImGui window to add widgets to.
// A default window called "Debug" is automatically stacked at the beginning of every frame.
// This can be called multiple times with the same window name to append content to the same window.
// Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCondition_FirstUseEver) prior to calling Begin().
bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWindowFlags flags)
{
ImGuiState& g = GImGui;
@ -2097,22 +2148,35 @@ bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, I
ImGuiWindow* window = FindWindow(name);
if (!window)
{
// Create window the first time, and load settings
if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
// Create window the first time
if (flags & ImGuiWindowFlags_NoSavedSettings)
{
// Tooltip and child windows don't store settings
window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
new(window) ImGuiWindow(name, ImVec2(0,0), size);
new(window) ImGuiWindow(name);
window->Size = window->SizeFull = size;
}
else
{
// Normal windows store settings in .ini file
ImGuiIniData* settings = FindWindowSettings(name);
if (settings && ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))// && ImLengthsize) == 0.0f)
size = settings->Size;
window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
new(window) ImGuiWindow(name, g.NewWindowDefaultPos, size);
new(window) ImGuiWindow(name);
window->PosFloat = ImVec2(60, 60);
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
ImGuiIniData* settings = FindWindowSettings(name);
if (!settings)
{
settings = AddWindowSettings(name);
}
else
{
window->SetWindowPosAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
window->SetWindowSizeAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
}
if (settings->Pos.x != FLT_MAX)
{
@ -2120,6 +2184,10 @@ bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, I
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
window->Collapsed = settings->Collapsed;
}
if (ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))
size = settings->Size;
window->Size = window->SizeFull = size;
}
g.Windows.push_back(window);
}
@ -2128,6 +2196,35 @@ bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, I
g.CurrentWindowStack.push_back(window);
g.CurrentWindow = window;
// Process SetNextWindow***() calls
if (g.SetNextWindowPosCond)
{
const ImVec2 backup_cursor_pos = window->DC.CursorPos;
ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond);
window->DC.CursorPos = backup_cursor_pos;
g.SetNextWindowPosCond = 0;
}
if (g.SetNextWindowSizeCond)
{
ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond);
g.SetNextWindowSizeCond = 0;
}
if (g.SetNextWindowCollapsedCond)
{
ImGui::SetWindowCollapsed(g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond);
g.SetNextWindowCollapsedCond = 0;
}
// Find root
size_t root_idx = g.CurrentWindowStack.size() - 1;
while (root_idx > 0)
{
if ((g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow) == 0)
break;
root_idx--;
}
window->RootWindow = g.CurrentWindowStack[root_idx];
// Default alpha
if (fill_alpha < 0.0f)
fill_alpha = style.WindowFillAlphaDefault;
@ -2282,7 +2379,7 @@ bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, I
const ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding);
if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
{
// Don't continously mark settings as dirty, the size of the window doesn't need to be stored.
// Don't continuously mark settings as dirty, the size of the window doesn't need to be stored.
window->SizeFull = size_auto_fit;
}
else if (window->AutoFitFrames > 0)
@ -2298,7 +2395,7 @@ bool ImGui::Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, I
{
// Resize grip
const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR());
const ImGuiID resize_id = window->GetID("#RESIZE");
const ImGuiID resize_id = window->GetID("##RESIZE");
bool hovered, held;
ButtonBehaviour(resize_aabb, resize_id, &hovered, &held, true);
resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
@ -2506,7 +2603,7 @@ void ImGui::End()
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
const ImGuiAabb bb(window->Pos, window->Pos+window->Size);
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredWindowExcludingChilds == window && IsMouseHoveringBox(bb) && g.IO.MouseClicked[0])
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow == window && IsMouseHoveringBox(bb) && g.IO.MouseClicked[0])
g.ActiveId = window->GetID("#MOVE");
// Stop logging
@ -2532,6 +2629,7 @@ void ImGui::End()
}
// Pop
window->RootWindow = NULL;
g.CurrentWindowStack.pop_back();
g.CurrentWindow = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
}
@ -2752,15 +2850,20 @@ ImVec2 ImGui::GetWindowPos()
return window->Pos;
}
void ImGui::SetWindowPos(const ImVec2& pos)
void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
{
ImGuiWindow* window = GetCurrentWindow();
// Test condition (NB: bit 0 is always true) and clear flags for next time
if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
return;
window->SetWindowPosAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
// Set
const ImVec2 old_pos = window->Pos;
window->PosFloat = pos;
window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
// If we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
window->DC.CursorPos += (window->Pos - old_pos);
window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
}
ImVec2 ImGui::GetWindowSize()
@ -2769,9 +2872,16 @@ ImVec2 ImGui::GetWindowSize()
return window->Size;
}
void ImGui::SetWindowSize(const ImVec2& size)
void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCondition cond)
{
ImGuiWindow* window = GetCurrentWindow();
// Test condition (NB: bit 0 is always true) and clear flags for next time
if (cond && (window->SetWindowSizeAllowFlags & cond) == 0)
return;
window->SetWindowSizeAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
// Set
if (ImLength(size) < 0.001f)
{
window->AutoFitFrames = 2;
@ -2780,9 +2890,44 @@ void ImGui::SetWindowSize(const ImVec2& size)
else
{
window->SizeFull = size;
window->AutoFitFrames = 0;
}
}
void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
{
ImGuiWindow* window = GetCurrentWindow();
// Test condition (NB: bit 0 is always true) and clear flags for next time
if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0)
return;
window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
// Set
window->Collapsed = collapsed;
}
void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
{
ImGuiState& g = GImGui;
g.SetNextWindowPosVal = pos;
g.SetNextWindowPosCond = cond ? cond : ImGuiSetCondition_Always;
}
void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond)
{
ImGuiState& g = GImGui;
g.SetNextWindowSizeVal = size;
g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCondition_Always;
}
void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
{
ImGuiState& g = GImGui;
g.SetNextWindowCollapsedVal = collapsed;
g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCondition_Always;
}
ImVec2 ImGui::GetContentRegionMax()
{
ImGuiWindow* window = GetCurrentWindow();
@ -3113,7 +3258,7 @@ static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_ho
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
const bool hovered = (g.HoveredRootWindow == window->RootWindow) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
bool pressed = false;
if (hovered)
{
@ -3526,6 +3671,18 @@ void ImGui::PopID()
window->IDStack.pop_back();
}
ImGuiID ImGui::GetID(const char* str_id)
{
ImGuiWindow* window = GetCurrentWindow();
return window->GetID(str_id);
}
ImGuiID ImGui::GetID(const void* ptr_id)
{
ImGuiWindow* window = GetCurrentWindow();
return window->GetID(ptr_id);
}
// User can input math operators (e.g. +100) to edit a numerical values.
// NB: only call right after InputText because we are using its InitialValue storage
static void ApplyNumericalTextInput(const char* buf, float *v)
@ -4318,7 +4475,8 @@ bool ImGui::InputInt(const char* label, int *v, int step, int step_fast, ImGuiIn
{
float f = (float)*v;
const bool value_changed = ImGui::InputFloat(label, &f, (float)step, (float)step_fast, 0, extra_flags);
*v = (int)f;
if (value_changed)
*v = (int)f;
return value_changed;
}
@ -6497,7 +6655,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
*ref = g.Style;
}
ImGui::PushItemWidth(ImGui::GetWindowWidth()*0.55f);
ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f);
if (ImGui::TreeNode("Sizes"))
{
@ -6571,6 +6729,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
static void ShowExampleAppConsole(bool* open);
static void ShowExampleAppLongText(bool* open);
static void ShowExampleAppAutoResize(bool* open);
static void ShowExampleAppFixedOverlay(bool* open);
// Demonstrate ImGui features (unfortunately this makes this function a little bloated!)
void ImGui::ShowTestWindow(bool* open)
@ -6884,7 +7043,7 @@ void ImGui::ShowTestWindow(bool* open)
ImGui::PushItemWidth(100);
goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::PopItemWidth();
ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth()*0.5f,300));
ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth() * 0.5f,300));
for (int i = 0; i < 100; i++)
{
ImGui::Text("%04d: scrollable region", i);
@ -7082,11 +7241,13 @@ void ImGui::ShowTestWindow(bool* open)
static bool show_app_console = false;
static bool show_app_long_text = false;
static bool show_app_auto_resize = false;
static bool show_app_fixed_overlay = false;
if (ImGui::CollapsingHeader("App Examples"))
{
ImGui::Checkbox("Console", &show_app_console);
ImGui::Checkbox("Long text display", &show_app_long_text);
ImGui::Checkbox("Auto-resizing window", &show_app_auto_resize);
ImGui::Checkbox("Simple overlay", &show_app_fixed_overlay);
}
if (show_app_console)
ShowExampleAppConsole(&show_app_console);
@ -7094,6 +7255,8 @@ void ImGui::ShowTestWindow(bool* open)
ShowExampleAppLongText(&show_app_long_text);
if (show_app_auto_resize)
ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_fixed_overlay)
ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
ImGui::End();
}
@ -7115,6 +7278,22 @@ static void ShowExampleAppAutoResize(bool* open)
ImGui::End();
}
static void ShowExampleAppFixedOverlay(bool* open)
{
if (!ImGui::Begin("Example: Fixed Overlay", open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
{
ImGui::End();
return;
}
ImGui::SetWindowPos(ImVec2(10,10));
ImGui::Text("Simple overlay\non the top-left side of the screen.");
ImGui::Separator();
ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
ImGui::End();
}
struct ExampleAppConsole
{
ImVector<char*> Items;
@ -7163,7 +7342,7 @@ struct ExampleAppConsole
const char* commands[] = { "HELP", "CLEAR", "CLASSIFY" };
ImVector<const char*> candidates;
for (size_t i = 0; i < IM_ARRAYSIZE(commands); i++)
if (ImStrnicmp(commands[i], word_start, word_end-word_start) == 0)
if (ImStrnicmp(commands[i], word_start, (int)(word_end-word_start)) == 0)
candidates.push_back(commands[i]);
if (candidates.size() == 0)
@ -7174,14 +7353,14 @@ struct ExampleAppConsole
else if (candidates.size() == 1)
{
// Single match. Delete the beginning of the word and replace it entirely so we've got nice casing
data->DeleteChars(word_start-data->Buf, word_end-word_start);
data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start));
data->InsertChars(data->CursorPos, candidates[0]);
data->InsertChars(data->CursorPos, " ");
}
else
{
// Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY"
int match_len = word_end - word_start;
int match_len = (int)(word_end - word_start);
while (true)
{
int c = 0;
@ -7200,7 +7379,7 @@ struct ExampleAppConsole
if (match_len > 0)
{
data->DeleteChars(word_start - data->Buf, word_end-word_start);
data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start));
data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len);
}
@ -7534,7 +7713,8 @@ void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, co
//-----------------------------------------------------------------------------
//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
//---- Include imgui_user.inl at the end of imgui.cpp
//---- So you can include code that extends ImGui using its private data/functions.
#ifdef IMGUI_INCLUDE_IMGUI_USER_INL
#include "imgui_user.inl"
#endif

120
imgui.h
View File

@ -1,4 +1,4 @@
// ImGui library v1.17 wip
// ImGui library v1.18
// See .cpp file for commentary.
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@ -37,6 +37,7 @@ typedef int ImGuiStyleVar; // enum ImGuiStyleVar_
typedef int ImGuiKey; // enum ImGuiKey_
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
typedef int ImGuiSetCondition; // enum ImGuiSetCondition_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
struct ImGuiTextEditCallbackData;
@ -77,7 +78,7 @@ namespace ImGui
template<typename T>
class ImVector
{
private:
protected:
size_t Size;
size_t Capacity;
T* Data;
@ -117,7 +118,7 @@ public:
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; }
inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; }
};
#endif // #ifndef ImVector
@ -127,7 +128,7 @@ public:
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImDrawList // Draw command list
// - struct ImBitmapFont // Bitmap font loader
// - struct ImFont // Bitmap font loader
// ImGui End-user API
// In a namespace so that user can add extra functions (e.g. Value() helpers for your vector or common types)
@ -149,11 +150,6 @@ namespace ImGui
IMGUI_API void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
IMGUI_API void EndChild();
IMGUI_API bool GetWindowIsFocused();
IMGUI_API ImVec2 GetWindowSize();
IMGUI_API float GetWindowWidth();
IMGUI_API void SetWindowSize(const ImVec2& size); // set to ImVec2(0,0) to force an auto-fit
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing.
IMGUI_API void SetWindowPos(const ImVec2& pos); // set current window pos.
IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries
IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries
IMGUI_API ImVec2 GetWindowContentRegionMax();
@ -161,11 +157,22 @@ namespace ImGui
IMGUI_API ImFont* GetWindowFont();
IMGUI_API float GetWindowFontSize();
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows.
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing.
IMGUI_API ImVec2 GetWindowSize(); // get current window position.
IMGUI_API float GetWindowWidth();
IMGUI_API bool GetWindowCollapsed();
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set current window position.
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set current window collapsed state.
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set next window position.
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set next window collapsed state.
IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget.
IMGUI_API void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
IMGUI_API ImGuiStorage* GetTreeStateStorage();
IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case. default to ~2/3 of windows width.
IMGUI_API void PopItemWidth();
IMGUI_API float GetItemWidth();
@ -204,10 +211,13 @@ namespace ImGui
IMGUI_API float GetTextLineHeight();
// ID scopes
IMGUI_API void PushID(const char* str_id);
// If you are creating repeated widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them.
IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack!
IMGUI_API void PushID(const void* ptr_id);
IMGUI_API void PushID(const int int_id);
IMGUI_API void PopID();
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed.
IMGUI_API ImGuiID GetID(const void* ptr_id);
// Widgets
IMGUI_API void Text(const char* fmt, ...);
@ -261,8 +271,7 @@ namespace ImGui
IMGUI_API void TreePop();
IMGUI_API void OpenNextNode(bool open); // force open/close the next TreeNode or CollapsingHeader
// Value helper output "name: value"
// Freely declare your own in the ImGui namespace.
// Value helper output "name: value". tip: freely declare your own within the ImGui namespace!
IMGUI_API void Value(const char* prefix, bool b);
IMGUI_API void Value(const char* prefix, int v);
IMGUI_API void Value(const char* prefix, unsigned int v);
@ -277,7 +286,6 @@ namespace ImGui
IMGUI_API void LogToClipboard(int max_depth = -1);
// Utilities
IMGUI_API void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
IMGUI_API bool IsItemFocused(); // was the last item focused for keyboard input?
IMGUI_API ImVec2 GetItemBoxMin(); // get bounding box of last item
@ -308,12 +316,14 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoResize = 1 << 2,
ImGuiWindowFlags_NoMove = 1 << 3,
ImGuiWindowFlags_NoScrollbar = 1 << 4,
ImGuiWindowFlags_AlwaysAutoResize = 1 << 5,
ImGuiWindowFlags_ChildWindow = 1 << 6, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 7, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 8, // For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 9, // For internal use by ComboBox()
ImGuiWindowFlags_Tooltip = 1 << 10 // For internal use by Render() when using Tooltip
ImGuiWindowFlags_NoScrollWithMouse = 1 << 5,
ImGuiWindowFlags_AlwaysAutoResize = 1 << 6,
ImGuiWindowFlags_NoSavedSettings = 1 << 7, // Never load/save settings in .ini file
ImGuiWindowFlags_ChildWindow = 1 << 8, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 9, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 10, // For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 11, // For internal use by ComboBox()
ImGuiWindowFlags_Tooltip = 1 << 12 // For internal use by Render() when using Tooltip
};
// Flags for ImGui::InputText()
@ -326,7 +336,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 3, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
ImGuiInputTextFlags_CallbackCompletion = 1 << 4, // Call user function on pressing TAB (for completion handling)
ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling)
ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every frame
ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every time
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
};
@ -418,6 +428,15 @@ enum ImGuiColorEditMode_
ImGuiColorEditMode_HEX = 2
};
// Condition flags for ImGui::SetWindow***() and SetNextWindow***() functions
// Those functions treat 0 as a shortcut to ImGuiSetCondition_Always
enum ImGuiSetCondition_
{
ImGuiSetCondition_Always = 1 << 0, // Set the variable
ImGuiSetCondition_FirstUseThisSession = 1 << 1, // Only set the variable on the first call for this window (once per session)
ImGuiSetCondition_FirstUseEver = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file
};
struct ImGuiStyle
{
float Alpha; // Global alpha applies to everything in ImGui
@ -448,9 +467,9 @@ struct ImGuiIO
ImVec2 DisplaySize; // <unset> // Display size, in pixels. For clamping windows positions.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
float IniSavingRate; // = 5.0f // Maximum time between saving .ini file, in seconds. Set to a negative value to disable .ini saving.
const char* IniFilename; // = "imgui.ini" // Absolute path to .ini file.
const char* LogFilename; // = "imgui_log.txt" // Absolute path to .log file.
float IniSavingRate; // = 5.0f // Maximum time between saving .ini file, in seconds.
const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving.
const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array
@ -479,7 +498,7 @@ struct ImGuiIO
void* (*MemReallocFn)(void* ptr, size_t sz);
void (*MemFreeFn)(void* ptr);
// Optional: notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
// Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese inputs in Windows)
void (*ImeSetInputScreenPosFn)(int x, int y);
//------------------------------------------------------------------
@ -587,22 +606,38 @@ struct ImGuiTextBuffer
};
// Helper: Key->value storage
// - Store collapse state for a tree
// - Store color edit options, etc.
// - Store collapse state for a tree (Int 0/1)
// - Store color edit options (Int using values in ImGuiColorEditMode enum).
// - Custom user storage for temporary values.
// Typically you don't have to worry about this since a storage is held within each Window.
// Declare your own storage if you want to manipulate the open/close state of a particular sub-tree in your interface.
// Declare your own storage if:
// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
// - You want to store custom debug data easily without adding or editing structures in your code.
struct ImGuiStorage
{
struct Pair { ImU32 key; int val; };
struct Pair
{
ImGuiID key;
union { int val_i; float val_f; };
Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
};
ImVector<Pair> Data;
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
// - Set***() functions find pair, insertion on demand if missing.
// - Get***Ptr() functions find pair, insertion on demand if missing, return pointer. Useful if you intend to do Get+Set.
// A typical use case where this is very convenient:
// float* pvar = ImGui::GetIntPtr(key); ImGui::SliderInt("var", pvar, 0, 100); some_var += *pvar;
// - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair.
IMGUI_API void Clear();
IMGUI_API int GetInt(ImU32 key, int default_val = 0);
IMGUI_API void SetInt(ImU32 key, int val);
IMGUI_API void SetAllInt(int val);
IMGUI_API int* Find(ImU32 key);
IMGUI_API void Insert(ImU32 key, int val);
IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const;
IMGUI_API void SetInt(ImGuiID key, int val);
IMGUI_API int* GetIntPtr(ImGuiID key, int default_val = 0);
IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const;
IMGUI_API void SetFloat(ImGuiID key, float val);
IMGUI_API float* GetFloatPtr(ImGuiID key, float default_val = 0);
IMGUI_API void SetAllInt(int val); // Use on your own storage if you know only integer are being stored.
};
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
@ -650,8 +685,8 @@ IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
#endif
// Draw command list
// This is the low-level list of polygon that ImGui:: functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
// Each ImGui window contains its own ImDrawList.
// This is the low-level list of polygon that ImGui:: functions are creating. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged.
// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl
@ -685,7 +720,7 @@ struct ImDrawList
IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f);
};
// Optional bitmap font data loader & renderer into vertices
// Bitmap font data loader & renderer into vertices
// Using the .fnt format exported by BMFont
// - tool: http://www.angelcode.com/products/bmfont
// - file-format: http://www.angelcode.com/products/bmfont/doc/file_format.html
@ -777,3 +812,10 @@ struct ImFont
};
#pragma pack(pop)
};
//---- Include imgui_user.h at the end of imgui.h
//---- So you can include code that extends ImGui using any of the types declared above.
//---- (also convenient for user to only explicitly include vanilla imgui.h)
#ifdef IMGUI_INCLUDE_IMGUI_USER_H
#include "imgui_user.h"
#endif