|
@@ -1,4 +1,4 @@
|
1
|
|
-// ImGui library v1.13
|
|
1
|
+// ImGui library v1.14 wip
|
2
|
2
|
// See ImGui::ShowTestWindow() for sample code.
|
3
|
3
|
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
|
4
|
4
|
// Get latest version at https://github.com/ocornut/imgui
|
|
@@ -185,11 +185,13 @@
|
185
|
185
|
- filters: set a current filter that tree node can automatically query to hide themselves
|
186
|
186
|
- filters: handle wildcards (with implicit leading/trailing *), regexps
|
187
|
187
|
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
|
188
|
|
- - input: keyboard: full keyboard navigation and focus.
|
|
188
|
+ ! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
|
|
189
|
+ - keyboard: full keyboard navigation and focus.
|
189
|
190
|
- input: support trackpad style scrolling & slider edit.
|
|
191
|
+ - tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen).
|
190
|
192
|
- misc: not thread-safe
|
191
|
193
|
- misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
|
192
|
|
- - style editor: add a button to print C code.
|
|
194
|
+ - style editor: add a button to output C code.
|
193
|
195
|
- optimisation/render: use indexed rendering
|
194
|
196
|
- optimisation/render: move clip-rect to vertex data? would allow merging all commands
|
195
|
197
|
- optimisation/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
|
|
@@ -760,13 +762,16 @@ struct ImGuiWindow
|
760
|
762
|
float ItemWidthDefault;
|
761
|
763
|
ImGuiStorage StateStorage;
|
762
|
764
|
float FontWindowScale; // Scale multipler per-window
|
763
|
|
-
|
764
|
|
- int FocusIdxCounter; // Start at -1 and increase as assigned via FocusItemRegister()
|
765
|
|
- int FocusIdxRequestCurrent; // Item being requested for focus, rely on layout to be stable between the frame pressing TAB and the next frame
|
766
|
|
- int FocusIdxRequestNext; // Item being requested for focus, for next update
|
767
|
|
-
|
768
|
765
|
ImDrawList* DrawList;
|
769
|
766
|
|
|
767
|
+ // Focus
|
|
768
|
+ int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
|
|
769
|
+ int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through)
|
|
770
|
+ int FocusIdxAllRequestCurrent; // Item being requested for focus
|
|
771
|
+ int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus
|
|
772
|
+ int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame)
|
|
773
|
+ int FocusIdxTabRequestNext; // "
|
|
774
|
+
|
770
|
775
|
public:
|
771
|
776
|
ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size);
|
772
|
777
|
~ImGuiWindow();
|
|
@@ -775,7 +780,7 @@ public:
|
775
|
780
|
ImGuiID GetID(const void* ptr);
|
776
|
781
|
|
777
|
782
|
void AddToRenderList();
|
778
|
|
- bool FocusItemRegister(bool is_active, int* out_idx = NULL); // Return TRUE if focus is requested
|
|
783
|
+ bool FocusItemRegister(bool is_active); // Return true if focus is requested
|
779
|
784
|
void FocusItemUnregister();
|
780
|
785
|
|
781
|
786
|
ImGuiAabb Aabb() const { return ImGuiAabb(Pos, Pos+Size); }
|
|
@@ -1017,12 +1022,12 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si
|
1017
|
1022
|
if (ImLength(Size) < 0.001f)
|
1018
|
1023
|
AutoFitFrames = 3;
|
1019
|
1024
|
|
1020
|
|
- FocusIdxCounter = -1;
|
1021
|
|
- FocusIdxRequestCurrent = IM_INT_MAX;
|
1022
|
|
- FocusIdxRequestNext = IM_INT_MAX;
|
1023
|
|
-
|
1024
|
1025
|
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
|
1025
|
1026
|
new(DrawList) ImDrawList();
|
|
1027
|
+
|
|
1028
|
+ FocusIdxAllCounter = FocusIdxTabCounter = -1;
|
|
1029
|
+ FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX;
|
|
1030
|
+ FocusIdxAllRequestNext = FocusIdxTabRequestNext = IM_INT_MAX;
|
1026
|
1031
|
}
|
1027
|
1032
|
|
1028
|
1033
|
ImGuiWindow::~ImGuiWindow()
|
|
@@ -1050,31 +1055,38 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
|
1050
|
1055
|
return id;
|
1051
|
1056
|
}
|
1052
|
1057
|
|
1053
|
|
-bool ImGuiWindow::FocusItemRegister(bool is_active, int* out_idx)
|
|
1058
|
+bool ImGuiWindow::FocusItemRegister(bool is_active)
|
1054
|
1059
|
{
|
1055
|
|
- FocusIdxCounter++;
|
1056
|
|
- if (out_idx)
|
1057
|
|
- *out_idx = FocusIdxCounter;
|
1058
|
|
-
|
1059
|
1060
|
ImGuiState& g = GImGui;
|
1060
|
1061
|
ImGuiWindow* window = GetCurrentWindow();
|
1061
|
|
- if (!window->DC.AllowKeyboardFocus.back())
|
1062
|
|
- return false;
|
1063
|
1062
|
|
1064
|
|
- // Process input at this point: TAB, Shift-TAB switch focus
|
1065
|
|
- if (FocusIdxRequestNext == IM_INT_MAX && is_active && ImGui::IsKeyPressedMap(ImGuiKey_Tab))
|
|
1063
|
+ const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus.back();
|
|
1064
|
+ FocusIdxAllCounter++;
|
|
1065
|
+ if (allow_keyboard_focus)
|
|
1066
|
+ FocusIdxTabCounter++;
|
|
1067
|
+
|
|
1068
|
+ // Process keyboard input at this point: TAB, Shift-TAB switch focus
|
|
1069
|
+ // We can always TAB out of a widget that doesn't allow tabbing in.
|
|
1070
|
+ if (FocusIdxAllRequestNext == IM_INT_MAX && FocusIdxTabRequestNext == IM_INT_MAX && is_active && ImGui::IsKeyPressedMap(ImGuiKey_Tab))
|
1066
|
1071
|
{
|
1067
|
1072
|
// Modulo on index will be applied at the end of frame once we've got the total counter of items.
|
1068
|
|
- FocusIdxRequestNext = FocusIdxCounter + (g.IO.KeyShift ? -1 : +1);
|
|
1073
|
+ FocusIdxTabRequestNext = FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1);
|
1069
|
1074
|
}
|
1070
|
1075
|
|
1071
|
|
- const bool focus_requested = (FocusIdxCounter == FocusIdxRequestCurrent);
|
1072
|
|
- return focus_requested;
|
|
1076
|
+ if (FocusIdxAllCounter == FocusIdxAllRequestCurrent)
|
|
1077
|
+ return true;
|
|
1078
|
+
|
|
1079
|
+ if (allow_keyboard_focus)
|
|
1080
|
+ if (FocusIdxTabCounter == FocusIdxTabRequestCurrent)
|
|
1081
|
+ return true;
|
|
1082
|
+
|
|
1083
|
+ return false;
|
1073
|
1084
|
}
|
1074
|
1085
|
|
1075
|
1086
|
void ImGuiWindow::FocusItemUnregister()
|
1076
|
1087
|
{
|
1077
|
|
- FocusIdxCounter--;
|
|
1088
|
+ FocusIdxAllCounter--;
|
|
1089
|
+ FocusIdxTabCounter--;
|
1078
|
1090
|
}
|
1079
|
1091
|
|
1080
|
1092
|
void ImGuiWindow::AddToRenderList()
|
|
@@ -1387,7 +1399,7 @@ void NewFrame()
|
1387
|
1399
|
// NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus.
|
1388
|
1400
|
if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Visible && IsKeyPressedMap(ImGuiKey_Tab, false))
|
1389
|
1401
|
{
|
1390
|
|
- g.FocusedWindow->FocusIdxRequestNext = 0;
|
|
1402
|
+ g.FocusedWindow->FocusIdxTabRequestNext = 0;
|
1391
|
1403
|
}
|
1392
|
1404
|
|
1393
|
1405
|
// Mark all windows as not visible
|
|
@@ -2094,18 +2106,17 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
|
2094
|
2106
|
else
|
2095
|
2107
|
window->ItemWidthDefault = 200.0f;
|
2096
|
2108
|
|
2097
|
|
- // Prepare for keyboard focus requests
|
2098
|
|
- if (window->FocusIdxRequestNext == IM_INT_MAX || window->FocusIdxCounter == -1)
|
2099
|
|
- {
|
2100
|
|
- window->FocusIdxRequestCurrent = IM_INT_MAX;
|
2101
|
|
- }
|
|
2109
|
+ // Prepare for focus requests
|
|
2110
|
+ if (window->FocusIdxAllRequestNext == IM_INT_MAX || window->FocusIdxAllCounter == -1)
|
|
2111
|
+ window->FocusIdxAllRequestCurrent = IM_INT_MAX;
|
2102
|
2112
|
else
|
2103
|
|
- {
|
2104
|
|
- const int mod = window->FocusIdxCounter+1;
|
2105
|
|
- window->FocusIdxRequestCurrent = (window->FocusIdxRequestNext + mod) % mod;
|
2106
|
|
- }
|
2107
|
|
- window->FocusIdxCounter = -1;
|
2108
|
|
- window->FocusIdxRequestNext = IM_INT_MAX;
|
|
2113
|
+ window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1);
|
|
2114
|
+ if (window->FocusIdxTabRequestNext == IM_INT_MAX || window->FocusIdxTabCounter == -1)
|
|
2115
|
+ window->FocusIdxTabRequestCurrent = IM_INT_MAX;
|
|
2116
|
+ else
|
|
2117
|
+ window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1);
|
|
2118
|
+ window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1;
|
|
2119
|
+ window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX;
|
2109
|
2120
|
|
2110
|
2121
|
ImGuiAabb title_bar_aabb = window->TitleBarAabb();
|
2111
|
2122
|
|
|
@@ -2627,6 +2638,13 @@ void SetScrollPosHere()
|
2627
|
2638
|
window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y);
|
2628
|
2639
|
}
|
2629
|
2640
|
|
|
2641
|
+void SetKeyboardFocusHere(int offset)
|
|
2642
|
+{
|
|
2643
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
2644
|
+ window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset;
|
|
2645
|
+ window->FocusIdxTabRequestNext = IM_INT_MAX;
|
|
2646
|
+}
|
|
2647
|
+
|
2630
|
2648
|
void SetTreeStateStorage(ImGuiStorage* tree)
|
2631
|
2649
|
{
|
2632
|
2650
|
ImGuiWindow* window = GetCurrentWindow();
|
|
@@ -6021,9 +6039,6 @@ void ShowTestWindow(bool* open)
|
6021
|
6039
|
ImGui::Text("Thanks for clicking me!");
|
6022
|
6040
|
}
|
6023
|
6041
|
|
6024
|
|
- static bool check = true;
|
6025
|
|
- ImGui::Checkbox("checkbox", &check);
|
6026
|
|
-
|
6027
|
6042
|
if (ImGui::TreeNode("Tree"))
|
6028
|
6043
|
{
|
6029
|
6044
|
for (size_t i = 0; i < 5; i++)
|
|
@@ -6071,6 +6086,8 @@ void ShowTestWindow(bool* open)
|
6071
|
6086
|
ImGui::TreePop();
|
6072
|
6087
|
}
|
6073
|
6088
|
|
|
6089
|
+ static bool check = true;
|
|
6090
|
+ ImGui::Checkbox("checkbox", &check);
|
6074
|
6091
|
|
6075
|
6092
|
static int e = 0;
|
6076
|
6093
|
ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
|
|
@@ -6374,6 +6391,41 @@ void ShowTestWindow(bool* open)
|
6374
|
6391
|
ImGui::BulletText("%s", lines[i]);
|
6375
|
6392
|
}
|
6376
|
6393
|
|
|
6394
|
+ if (ImGui::CollapsingHeader("Keyboard & Focus"))
|
|
6395
|
+ {
|
|
6396
|
+ if (ImGui::TreeNode("Tabbing"))
|
|
6397
|
+ {
|
|
6398
|
+ ImGui::Text("Use TAB/SHIFT+TAB to cycle thru keyboard editable fields.");
|
|
6399
|
+ static char buf[32] = "dummy";
|
|
6400
|
+ ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
|
|
6401
|
+ ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
|
|
6402
|
+ ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
|
|
6403
|
+ ImGui::PushAllowKeyboardFocus(false);
|
|
6404
|
+ ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
|
|
6405
|
+ //ImGui::SameLine(); ImGui::Text("(?)"); if (ImGui::IsHovered()) ImGui::SetTooltip("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
|
|
6406
|
+ ImGui::PopAllowKeyboardFocus();
|
|
6407
|
+ ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
|
|
6408
|
+ ImGui::TreePop();
|
|
6409
|
+ }
|
|
6410
|
+
|
|
6411
|
+ if (ImGui::TreeNode("Focus from code"))
|
|
6412
|
+ {
|
|
6413
|
+ bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine();
|
|
6414
|
+ bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine();
|
|
6415
|
+ bool focus_3 = ImGui::Button("Focus on 3");
|
|
6416
|
+ static char buf[128] = "click on a button to set focus";
|
|
6417
|
+ if (focus_1) ImGui::SetKeyboardFocusHere();
|
|
6418
|
+ ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
|
|
6419
|
+ if (focus_2) ImGui::SetKeyboardFocusHere();
|
|
6420
|
+ ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
|
|
6421
|
+ ImGui::PushAllowKeyboardFocus(false);
|
|
6422
|
+ if (focus_3) ImGui::SetKeyboardFocusHere();
|
|
6423
|
+ ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf));
|
|
6424
|
+ ImGui::PopAllowKeyboardFocus();
|
|
6425
|
+ ImGui::TreePop();
|
|
6426
|
+ }
|
|
6427
|
+ }
|
|
6428
|
+
|
6377
|
6429
|
if (ImGui::CollapsingHeader("Long text"))
|
6378
|
6430
|
{
|
6379
|
6431
|
static ImGuiTextBuffer log;
|