Procházet zdrojové kódy

Console input keeps keyboard focus

Thomas Buck před 9 roky
rodič
revize
e5922c7c3d
5 změnil soubory, kde provedl 107 přidání a 45 odebrání
  1. 2
    1
      ChangeLog.md
  2. 1
    0
      include/Console.h
  3. 7
    0
      src/Console.cpp
  4. 93
    41
      src/deps/imgui/imgui.cpp
  5. 4
    3
      src/deps/imgui/imgui.h

+ 2
- 1
ChangeLog.md Zobrazit soubor

@@ -3,7 +3,8 @@
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5 5
     [ 20140930 ]
6
-    * Updated imgui to version 1.13
6
+    * Updated imgui to version 1.14 wip
7
+    * Console input keeps keyboard focus after command input
7 8
 
8 9
     [ 20140920 ]
9 10
     * Updated imgui (fix for resource leak)

+ 1
- 0
include/Console.h Zobrazit soubor

@@ -16,6 +16,7 @@ private:
16 16
     const static int bufferLength = 256;
17 17
     static char buffer[bufferLength];
18 18
     static bool scrollToBottom;
19
+    static bool focusInput;
19 20
     static unsigned long lastLogLength;
20 21
 };
21 22
 

+ 7
- 0
src/Console.cpp Zobrazit soubor

@@ -13,6 +13,7 @@
13 13
 
14 14
 char Console::buffer[bufferLength] = "";
15 15
 bool Console::scrollToBottom = false;
16
+bool Console::focusInput = false;
16 17
 unsigned long Console::lastLogLength = 0;
17 18
 
18 19
 void Console::display() {
@@ -32,6 +33,11 @@ void Console::display() {
32 33
         }
33 34
         ImGui::EndChild();
34 35
 
36
+        if (focusInput) {
37
+            ImGui::SetKeyboardFocusHere();
38
+            focusInput = false;
39
+        }
40
+
35 41
         if (ImGui::InputText("Command", buffer, bufferLength,
36 42
                     ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) {
37 43
             getLog() << "> " << buffer << Log::endl;
@@ -41,6 +47,7 @@ void Console::display() {
41 47
             }
42 48
             buffer[0] = '\0';
43 49
             scrollToBottom = true;
50
+            focusInput = true;
44 51
         }
45 52
     }
46 53
     ImGui::End();

+ 93
- 41
src/deps/imgui/imgui.cpp Zobrazit soubor

@@ -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;

+ 4
- 3
src/deps/imgui/imgui.h Zobrazit soubor

@@ -1,4 +1,4 @@
1
-// ImGui library v1.13
1
+// ImGui library v1.14 wip
2 2
 // See .cpp file for commentary.
3 3
 // See ImGui::ShowTestWindow() for sample code.
4 4
 // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@@ -153,12 +153,13 @@ namespace ImGui
153 153
     ImDrawList* GetWindowDrawList();                                                // get rendering command-list if you want to append your own draw primitives.
154 154
     void        SetWindowFontScale(float scale);                                    // per-window font scale. Adjust IO.FontBaseScale if you want to scale all windows together.
155 155
     void        SetScrollPosHere();                                                 // adjust scrolling position to center into the current cursor position.
156
+    void        SetKeyboardFocusHere(int offset = 0);                               // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
156 157
     void        SetTreeStateStorage(ImGuiStorage* tree);                            // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
157 158
     ImGuiStorage* GetTreeStateStorage();
158 159
     void        PushItemWidth(float item_width);
159 160
     void        PopItemWidth();
160 161
     float       GetItemWidth();
161
-    void        PushAllowKeyboardFocus(bool v);
162
+    void        PushAllowKeyboardFocus(bool v);                                     // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
162 163
     void        PopAllowKeyboardFocus();
163 164
     void        PushStyleColor(ImGuiCol idx, const ImVec4& col);
164 165
     void        PopStyleColor();
@@ -419,7 +420,7 @@ struct ImGuiIO
419 420
     ImVec2      FontTexUvForWhite;          // = (0.0f,0.0f)            // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
420 421
     float       FontBaseScale;              // = 1.0f                   // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
421 422
     bool        FontAllowUserScaling;       // = false                  // Set to allow scaling text with CTRL+Wheel.
422
-	ImWchar     FontFallbackGlyph;          // = '?'                    // Replacement glyph is one isn't found.
423
+    ImWchar     FontFallbackGlyph;          // = '?'                    // Replacement glyph is one isn't found.
423 424
     float       PixelCenterOffset;          // = 0.0f                   // Try to set to 0.5f or 0.375f if rendering is blurry
424 425
 
425 426
     //------------------------------------------------------------------

Loading…
Zrušit
Uložit