Explorar el Código

Updated ImGui.

Branimir Karadžić hace 7 años
padre
commit
811d60a2ab

+ 31 - 22
3rdparty/dear-imgui/imgui.cpp

@@ -441,7 +441,7 @@
     Note: The 'io.WantCaptureMouse' is more accurate that any attempt to "check if the mouse is hovering a window" (don't do that!).
     Note: The 'io.WantCaptureMouse' is more accurate that any attempt to "check if the mouse is hovering a window" (don't do that!).
      It handle mouse dragging correctly (both dragging that started over your application or over an imgui window) and handle e.g. modal windows blocking inputs.
      It handle mouse dragging correctly (both dragging that started over your application or over an imgui window) and handle e.g. modal windows blocking inputs.
      Those flags are updated by ImGui::NewFrame(). Preferably read the flags after calling NewFrame() if you can afford it, but reading them before is also
      Those flags are updated by ImGui::NewFrame(). Preferably read the flags after calling NewFrame() if you can afford it, but reading them before is also
-     perfectly fine, as the bool toggle fairly rarely. If you have on a touch device, you might find use for an early call to NewFrameUpdateHoveredWindowAndCaptureFlags().
+     perfectly fine, as the bool toggle fairly rarely. If you have on a touch device, you might find use for an early call to UpdateHoveredWindowAndCaptureFlags().
     Note: Text input widget releases focus on "Return KeyDown", so the subsequent "Return KeyUp" event that your application receive will typically
     Note: Text input widget releases focus on "Return KeyDown", so the subsequent "Return KeyUp" event that your application receive will typically
      have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs
      have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs
      were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.)
      were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.)
@@ -858,7 +858,6 @@ static void             NavUpdate();
 static void             NavUpdateWindowing();
 static void             NavUpdateWindowing();
 static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id);
 static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id);
 
 
-static void             UpdateMovingWindow();
 static void             UpdateMouseInputs();
 static void             UpdateMouseInputs();
 static void             UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
 static void             UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
 static void             FocusFrontMostActiveWindow(ImGuiWindow* ignore_window);
 static void             FocusFrontMostActiveWindow(ImGuiWindow* ignore_window);
@@ -2073,7 +2072,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
     CollapseToggleWanted = false;
     CollapseToggleWanted = false;
     SkipItems = false;
     SkipItems = false;
     Appearing = false;
     Appearing = false;
-    CloseButton = false;
+    HasCloseButton = false;
     BeginOrderWithinParent = -1;
     BeginOrderWithinParent = -1;
     BeginOrderWithinContext = -1;
     BeginOrderWithinContext = -1;
     BeginCount = 0;
     BeginCount = 0;
@@ -3507,7 +3506,7 @@ static void ImGui::NavUpdate()
 #endif
 #endif
 }
 }
 
 
-static void ImGui::UpdateMovingWindow()
+void ImGui::UpdateMovingWindow()
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     if (g.MovingWindow != NULL)
     if (g.MovingWindow != NULL)
@@ -3596,7 +3595,7 @@ static void ImGui::UpdateMouseInputs()
 }
 }
 
 
 // The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
 // The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
-void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags()
+void ImGui::UpdateHoveredWindowAndCaptureFlags()
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
 
 
@@ -3767,7 +3766,7 @@ void ImGui::NewFrame()
 
 
     // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
     // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
     UpdateMovingWindow();
     UpdateMovingWindow();
-    NewFrameUpdateHoveredWindowAndCaptureFlags();
+    UpdateHoveredWindowAndCaptureFlags();
 
 
     if (GetFrontMostPopupModal() != NULL)
     if (GetFrontMostPopupModal() != NULL)
         g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f);
         g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f);
@@ -6034,7 +6033,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
         window_just_activated_by_user |= (window != popup_ref.Window);
         window_just_activated_by_user |= (window != popup_ref.Window);
     }
     }
     window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize);
     window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize);
-    window->CloseButton = (p_open != NULL);
+    window->HasCloseButton = (p_open != NULL);
     if (window->Appearing)
     if (window->Appearing)
         SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
         SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
 
 
@@ -8076,7 +8075,7 @@ bool ImGui::SmallButton(const char* label)
     return pressed;
     return pressed;
 }
 }
 
 
-bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
+bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiButtonFlags flags)
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
     if (window->SkipItems)
     if (window->SkipItems)
@@ -8084,24 +8083,33 @@ bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
 
 
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     const ImGuiID id = window->GetID(str_id);
     const ImGuiID id = window->GetID(str_id);
-    float sz = ImGui::GetFrameHeight();
-    const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(sz, sz));
-    ItemSize(bb);
+    const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
+    const float default_size = GetFrameHeight();
+    ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f);
     if (!ItemAdd(bb, id))
     if (!ItemAdd(bb, id))
         return false;
         return false;
 
 
+    if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat)
+        flags |= ImGuiButtonFlags_Repeat;
+
     bool hovered, held;
     bool hovered, held;
-    bool pressed = ButtonBehavior(bb, id, &hovered, &held);
+    bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
 
 
     // Render
     // Render
     const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
     const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
     RenderNavHighlight(bb, id);
     RenderNavHighlight(bb, id);
     RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding);
     RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding);
-    RenderArrow(bb.Min + g.Style.FramePadding, dir);
+    RenderArrow(bb.Min + ImVec2(ImMax(0.0f, size.x - g.FontSize - g.Style.FramePadding.x), ImMax(0.0f, size.y - g.FontSize - g.Style.FramePadding.y)), dir);
 
 
     return pressed;
     return pressed;
 }
 }
 
 
+bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
+{
+    float sz = GetFrameHeight();
+    return ArrowButtonEx(str_id, dir, ImVec2(sz, sz), 0);
+}
+
 // Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack.
 // Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack.
 // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id)
 // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id)
 bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
 bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
@@ -9077,14 +9085,9 @@ template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
 static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags)
 static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-    ImGuiWindow* window = GetCurrentWindow();
+    ImGuiWindow* window = g.CurrentWindow;
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
 
 
-    // Draw frame
-    const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
-    RenderNavHighlight(bb, id);
-    RenderFrame(bb.Min, bb.Max, frame_col, true, style.FrameRounding);
-
     const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
     const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
     const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
     const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
     const bool is_power = (power != 1.0f) && is_decimal;
     const bool is_power = (power != 1.0f) && is_decimal;
@@ -9245,10 +9248,16 @@ static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType d
 }
 }
 
 
 // For 32-bits and larger types, slider bounds are limited to half the natural type range.
 // For 32-bits and larger types, slider bounds are limited to half the natural type range.
-// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2.
-// It would be possible to life that limitation with some work but it doesn't seem to be work it for sliders.
+// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
+// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
 bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags)
 bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags)
 {
 {
+    // Draw frame
+    ImGuiContext& g = *GImGui;
+    const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
+    RenderNavHighlight(bb, id);
+    RenderFrame(bb.Min, bb.Max, frame_col, true, g.Style.FrameRounding);
+
     switch (data_type)
     switch (data_type)
     {
     {
     case ImGuiDataType_S32:
     case ImGuiDataType_S32:
@@ -9524,7 +9533,7 @@ static bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed
         if (g.IO.KeyShift)
         if (g.IO.KeyShift)
             adjust_delta *= 10.0f;
             adjust_delta *= 10.0f;
     }
     }
-    if (g.ActiveIdSource == ImGuiInputSource_Nav)
+    else if (g.ActiveIdSource == ImGuiInputSource_Nav)
     {
     {
         int decimal_precision = (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImParseFormatPrecision(format, 3) : 0;
         int decimal_precision = (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImParseFormatPrecision(format, 3) : 0;
         adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x;
         adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x;

+ 29 - 16
3rdparty/dear-imgui/imgui_demo.cpp

@@ -12,11 +12,11 @@
 // Thank you,
 // Thank you,
 // -Your beloved friend, imgui_demo.cpp (that you won't delete)
 // -Your beloved friend, imgui_demo.cpp (that you won't delete)
 
 
-// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions.
-// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code.
+// Message to beginner C/C++ programmers about the meaning of the 'static' keyword: in this demo code, we frequently we use 'static' variables inside functions.
 // A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function.
 // A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function.
+// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code.
 // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads.
 // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads.
-// This might be a pattern you occasionally want to use in your code, but most of the real data you would be editing is likely to be stored outside your function.
+// This might be a pattern you occasionally want to use in your code, but most of the real data you would be editing is likely to be stored outside your functions.
 
 
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
 #define _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
@@ -76,6 +76,7 @@
 
 
 #if !defined(IMGUI_DISABLE_DEMO_WINDOWS)
 #if !defined(IMGUI_DISABLE_DEMO_WINDOWS)
 
 
+// Forward Declarations
 static void ShowExampleAppConsole(bool* p_open);
 static void ShowExampleAppConsole(bool* p_open);
 static void ShowExampleAppLog(bool* p_open);
 static void ShowExampleAppLog(bool* p_open);
 static void ShowExampleAppLayout(bool* p_open);
 static void ShowExampleAppLayout(bool* p_open);
@@ -89,6 +90,7 @@ static void ShowExampleAppCustomRendering(bool* p_open);
 static void ShowExampleAppMainMenuBar();
 static void ShowExampleAppMainMenuBar();
 static void ShowExampleMenuFile();
 static void ShowExampleMenuFile();
 
 
+// Helper to display a little (?) mark which shows a tooltip when hovered.
 static void ShowHelpMarker(const char* desc)
 static void ShowHelpMarker(const char* desc)
 {
 {
     ImGui::TextDisabled("(?)");
     ImGui::TextDisabled("(?)");
@@ -102,6 +104,7 @@ static void ShowHelpMarker(const char* desc)
     }
     }
 }
 }
 
 
+// Helper to display basic user controls.
 void ImGui::ShowUserGuide()
 void ImGui::ShowUserGuide()
 {
 {
     ImGui::BulletText("Double-click on title bar to collapse window.");
     ImGui::BulletText("Double-click on title bar to collapse window.");
@@ -124,10 +127,11 @@ void ImGui::ShowUserGuide()
     ImGui::Unindent();
     ImGui::Unindent();
 }
 }
 
 
-// Demonstrate most ImGui features (big function!)
+// Demonstrate most Dear ImGui features (this is big function!)
+// You may execute this function to experiment with the UI and understand what it does. You may then search for keywords in the code when you are interested by a specific feature.
 void ImGui::ShowDemoWindow(bool* p_open)
 void ImGui::ShowDemoWindow(bool* p_open)
 {
 {
-    // Examples apps
+    // Examples Apps (accessible from the "Examples" menu)
     static bool show_app_main_menu_bar = false;
     static bool show_app_main_menu_bar = false;
     static bool show_app_console = false;
     static bool show_app_console = false;
     static bool show_app_log = false;
     static bool show_app_log = false;
@@ -139,10 +143,6 @@ void ImGui::ShowDemoWindow(bool* p_open)
     static bool show_app_simple_overlay = false;
     static bool show_app_simple_overlay = false;
     static bool show_app_window_titles = false;
     static bool show_app_window_titles = false;
     static bool show_app_custom_rendering = false;
     static bool show_app_custom_rendering = false;
-    static bool show_app_style_editor = false;
-
-    static bool show_app_metrics = false;
-    static bool show_app_about = false;
 
 
     if (show_app_main_menu_bar)       ShowExampleAppMainMenuBar();
     if (show_app_main_menu_bar)       ShowExampleAppMainMenuBar();
     if (show_app_console)             ShowExampleAppConsole(&show_app_console);
     if (show_app_console)             ShowExampleAppConsole(&show_app_console);
@@ -156,6 +156,11 @@ void ImGui::ShowDemoWindow(bool* p_open)
     if (show_app_window_titles)       ShowExampleAppWindowTitles(&show_app_window_titles);
     if (show_app_window_titles)       ShowExampleAppWindowTitles(&show_app_window_titles);
     if (show_app_custom_rendering)    ShowExampleAppCustomRendering(&show_app_custom_rendering);
     if (show_app_custom_rendering)    ShowExampleAppCustomRendering(&show_app_custom_rendering);
 
 
+    // Dear ImGui Apps (accessible from the "Help" menu)
+    static bool show_app_metrics = false;
+    static bool show_app_style_editor = false;
+    static bool show_app_about = false;
+
     if (show_app_metrics)             { ImGui::ShowMetricsWindow(&show_app_metrics); }
     if (show_app_metrics)             { ImGui::ShowMetricsWindow(&show_app_metrics); }
     if (show_app_style_editor)        { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); }
     if (show_app_style_editor)        { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); }
     if (show_app_about)
     if (show_app_about)
@@ -168,6 +173,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
         ImGui::End();
         ImGui::End();
     }
     }
 
 
+    // Demonstrate the various window flags. Typically you would just use the default!
     static bool no_titlebar = false;
     static bool no_titlebar = false;
     static bool no_scrollbar = false;
     static bool no_scrollbar = false;
     static bool no_menu = false;
     static bool no_menu = false;
@@ -177,7 +183,6 @@ void ImGui::ShowDemoWindow(bool* p_open)
     static bool no_close = false;
     static bool no_close = false;
     static bool no_nav = false;
     static bool no_nav = false;
 
 
-    // Demonstrate the various window flags. Typically you would just use the default.
     ImGuiWindowFlags window_flags = 0;
     ImGuiWindowFlags window_flags = 0;
     if (no_titlebar)  window_flags |= ImGuiWindowFlags_NoTitleBar;
     if (no_titlebar)  window_flags |= ImGuiWindowFlags_NoTitleBar;
     if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
     if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
@@ -188,19 +193,22 @@ void ImGui::ShowDemoWindow(bool* p_open)
     if (no_nav)       window_flags |= ImGuiWindowFlags_NoNav;
     if (no_nav)       window_flags |= ImGuiWindowFlags_NoNav;
     if (no_close)     p_open = NULL; // Don't pass our bool* to Begin
     if (no_close)     p_open = NULL; // Don't pass our bool* to Begin
 
 
+    // We specify a default size in case there's no data in the .ini file. Typically this isn't required! We only do it to make the Demo applications a little more welcoming.
     ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver);
     ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver);
+
+    // Main body of the Demo window starts here.
     if (!ImGui::Begin("ImGui Demo", p_open, window_flags))
     if (!ImGui::Begin("ImGui Demo", p_open, window_flags))
     {
     {
         // Early out if the window is collapsed, as an optimization.
         // Early out if the window is collapsed, as an optimization.
         ImGui::End();
         ImGui::End();
         return;
         return;
     }
     }
-
-    //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);    // 2/3 of the space for widget and 1/3 for labels
-    ImGui::PushItemWidth(-140);                                 // Right align, keep 140 pixels for labels
-
     ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION);
     ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION);
 
 
+    // Most "big" widgets share a common width settings by default.
+    //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);    // Use 2/3 of the space for widgets and 1/3 for labels (default)
+    ImGui::PushItemWidth(ImGui::GetFontSize() * -12);           // Use fixed width for labels (by passing a negative value), the rest goes to widgets. We choose a width proportional to our font size.
+
     // Menu
     // Menu
     if (ImGui::BeginMenuBar())
     if (ImGui::BeginMenuBar())
     {
     {
@@ -302,10 +310,15 @@ void ImGui::ShowDemoWindow(bool* p_open)
             }
             }
 
 
             // Arrow buttons
             // Arrow buttons
+            static int counter = 0;
             float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
             float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
-            if (ImGui::ArrowButton("##left", ImGuiDir_Left)) {}
+            ImGui::PushButtonRepeat(true);
+            if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { counter--; }
             ImGui::SameLine(0.0f, spacing);
             ImGui::SameLine(0.0f, spacing);
-            if (ImGui::ArrowButton("##left", ImGuiDir_Right)) {}
+            if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { counter++; }
+            ImGui::PopButtonRepeat();
+            ImGui::SameLine();
+            ImGui::Text("%d", counter);
 
 
             ImGui::Text("Hover over me");
             ImGui::Text("Hover over me");
             if (ImGui::IsItemHovered())
             if (ImGui::IsItemHovered())

+ 4 - 2
3rdparty/dear-imgui/imgui_internal.h

@@ -966,7 +966,7 @@ struct IMGUI_API ImGuiWindow
     bool                    CollapseToggleWanted;
     bool                    CollapseToggleWanted;
     bool                    SkipItems;                          // Set when items can safely be all clipped (e.g. window not visible or collapsed)
     bool                    SkipItems;                          // Set when items can safely be all clipped (e.g. window not visible or collapsed)
     bool                    Appearing;                          // Set during the frame where the window is appearing (or re-appearing)
     bool                    Appearing;                          // Set during the frame where the window is appearing (or re-appearing)
-    bool                    CloseButton;                        // Set when the window has a close button (p_open != NULL)
+    bool                    HasCloseButton;                     // Set when the window has a close button (p_open != NULL)
     int                     BeginOrderWithinParent;             // Order within immediate parent window, if we are a child window. Otherwise 0.
     int                     BeginOrderWithinParent;             // Order within immediate parent window, if we are a child window. Otherwise 0.
     int                     BeginOrderWithinContext;            // Order within entire imgui context. This is mostly used for debugging submission order related issues.
     int                     BeginOrderWithinContext;            // Order within entire imgui context. This is mostly used for debugging submission order related issues.
     int                     BeginCount;                         // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
     int                     BeginCount;                         // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
@@ -1070,7 +1070,8 @@ namespace ImGui
     IMGUI_API void          Initialize(ImGuiContext* context);
     IMGUI_API void          Initialize(ImGuiContext* context);
     IMGUI_API void          Shutdown(ImGuiContext* context);    // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
     IMGUI_API void          Shutdown(ImGuiContext* context);    // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
 
 
-    IMGUI_API void          NewFrameUpdateHoveredWindowAndCaptureFlags();
+    IMGUI_API void          UpdateHoveredWindowAndCaptureFlags();
+    IMGUI_API void          UpdateMovingWindow();
 
 
     IMGUI_API void                  MarkIniSettingsDirty();
     IMGUI_API void                  MarkIniSettingsDirty();
     IMGUI_API void                  MarkIniSettingsDirty(ImGuiWindow* window);
     IMGUI_API void                  MarkIniSettingsDirty(ImGuiWindow* window);
@@ -1154,6 +1155,7 @@ namespace ImGui
     IMGUI_API bool          ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
     IMGUI_API bool          ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
     IMGUI_API bool          ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
     IMGUI_API bool          ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
     IMGUI_API bool          CloseButton(ImGuiID id, const ImVec2& pos, float radius);
     IMGUI_API bool          CloseButton(ImGuiID id, const ImVec2& pos, float radius);
+    IMGUI_API bool          ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
 
 
     IMGUI_API bool          DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power);
     IMGUI_API bool          DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power);
     IMGUI_API bool          SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags = 0);
     IMGUI_API bool          SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags = 0);