diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/web/test_window_03.png b/web/test_window_03.png
index c4068cb..4f10986 100644
--- a/web/test_window_03.png
+++ b/web/test_window_03.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/web/test_window_03.png b/web/test_window_03.png
index c4068cb..4f10986 100644
--- a/web/test_window_03.png
+++ b/web/test_window_03.png
Binary files differ
diff --git a/web/test_window_04.png b/web/test_window_04.png
index 02f5d8b..59c3b85 100644
--- a/web/test_window_04.png
+++ b/web/test_window_04.png
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/web/test_window_03.png b/web/test_window_03.png
index c4068cb..4f10986 100644
--- a/web/test_window_03.png
+++ b/web/test_window_03.png
Binary files differ
diff --git a/web/test_window_04.png b/web/test_window_04.png
index 02f5d8b..59c3b85 100644
--- a/web/test_window_04.png
+++ b/web/test_window_04.png
Binary files differ
diff --git a/web/test_window_05.png b/web/test_window_05.png
deleted file mode 100644
index 2794782..0000000
--- a/web/test_window_05.png
+++ /dev/null
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/web/test_window_03.png b/web/test_window_03.png
index c4068cb..4f10986 100644
--- a/web/test_window_03.png
+++ b/web/test_window_03.png
Binary files differ
diff --git a/web/test_window_04.png b/web/test_window_04.png
index 02f5d8b..59c3b85 100644
--- a/web/test_window_04.png
+++ b/web/test_window_04.png
Binary files differ
diff --git a/web/test_window_05.png b/web/test_window_05.png
deleted file mode 100644
index 2794782..0000000
--- a/web/test_window_05.png
+++ /dev/null
Binary files differ
diff --git a/web/test_window_06.png b/web/test_window_06.png
deleted file mode 100644
index 6b7a829..0000000
--- a/web/test_window_06.png
+++ /dev/null
Binary files differ
diff --git a/README.md b/README.md
index b3a1499..273be08 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
=====
[](https://travis-ci.org/ocornut/imgui)
+[](http://www.patreon.com/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. 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.
@@ -32,6 +34,7 @@



+
ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj
index 5f731ac..92ad83a 100644
--- a/examples/directx11_example/directx11_example.vcxproj
+++ b/examples/directx11_example/directx11_example.vcxproj
@@ -18,7 +18,7 @@
Application
true
- MultiByte
+ Unicode
Application
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 1a87d3c..ce6fbb2 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -517,11 +517,11 @@
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
- hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
+ hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
@@ -532,7 +532,7 @@
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@@ -603,7 +603,7 @@
}
ImGui::Shutdown();
- UnregisterClass("ImGui Example", wc.hInstance);
+ UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}
diff --git a/imgui.cpp b/imgui.cpp
index 37865c9..4f49d1c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1102,6 +1102,11 @@
return GImGui->CurrentWindow;
}
+static void SetActiveId(ImGuiID id)
+{
+ GImGui.ActiveId = id;
+}
+
static void RegisterAliveId(const ImGuiID& id)
{
if (GImGui->ActiveId == id)
@@ -1682,7 +1687,7 @@
// Clear reference to active widget if the widget isn't alive anymore
g.HoveredId = 0;
if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
@@ -1868,7 +1873,7 @@
// Select window for move/focus when we're done with all our widgets (we only consider non-childs windows here)
if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
- g.ActiveId = g.HoveredRootWindow->GetID("#MOVE");
+ SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
// Sort the window list so that all child windows are after their parent
// We cannot do that on FocusWindow() because childs may not exist yet
@@ -2554,7 +2559,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -3567,7 +3572,7 @@
{
if (g.IO.MouseClicked[0])
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
@@ -3588,7 +3593,7 @@
{
if (hovered)
pressed = true;
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -4244,7 +4249,7 @@
bool start_text_input = false;
if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
{
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
const bool is_ctrl_down = g.IO.KeyCtrl;
@@ -4262,7 +4267,7 @@
char text_buf[64];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);
- g.ActiveId = g.SliderAsInputTextId;
+ SetActiveId(g.SliderAsInputTextId);
g.HoveredId = 0;
window->FocusItemUnregister(); // Our replacement slider will override the focus ID (registered previously to allow for a TAB focus to happen)
value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
@@ -4271,15 +4276,18 @@
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
g.SliderAsInputTextId = g.ActiveId;
- g.ActiveId = id;
+ SetActiveId(id);
g.HoveredId = id;
}
else
{
if (g.ActiveId == g.SliderAsInputTextId)
- g.ActiveId = id;
+ SetActiveId(id);
else
- g.ActiveId = g.SliderAsInputTextId = 0;
+ {
+ SetActiveId(0);
+ g.SliderAsInputTextId = 0;
+ }
}
if (value_changed)
{
@@ -4343,7 +4351,7 @@
}
else
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5084,7 +5092,7 @@
if (tab_focus_requested || is_ctrl_down)
select_all = true;
}
- g.ActiveId = id;
+ SetActiveId(id);
FocusWindow(window);
}
else if (io.MouseClicked[0])
@@ -5092,7 +5100,7 @@
// Release focus when we click outside
if (g.ActiveId == id)
{
- g.ActiveId = 0;
+ SetActiveId(0);
}
}
@@ -5130,6 +5138,25 @@
if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
edit_state.SelectedAllMouseLock = false;
+ if (g.IO.InputCharacters[0])
+ {
+ // Process text input (before we check for Return because using some IME will effectively send a Return?)
+ for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
+ {
+ const ImWchar c = g.IO.InputCharacters[n];
+ if (c)
+ {
+ // Insert character if they pass filtering
+ if (InputTextFilterCharacter(c, flags))
+ continue;
+ edit_state.OnKeyPressed(c);
+ }
+ }
+
+ // Consume characters
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
+ }
+
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
@@ -5137,8 +5164,8 @@
else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; }
- else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Enter)) { SetActiveId(0); enter_pressed = true; }
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveId(0); cancel_edit = true; }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); }
else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); }
@@ -5191,24 +5218,6 @@
}
}
}
- else if (g.IO.InputCharacters[0])
- {
- // Text input
- for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
- {
- const ImWchar c = g.IO.InputCharacters[n];
- if (c)
- {
- // Insert character if they pass filtering
- if (InputTextFilterCharacter(c, flags))
- continue;
- edit_state.OnKeyPressed(c);
- }
- }
-
- // Consume characters
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
- }
edit_state.CursorAnim += g.IO.DeltaTime;
edit_state.UpdateScrollOffset();
@@ -5527,7 +5536,7 @@
}
if (item_pressed)
{
- g.ActiveId = 0;
+ SetActiveId(0);
g.ActiveComboID = 0;
value_changed = true;
*current_item = item_idx;
@@ -7827,7 +7836,8 @@
// Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature')
// However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants.
// In your own application be reasonable and use UTF-8 in source or retrieve the data from file system!
- ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to specify extra character ranges. Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.");
+ // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
+ ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges.");
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
diff --git a/web/code_sample_01.png b/web/code_sample_01.png
index 6178f8d..d872db8 100644
--- a/web/code_sample_01.png
+++ b/web/code_sample_01.png
Binary files differ
diff --git a/web/examples_01.png b/web/examples_01.png
new file mode 100644
index 0000000..151eab1
--- /dev/null
+++ b/web/examples_01.png
Binary files differ
diff --git a/web/examples_02.png b/web/examples_02.png
new file mode 100644
index 0000000..bd6a720
--- /dev/null
+++ b/web/examples_02.png
Binary files differ
diff --git a/web/test_window_01.png b/web/test_window_01.png
index f54485a..608cc96 100644
--- a/web/test_window_01.png
+++ b/web/test_window_01.png
Binary files differ
diff --git a/web/test_window_02.png b/web/test_window_02.png
index 331e638..8cb4df8 100644
--- a/web/test_window_02.png
+++ b/web/test_window_02.png
Binary files differ
diff --git a/web/test_window_03.png b/web/test_window_03.png
index c4068cb..4f10986 100644
--- a/web/test_window_03.png
+++ b/web/test_window_03.png
Binary files differ
diff --git a/web/test_window_04.png b/web/test_window_04.png
index 02f5d8b..59c3b85 100644
--- a/web/test_window_04.png
+++ b/web/test_window_04.png
Binary files differ
diff --git a/web/test_window_05.png b/web/test_window_05.png
deleted file mode 100644
index 2794782..0000000
--- a/web/test_window_05.png
+++ /dev/null
Binary files differ
diff --git a/web/test_window_06.png b/web/test_window_06.png
deleted file mode 100644
index 6b7a829..0000000
--- a/web/test_window_06.png
+++ /dev/null
Binary files differ
diff --git a/web/utf8_sample_01.png b/web/utf8_sample_01.png
index 023bc66..d046277 100644
--- a/web/utf8_sample_01.png
+++ b/web/utf8_sample_01.png
Binary files differ