Browse Source

Merge remote-tracking branch 'origin' into 2015-04-indexed-rendering

ocornut 10 years ago
parent
commit
b360c83e92
3 changed files with 221 additions and 144 deletions
  1. 4 1
      README.md
  2. 198 136
      imgui.cpp
  3. 19 7
      imgui.h

+ 4 - 1
README.md

@@ -44,7 +44,10 @@ Gallery
 ![screenshot 4](/web/test_window_04.png?raw=true)
 ![screenshot 4](/web/test_window_04.png?raw=true)
 ![screenshot 5](/web/test_window_05_menus.png?raw=true)
 ![screenshot 5](/web/test_window_05_menus.png?raw=true)
 ![screenshot 6](/web/examples_03.png?raw=true)
 ![screenshot 6](/web/examples_03.png?raw=true)
-![screenshot 7](/web/examples_02.png?raw=true)
+
+![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png)
+
+![screenshot 8](/web/examples_02.png?raw=true)
 
 
 ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with:
 ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with:
 ```
 ```

+ 198 - 136
imgui.cpp

@@ -1,4 +1,4 @@
-// ImGui library v1.40 WIP
+// ImGui library v1.41 WIP
 // See ImGui::ShowTestWindow() for sample code.
 // See ImGui::ShowTestWindow() for sample code.
 // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
 // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
 // Get latest version at https://github.com/ocornut/imgui
 // Get latest version at https://github.com/ocornut/imgui
@@ -136,11 +136,13 @@
  Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
  Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
  Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
  Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
  
  
- - 2015/05/31 (1.39) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
- - 2015/05/31 (1.39) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
- - 2015/05/27 (1.39) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
- - 2015/05/11 (1.39) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened.
- - 2015/05/03 (1.39) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
+ - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence
+ - 2015/06/14 (1.41) - changed Selectable() API from (label, selected, size) to (label, selected, flags, size). Size override should have been rarely be used. Sorry!
+ - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
+ - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
+ - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
+ - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened.
+ - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
  - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete).
  - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete).
  - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
  - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
  - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive.
  - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive.
@@ -326,19 +328,22 @@
  ==================
  ==================
 
 
  - misc: merge or clarify ImVec4 vs ImRect?
  - misc: merge or clarify ImVec4 vs ImRect?
- - window: add horizontal scroll
  - window: fix resize grip rendering scaling along with Rounding style setting
  - window: fix resize grip rendering scaling along with Rounding style setting
  - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit?
  - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit?
  - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. 
  - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. 
  - window: allow resizing of child windows (possibly given min/max for each axis?)
  - window: allow resizing of child windows (possibly given min/max for each axis?)
  - window: background options for child windows, border option (disable rounding)
  - window: background options for child windows, border option (disable rounding)
  - window: resizing from any sides? + mouse cursor directives for app.
  - window: resizing from any sides? + mouse cursor directives for app.
+ - scrolling: add horizontal scroll
+!- scrolling: set scrolling given a position.
+!- scrolling: allow immediately effective change of scroll if we haven't appended items yet
  - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc.
  - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc.
  - widgets: clean up widgets internal toward exposing everything.
  - widgets: clean up widgets internal toward exposing everything.
  - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them.
  - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them.
  - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
  - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
  - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
  - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
  - input text: add ImGuiInputTextFlags_EnterToApply? (off github issue #218)
  - input text: add ImGuiInputTextFlags_EnterToApply? (off github issue #218)
+!- input text: multiple lines inputs (#200)
 !- input number: large int not reliably supported because of int<>float conversions.
 !- input number: large int not reliably supported because of int<>float conversions.
  - input number: optional range min/max for Input*() functions
  - input number: optional range min/max for Input*() functions
  - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
  - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
@@ -359,8 +364,12 @@
  - combo/listbox: keyboard control. need inputtext like non-active focus + key handling. considering keybord for custom listbox (see github pr #203)
  - combo/listbox: keyboard control. need inputtext like non-active focus + key handling. considering keybord for custom listbox (see github pr #203)
  - listbox: multiple selection
  - listbox: multiple selection
  - listbox: user may want to initial scroll to focus on the one selected value?
  - listbox: user may want to initial scroll to focus on the one selected value?
+ - listbox: keyboard navigation.
+ - listbox: scrolling should track modified selection.
  - menus: local shortcuts, global shortcuts (github issue #126)
  - menus: local shortcuts, global shortcuts (github issue #126)
  - menus: icons
  - menus: icons
+ - menus: see we can allow for click-menu-hold-release-on-item to work (like Windows does)
+ - menus: menubars: some sort of priority / effect of main menu-bar on desktop size?
  - tabs
  - tabs
  - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
  - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
  - gauge: various forms of gauge/loading bars widgets
  - gauge: various forms of gauge/loading bars widgets
@@ -381,7 +390,7 @@
  - tooltip: figure out a way to use TextWrapped() in a tooltip.
  - tooltip: figure out a way to use TextWrapped() in a tooltip.
  - settings: write more decent code to allow saving/loading new fields
  - settings: write more decent code to allow saving/loading new fields
  - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file
  - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file
- ! style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost.
+ - style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost.
  - style: checkbox: padding for "active" color should be a multiplier of the 
  - style: checkbox: padding for "active" color should be a multiplier of the 
  - style: colorbox not always square?
  - style: colorbox not always square?
  - text: simple markup language for color change?
  - text: simple markup language for color change?
@@ -392,7 +401,7 @@
  - filters: set a current filter that tree node can automatically query to hide themselves
  - filters: set a current filter that tree node can automatically query to hide themselves
  - filters: handle wildcards (with implicit leading/trailing *), regexps
  - filters: handle wildcards (with implicit leading/trailing *), regexps
  - 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)
  - 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)
- ! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
+!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
  - keyboard: full keyboard navigation and focus.
  - keyboard: full keyboard navigation and focus.
  - input: rework IO to be able to pass actual events to fix temporal aliasing issues.
  - input: rework IO to be able to pass actual events to fix temporal aliasing issues.
  - input: support track pad style scrolling & slider edit.
  - input: support track pad style scrolling & slider edit.
@@ -511,7 +520,6 @@ struct ImGuiState;
 struct ImGuiWindow;
 struct ImGuiWindow;
 typedef int ImGuiLayoutType;      // enum ImGuiLayoutType_
 typedef int ImGuiLayoutType;      // enum ImGuiLayoutType_
 typedef int ImGuiButtonFlags;     // enum ImGuiButtonFlags_
 typedef int ImGuiButtonFlags;     // enum ImGuiButtonFlags_
-typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_
 
 
 static bool         ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0);
 static bool         ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0);
 static void         LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);
 static void         LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);
@@ -972,18 +980,19 @@ enum ImGuiLayoutType_
 
 
 enum ImGuiButtonFlags_
 enum ImGuiButtonFlags_
 {
 {
-    ImGuiButtonFlags_Repeat             = (1 << 0),
-    ImGuiButtonFlags_PressedOnClick     = (1 << 1),
-    ImGuiButtonFlags_FlattenChilds      = (1 << 2),
-    ImGuiButtonFlags_DontClosePopups    = (1 << 3),
-    ImGuiButtonFlags_Disabled           = (1 << 4)
+    ImGuiButtonFlags_Repeat             = 1 << 0,
+    ImGuiButtonFlags_PressedOnClick     = 1 << 1,
+    ImGuiButtonFlags_FlattenChilds      = 1 << 2,
+    ImGuiButtonFlags_DontClosePopups    = 1 << 3,
+    ImGuiButtonFlags_Disabled           = 1 << 4
 };
 };
 
 
-enum ImGuiSelectableFlags_
+enum ImGuiSelectableFlagsPrivate_
 {
 {
-    ImGuiSelectableFlags_MenuItem        = (1 << 0),
-    ImGuiSelectableFlags_DontClosePopups = (1 << 1),
-    ImGuiSelectableFlags_Disabled        = (1 << 2)
+    // NB: need to be in sync with last value of ImGuiSelectableFlags_
+    ImGuiSelectableFlags_MenuItem           = 1 << 2,
+    ImGuiSelectableFlags_Disabled           = 1 << 3,
+    ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 4
 };
 };
 
 
 
 
@@ -1294,7 +1303,6 @@ struct ImGuiState
     ImGuiTextEditState      InputTextState;
     ImGuiTextEditState      InputTextState;
     ImGuiID                 ScalarAsInputTextId;                // Temporary text input when CTRL+clicking on a slider, etc.
     ImGuiID                 ScalarAsInputTextId;                // Temporary text input when CTRL+clicking on a slider, etc.
     ImGuiStorage            ColorEditModeStorage;               // Store user selection of color edit mode
     ImGuiStorage            ColorEditModeStorage;               // Store user selection of color edit mode
-    ImGuiID                 ActiveComboID;
     ImVec2                  ActiveClickDeltaToCenter;
     ImVec2                  ActiveClickDeltaToCenter;
     float                   DragCurrentValue;                   // current dragged value, always float, not rounded by end-user precision settings
     float                   DragCurrentValue;                   // current dragged value, always float, not rounded by end-user precision settings
     ImVec2                  DragLastMouseDelta;
     ImVec2                  DragLastMouseDelta;
@@ -1355,7 +1363,6 @@ struct ImGuiState
         SetNextTreeNodeOpenedCond = 0;
         SetNextTreeNodeOpenedCond = 0;
 
 
         ScalarAsInputTextId = 0;
         ScalarAsInputTextId = 0;
-        ActiveComboID = 0;
         ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
         ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
         DragCurrentValue = 0.0f;
         DragCurrentValue = 0.0f;
         DragLastMouseDelta = ImVec2(0.0f, 0.0f);
         DragLastMouseDelta = ImVec2(0.0f, 0.0f);
@@ -1395,7 +1402,7 @@ struct ImGuiWindow
     ImVec2                  SizeContents;                       // Size of contents (== extents reach of the drawing cursor) from previous frame
     ImVec2                  SizeContents;                       // Size of contents (== extents reach of the drawing cursor) from previous frame
     ImGuiID                 MoveID;                             // == window->GetID("#MOVE")
     ImGuiID                 MoveID;                             // == window->GetID("#MOVE")
     float                   ScrollY;
     float                   ScrollY;
-    float                   NextScrollY;
+    float                   ScrollTargetCenterY;                // position which we aim to center on
     bool                    ScrollbarY;
     bool                    ScrollbarY;
     bool                    Active;                             // Set to true on Begin()
     bool                    Active;                             // Set to true on Begin()
     bool                    WasActive;
     bool                    WasActive;
@@ -1761,7 +1768,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
     Size = SizeFull = ImVec2(0.0f, 0.0f);
     Size = SizeFull = ImVec2(0.0f, 0.0f);
     SizeContents = ImVec2(0.0f, 0.0f);
     SizeContents = ImVec2(0.0f, 0.0f);
     ScrollY = 0.0f;
     ScrollY = 0.0f;
-    NextScrollY = 0.0f;
+    ScrollTargetCenterY = -1.0f;
     ScrollbarY = false;
     ScrollbarY = false;
     Active = WasActive = false;
     Active = WasActive = false;
     Accessed = false;
     Accessed = false;
@@ -2188,7 +2195,7 @@ void ImGui::NewFrame()
             if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
             if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
             {
             {
                 const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
                 const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
-                window->NextScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines;
+                window->ScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines;
             }
             }
         }
         }
     }
     }
@@ -2696,7 +2703,7 @@ static void RenderCheckMark(ImVec2 pos, ImU32 col)
     a.x = pos.x + start_x;
     a.x = pos.x + start_x;
     b.x = a.x + rem_third;
     b.x = a.x + rem_third;
     c.x = a.x + rem_third * 3.0f;
     c.x = a.x + rem_third * 3.0f;
-    b.y = pos.y + (float)(int)(g.Font->BaseLine * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y);
+    b.y = pos.y + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y);
     a.y = b.y - rem_third;
     a.y = b.y - rem_third;
     c.y = b.y - rem_third * 2.0f;
     c.y = b.y - rem_third * 2.0f;
 
 
@@ -3119,6 +3126,14 @@ static void ClosePopupToLevel(int remaining)
     g.OpenedPopupStack.resize(remaining);
     g.OpenedPopupStack.resize(remaining);
 }
 }
 
 
+static void ClosePopup(ImGuiID id)
+{
+    if (!IsPopupOpen(id))
+        return;
+    ImGuiState& g = *GImGui;
+    ClosePopupToLevel(g.OpenedPopupStack.size() - 1);
+}
+
 // Close the popup we have begin-ed into.
 // Close the popup we have begin-ed into.
 void ImGui::CloseCurrentPopup()
 void ImGui::CloseCurrentPopup()
 {
 {
@@ -3149,7 +3164,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
     }
     }
 
 
     ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
     ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
-    ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_ShowBorders|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
+    ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
 
 
     char name[32];
     char name[32];
     if (flags & ImGuiWindowFlags_ChildMenu)
     if (flags & ImGuiWindowFlags_ChildMenu)
@@ -3169,7 +3184,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
 
 
 bool ImGui::BeginPopup(const char* str_id)
 bool ImGui::BeginPopup(const char* str_id)
 {
 {
-    return BeginPopupEx(str_id, 0);
+    return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders);
 }
 }
 
 
 void ImGui::EndPopup()
 void ImGui::EndPopup()
@@ -3461,7 +3476,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
     }
     }
 
 
     // Process SetNextWindow***() calls
     // Process SetNextWindow***() calls
-    bool window_pos_set_by_api = false;
+    bool window_pos_set_by_api = false, window_size_set_by_api = false;
     if (g.SetNextWindowPosCond)
     if (g.SetNextWindowPosCond)
     {
     {
         const ImVec2 backup_cursor_pos = window->DC.CursorPos;                  // FIXME: not sure of the exact reason of this anymore :( need to look into that.
         const ImVec2 backup_cursor_pos = window->DC.CursorPos;                  // FIXME: not sure of the exact reason of this anymore :( need to look into that.
@@ -3474,6 +3489,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
     if (g.SetNextWindowSizeCond)
     if (g.SetNextWindowSizeCond)
     {
     {
         if (!window_was_visible) window->SetWindowSizeAllowFlags |= ImGuiSetCond_Appearing;
         if (!window_was_visible) window->SetWindowSizeAllowFlags |= ImGuiSetCond_Appearing;
+        window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0;
         ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond);
         ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond);
         g.SetNextWindowSizeCond = 0;
         g.SetNextWindowSizeCond = 0;
     }
     }
@@ -3565,7 +3581,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
         if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && !window_was_visible)
         if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && !window_was_visible)
         {
         {
             window->HiddenFrames = 1;
             window->HiddenFrames = 1;
-            window->Size = window->SizeFull = window->SizeContents = ImVec2(0.f, 0.f);  // TODO: We don't support SetNextWindowSize() for tooltips or popups yet
+            if (!window_size_set_by_api)
+                window->Size = window->SizeFull = ImVec2(0.f, 0.f);
+            window->SizeContents = ImVec2(0.f, 0.f);
         }
         }
 
 
         // Calculate auto-fit size
         // Calculate auto-fit size
@@ -3595,11 +3613,11 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
         }
         }
         else
         else
         {
         {
-            if (flags & ImGuiWindowFlags_AlwaysAutoResize)
+            if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window_size_set_by_api)
             {
             {
                 window->SizeFull = size_auto_fit;
                 window->SizeFull = size_auto_fit;
             }
             }
-            else if (window->AutoFitFrames > 0)
+            else if (window->AutoFitFrames > 0 && !window_size_set_by_api)
             {
             {
                 // Auto-fit only grows during the first few frames
                 // Auto-fit only grows during the first few frames
                 window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit;
                 window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit;
@@ -3699,11 +3717,14 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
         window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX;
         window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX;
 
 
         // Apply scrolling
         // Apply scrolling
-        window->ScrollY = window->NextScrollY;
+        if (window->ScrollTargetCenterY >= 0.0f)
+        {
+            window->ScrollY = window->ScrollTargetCenterY - (window->Pos.y + (window->SizeFull.y + window->TitleBarHeight() + window->WindowPadding().y) * 0.5f);
+            window->ScrollTargetCenterY = -1.0f;
+        }
         window->ScrollY = ImMax(window->ScrollY, 0.0f);
         window->ScrollY = ImMax(window->ScrollY, 0.0f);
         if (!window->Collapsed && !window->SkipItems)
         if (!window->Collapsed && !window->SkipItems)
             window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y));
             window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y));
-        window->NextScrollY = window->ScrollY;
 
 
         // Draw window + handle manual resize
         // Draw window + handle manual resize
         ImRect title_bar_rect = window->TitleBarRect();
         ImRect title_bar_rect = window->TitleBarRect();
@@ -3998,7 +4019,6 @@ static void Scrollbar(ImGuiWindow* window)
         // Apply scroll
         // Apply scroll
         const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm));
         const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm));
         window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y));
         window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y));
-        window->NextScrollY = window->ScrollY;
 
 
         // Update values for rendering
         // Update values for rendering
         scroll_ratio = ImSaturate(window->ScrollY / scroll_max);
         scroll_ratio = ImSaturate(window->ScrollY / scroll_max);
@@ -4303,36 +4323,43 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
     return "Unknown";
     return "Unknown";
 }
 }
 
 
+bool ImGui::IsWindowHovered()
+{
+    ImGuiState& g = *GImGui;
+    return g.HoveredWindow == g.CurrentWindow;
+}
+
 bool ImGui::IsWindowFocused()
 bool ImGui::IsWindowFocused()
 {
 {
     ImGuiState& g = *GImGui;
     ImGuiState& g = *GImGui;
-    ImGuiWindow* window = GetCurrentWindow();
-    return g.FocusedWindow == window;
+    return g.FocusedWindow == g.CurrentWindow;
 }
 }
 
 
 bool ImGui::IsRootWindowFocused()
 bool ImGui::IsRootWindowFocused()
 {
 {
     ImGuiState& g = *GImGui;
     ImGuiState& g = *GImGui;
-    ImGuiWindow* root_window = GetCurrentWindow()->RootWindow;
+    ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
     return g.FocusedWindow == root_window;
     return g.FocusedWindow == root_window;
 }
 }
 
 
 bool ImGui::IsRootWindowOrAnyChildFocused()
 bool ImGui::IsRootWindowOrAnyChildFocused()
 {
 {
     ImGuiState& g = *GImGui;
     ImGuiState& g = *GImGui;
-    ImGuiWindow* root_window = GetCurrentWindow()->RootWindow;
+    ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
     return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window;
     return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window;
 }
 }
 
 
 float ImGui::GetWindowWidth()
 float ImGui::GetWindowWidth()
 {
 {
-    ImGuiWindow* window = GetCurrentWindow();
+    ImGuiState& g = *GImGui;
+    ImGuiWindow* window = g.CurrentWindow;
     return window->Size.x;
     return window->Size.x;
 }
 }
 
 
 ImVec2 ImGui::GetWindowPos()
 ImVec2 ImGui::GetWindowPos()
 {
 {
-    ImGuiWindow* window = GetCurrentWindow();
+    ImGuiState& g = *GImGui;
+    ImGuiWindow* window = g.CurrentWindow;
     return window->Pos;
     return window->Pos;
 }
 }
 
 
@@ -4621,7 +4648,7 @@ float ImGui::GetScrollMaxY()
 void ImGui::SetScrollPosHere()
 void ImGui::SetScrollPosHere()
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-    window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y);
+    window->ScrollTargetCenterY = (float)(int)(window->DC.CursorPos.y + window->ScrollY - window->DC.PrevLineHeight * 0.5f);
 }
 }
 
 
 void ImGui::SetKeyboardFocusHere(int offset)
 void ImGui::SetKeyboardFocusHere(int offset)
@@ -5083,7 +5110,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
 
 
     // Default to using texture ID as ID. User can still push string/integer prefixes.
     // Default to using texture ID as ID. User can still push string/integer prefixes.
-    // We could hash the size/uv to create a unique ID but that would prevent the user from animating buttons.
+    // We could hash the size/uv to create a unique ID but that would prevent the user from animating UV.
     ImGui::PushID((void *)user_texture_id);
     ImGui::PushID((void *)user_texture_id);
     const ImGuiID id = window->GetID("#image");
     const ImGuiID id = window->GetID("#image");
     ImGui::PopID();
     ImGui::PopID();
@@ -5100,8 +5127,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
 
 
     // Render
     // Render
     const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
     const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
-    if (padding.x > 0.0f || padding.y > 0.0f)
-        RenderFrame(bb.Min, bb.Max, col);
+    RenderFrame(bb.Min, bb.Max, col);
     if (bg_col.w > 0.0f)
     if (bg_col.w > 0.0f)
         window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, window->Color(bg_col));
         window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, window->Color(bg_col));
     window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, window->Color(tint_col));
     window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, window->Color(tint_col));
@@ -5615,13 +5641,15 @@ static inline float RoundScalar(float value, int decimal_precision)
     //    0: 1, 1: 0.1, 2: 0.01, etc.
     //    0: 1, 1: 0.1, 2: 0.01, etc.
     // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
     // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
     // FIXME: Investigate better rounding methods
     // FIXME: Investigate better rounding methods
-    const float min_step = 1.0f / powf(10.0f, (float)decimal_precision);
-    const float remainder = fmodf(value, min_step);
+    float min_step = 1.0f / powf(10.0f, (float)decimal_precision);
+    bool negative = value < 0.0f;
+    value = fabsf(value);
+    float remainder = fmodf(value, min_step);
     if (remainder <= min_step*0.5f)
     if (remainder <= min_step*0.5f)
         value -= remainder;
         value -= remainder;
     else
     else
         value += (min_step - remainder);
         value += (min_step - remainder);
-    return value;
+    return negative ? -value : value;
 }
 }
 
 
 static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal)
 static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal)
@@ -5704,7 +5732,6 @@ static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, f
 
 
             // Round past decimal precision
             // Round past decimal precision
             new_value = RoundScalar(new_value, decimal_precision);
             new_value = RoundScalar(new_value, decimal_precision);
-
             if (*v != new_value)
             if (*v != new_value)
             {
             {
                 *v = new_value;
                 *v = new_value;
@@ -7270,7 +7297,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char** items, int
 bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items)
 bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items)
 {
 {
     int items_count = 0;
     int items_count = 0;
-    const char* p = items_separated_by_zeros;       // FIXME-OPT: Avoid computing this
+    const char* p = items_separated_by_zeros;       // FIXME-OPT: Avoid computing this, or at least only when combo is open
     while (*p)
     while (*p)
     {
     {
         p += strlen(p) + 1;
         p += strlen(p) + 1;
@@ -7302,7 +7329,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
     const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
     const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
     const bool hovered = IsHovered(frame_bb, id);
     const bool hovered = IsHovered(frame_bb, id);
 
 
-    bool value_changed = false;
     const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
     const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
     RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
     RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
     RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding);	// FIXME-ROUNDING
     RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding);	// FIXME-ROUNDING
@@ -7318,80 +7344,81 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
     if (label_size.x > 0)
     if (label_size.x > 0)
         RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
         RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
     
     
-    ImGui::PushID((int)id);
     bool menu_toggled = false;
     bool menu_toggled = false;
     if (hovered)
     if (hovered)
     {
     {
         g.HoveredId = id;
         g.HoveredId = id;
         if (g.IO.MouseClicked[0])
         if (g.IO.MouseClicked[0])
         {
         {
-            menu_toggled = true;
-            g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id;
-            if (g.ActiveComboID)
-                FocusWindow(window);
+            SetActiveId(0);
+            if (IsPopupOpen(id))
+            {
+                ClosePopup(id);
+            }
+            else
+            {
+            	FocusWindow(window);
+                ImGui::OpenPopup(label);
+                menu_toggled = true;
+            }
         }
         }
     }
     }
     
     
-    if (g.ActiveComboID == id)
+    bool value_changed = false;
+    if (IsPopupOpen(id))
     {
     {
         // Size default to hold ~7 items
         // Size default to hold ~7 items
         if (height_in_items < 0)
         if (height_in_items < 0)
             height_in_items = 7;
             height_in_items = 7;
 
 
         const ImVec2 backup_pos = ImGui::GetCursorPos();
         const ImVec2 backup_pos = ImGui::GetCursorPos();
-        const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x;
         const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3);
         const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3);
-        const ImRect popup_rect(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height));
-        ImGui::SetCursorPos(popup_rect.Min - window->Pos);
-
-        const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
+        const ImRect popup_rect(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImVec2(frame_bb.Max.x, frame_bb.Max.y + popup_height));
+        ImGui::SetNextWindowPos(popup_rect.Min);
+        ImGui::SetNextWindowSize(popup_rect.GetSize());
         ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
         ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
-        ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags);
-        ImGui::Spacing();
-
-        bool combo_item_active = false;
-        combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY"));
 
 
-        // Display items
-        for (int i = 0; i < items_count; i++)
+        const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
+        if (BeginPopupEx(label, flags))
         {
         {
-            ImGui::PushID((void*)(intptr_t)i);
-            const bool item_selected = (i == *current_item);
-            const char* item_text;
-            if (!items_getter(data, i, &item_text))
-                item_text = "*Unknown item*";
-            if (ImGui::Selectable(item_text, item_selected))
+            // Display items
+            ImGui::Spacing();
+            for (int i = 0; i < items_count; i++)
             {
             {
-                SetActiveId(0);
-                g.ActiveComboID = 0;
-                value_changed = true;
-                *current_item = i;
+                ImGui::PushID((void*)(intptr_t)i);
+                const bool item_selected = (i == *current_item);
+                const char* item_text;
+                if (!items_getter(data, i, &item_text))
+                    item_text = "*Unknown item*";
+                if (ImGui::Selectable(item_text, item_selected))
+                {
+                    SetActiveId(0);
+                    value_changed = true;
+                    *current_item = i;
+                }
+                if (item_selected && menu_toggled)
+                    ImGui::SetScrollPosHere();
+                ImGui::PopID();
             }
             }
-            if (item_selected && menu_toggled)
-                ImGui::SetScrollPosHere();
-            combo_item_active |= ImGui::IsItemActive();
-            ImGui::PopID();
+            ImGui::EndPopup();
         }
         }
-        ImGui::EndChild();
         ImGui::PopStyleVar();
         ImGui::PopStyleVar();
-        ImGui::SetCursorPos(backup_pos);
-        
-        if (!combo_item_active && g.ActiveId != 0)
-            g.ActiveComboID = 0;
     }
     }
-
-    ImGui::PopID();
-
     return value_changed;
     return value_changed;
 }
 }
 
 
-static bool SelectableEx(const char* label, bool selected, const ImVec2& size_arg, const ImVec2 size_draw_arg, ImGuiSelectableFlags flags)
+// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image.
+// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
+bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
 {
 {
     ImGuiState& g = *GImGui;
     ImGuiState& g = *GImGui;
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
     if (window->SkipItems)
     if (window->SkipItems)
         return false;
         return false;
 
 
+    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
+        PopClipRect();
+
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
     ImGuiID id = window->GetID(label);
     ImGuiID id = window->GetID(label);
     ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
     ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
@@ -7403,10 +7430,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
 
 
     // Fill horizontal space.
     // Fill horizontal space.
     ImVec2 window_padding = window->WindowPadding();
     ImVec2 window_padding = window->WindowPadding();
-    float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x);
-    ImVec2 size_draw(size_draw_arg.x != 0.0f ? size_draw_arg.x : w_draw, size_draw_arg.y != 0.0f ? size_draw_arg.y : size.y);
+    float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? ImGui::GetWindowContentRegionMax().x : ImGui::GetContentRegionMax().x;
+    float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x);
+    ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y);
     ImRect bb_with_spacing(pos, pos + size_draw);
     ImRect bb_with_spacing(pos, pos + size_draw);
-    if (size_draw_arg.x == 0.0f)
+    if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth))
         bb_with_spacing.Max.x += window_padding.x;
         bb_with_spacing.Max.x += window_padding.x;
 
 
     // Selectables are tightly packed together, we extend the box to cover spacing between selectable.
     // Selectables are tightly packed together, we extend the box to cover spacing between selectable.
@@ -7419,7 +7447,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
     bb_with_spacing.Max.x += spacing_R;
     bb_with_spacing.Max.x += spacing_R;
     bb_with_spacing.Max.y += spacing_D;
     bb_with_spacing.Max.y += spacing_D;
     if (!ItemAdd(bb_with_spacing, &id))
     if (!ItemAdd(bb_with_spacing, &id))
+    {
+        if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
+            PushColumnClipRect();
         return false;
         return false;
+    }
 
 
     bool hovered, held;
     bool hovered, held;
     bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, ((flags & ImGuiSelectableFlags_MenuItem) ? ImGuiButtonFlags_PressedOnClick : 0) | ((flags & ImGuiSelectableFlags_Disabled) ? ImGuiButtonFlags_Disabled : 0));
     bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, ((flags & ImGuiSelectableFlags_MenuItem) ? ImGuiButtonFlags_PressedOnClick : 0) | ((flags & ImGuiSelectableFlags_Disabled) ? ImGuiButtonFlags_Disabled : 0));
@@ -7430,8 +7462,15 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
     if (hovered || selected)
     if (hovered || selected)
     {
     {
         const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
         const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
-        RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding);
+        RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f);
+    }
+
+    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
+    {
+        PushColumnClipRect();
+        bb_with_spacing.Max.x -= (ImGui::GetContentRegionMax().x - max_x);
     }
     }
+
     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
     RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size);
     RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size);
     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
@@ -7442,16 +7481,9 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
     return pressed;
     return pressed;
 }
 }
 
 
-// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image.
-// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
-bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg)
-{
-    return SelectableEx(label, selected, size_arg, size_arg, 0);
-}
-
-bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg)
+bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
 {
 {
-    if (SelectableEx(label, *p_selected, size_arg, size_arg, 0))
+    if (ImGui::Selectable(label, *p_selected, flags, size_arg))
     {
     {
         *p_selected = !*p_selected;
         *p_selected = !*p_selected;
         return true;
         return true;
@@ -7567,7 +7599,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
     float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
     float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
     float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
     float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
 
 
-    bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), ImGuiSelectableFlags_MenuItem | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
+    bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
     if (shortcut_size.x > 0.0f)
     if (shortcut_size.x > 0.0f)
     {
     {
         ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
         ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
@@ -7680,7 +7712,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
         window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
         window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
         float w = label_size.x;
         float w = label_size.x;
-        pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
+        pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
         ImGui::PopStyleVar();
         ImGui::PopStyleVar();
         ImGui::SameLine();
         ImGui::SameLine();
         window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
         window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
@@ -7690,7 +7722,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
         popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
         popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
         float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
         float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
         float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
         float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
-        pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0));
+        pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
         if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
         if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
         RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false);
         RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false);
         if (!enabled) ImGui::PopStyleColor();
         if (!enabled) ImGui::PopStyleColor();
@@ -7750,7 +7782,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
     if (opened)
     if (opened)
     {
     {
         ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
         ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
-        ImGuiWindowFlags flags = (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu;
+        ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu);
         opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
         opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
     }
     }
 
 
@@ -7773,7 +7805,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
     const ImGuiID id = window->GetID("#colorbutton");
     const ImGuiID id = window->GetID("#colorbutton");
     const float square_size = g.FontSize;
     const float square_size = g.FontSize;
-    const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2)));
+    const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.y*2, square_size + (small_height ? 0 : style.FramePadding.y*2)));
     ItemSize(bb, small_height ? 0.0f : style.FramePadding.y);
     ItemSize(bb, small_height ? 0.0f : style.FramePadding.y);
     if (!ItemAdd(bb, &id))
     if (!ItemAdd(bb, &id))
         return false;
         return false;
@@ -7820,7 +7852,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
     const ImGuiID id = window->GetID(label);
     const ImGuiID id = window->GetID(label);
     const float w_full = ImGui::CalcItemWidth();
     const float w_full = ImGui::CalcItemWidth();
-    const float square_sz = (g.FontSize + style.FramePadding.x * 2.0f);
+    const float square_sz = (g.FontSize + style.FramePadding.y * 2.0f);
 
 
     ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
     ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
     if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton)
     if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton)
@@ -9219,7 +9251,8 @@ bool    ImFontAtlas::Build()
         const float font_scale = stbtt_ScaleForPixelHeight(&data.FontInfo, data.SizePixels);
         const float font_scale = stbtt_ScaleForPixelHeight(&data.FontInfo, data.SizePixels);
         int font_ascent, font_descent, font_line_gap;
         int font_ascent, font_descent, font_line_gap;
         stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap);
         stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap);
-        data.OutFont->BaseLine = (font_ascent * font_scale);
+        data.OutFont->Ascent = (font_ascent * font_scale);
+        data.OutFont->Descent = (font_descent * font_scale);
         data.OutFont->Glyphs.resize(0);
         data.OutFont->Glyphs.resize(0);
 
 
         const float uv_scale_x = 1.0f / TexWidth;
         const float uv_scale_x = 1.0f / TexWidth;
@@ -9378,7 +9411,7 @@ void    ImFont::Clear()
 {
 {
     FontSize = 0.0f;
     FontSize = 0.0f;
     DisplayOffset = ImVec2(-0.5f, 0.5f);
     DisplayOffset = ImVec2(-0.5f, 0.5f);
-    BaseLine = 0.0f;
+    Ascent = Descent = 0.0f;
     ContainerAtlas = NULL;
     ContainerAtlas = NULL;
     Glyphs.clear();
     Glyphs.clear();
     FallbackGlyph = NULL;
     FallbackGlyph = NULL;
@@ -9735,12 +9768,20 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
         if (c == 0)
         if (c == 0)
             break;
             break;
 
 
-        if (c == '\n')
+        if (c < 32)
         {
         {
-            line_width = word_width = blank_width = 0.0f;
-            inside_word = true;
-            s = next_s;
-            continue;
+            if (c == '\n')
+            {
+                line_width = word_width = blank_width = 0.0f;
+                inside_word = true;
+                s = next_s;
+                continue;
+            }
+            if (c == '\r')
+            {
+                s = next_s;
+                continue;
+            }
         }
         }
 
 
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
@@ -9846,12 +9887,17 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
                 break;
                 break;
         }
         }
         
         
-        if (c == '\n')
+        if (c < 32)
         {
         {
-            text_size.x = ImMax(text_size.x, line_width);
-            text_size.y += line_height;
-            line_width = 0.0f;
-            continue;
+            if (c == '\n')
+            {
+                text_size.x = ImMax(text_size.x, line_width);
+                text_size.y += line_height;
+                line_width = 0.0f;
+                continue;
+            }
+            if (c == '\r')
+                continue;
         }
         }
         
         
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
@@ -9893,12 +9939,17 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be
     {
     {
         const unsigned int c = (unsigned int)(*s++);
         const unsigned int c = (unsigned int)(*s++);
 
 
-        if (c == '\n')
+        if (c < 32)
         {
         {
-            text_size.x = ImMax(text_size.x, line_width);
-            text_size.y += line_height;
-            line_width = 0.0f;
-            continue;
+            if (c == '\n')
+            {
+                text_size.x = ImMax(text_size.x, line_width);
+                text_size.y += line_height;
+                line_width = 0.0f;
+                continue;
+            }
+            if (c == '\r')
+                continue;
         }
         }
         
         
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
         const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
@@ -9994,11 +10045,16 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
                 break;
                 break;
         }
         }
 
 
-        if (c == '\n')
+        if (c < 32)
         {
         {
-            x = pos.x;
-            y += line_height;
-            continue;
+            if (c == '\n')
+            {
+                x = pos.x;
+                y += line_height;
+                continue;
+            }
+            if (c == '\r')
+                continue;
         }
         }
 
 
         float char_width = 0.0f;
         float char_width = 0.0f;
@@ -10593,7 +10649,7 @@ void ImGui::ShowTestWindow(bool* opened)
                     ImGui::SameLine();
                     ImGui::SameLine();
                 ImGui::PushID(i);
                 ImGui::PushID(i);
                 int frame_padding = -1 + i;     // -1 = uses default padding
                 int frame_padding = -1 + i;     // -1 = uses default padding
-                if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding))
+                if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255)))
                     pressed_count += 1;
                     pressed_count += 1;
                 ImGui::PopID();
                 ImGui::PopID();
             }
             }
@@ -10626,7 +10682,7 @@ void ImGui::ShowTestWindow(bool* opened)
                 for (int i = 0; i < 16; i++)
                 for (int i = 0; i < 16; i++)
                 {
                 {
                     ImGui::PushID(i);
                     ImGui::PushID(i);
-                    if (ImGui::Selectable("Me", &selected[i], ImVec2(50,50)))
+                    if (ImGui::Selectable("Me", &selected[i], 0, ImVec2(50,50)))
                     {
                     {
                         int x = i % 4, y = i / 4;
                         int x = i % 4, y = i / 4;
                         if (x > 0) selected[i - 1] ^= 1;
                         if (x > 0) selected[i - 1] ^= 1;
@@ -10828,13 +10884,13 @@ void ImGui::ShowTestWindow(bool* opened)
             ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%");
             ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%");
 
 
             static float f1=1.00f, f2=0.0067f;
             static float f1=1.00f, f2=0.0067f;
-            ImGui::DragFloat("drag float", &f1, 1.0f);
+            ImGui::DragFloat("drag float", &f1, 0.005f);
             ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
             ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
         }
         }
 
 
         {
         {
             static int i1=0;
             static int i1=0;
-            ImGui::SliderInt("slider int", &i1, 0, 3);
+            ImGui::SliderInt("slider int", &i1, -1, 3);
             ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value.");
             ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value.");
 
 
             static float f1=0.123f, f2=0.0f;
             static float f1=0.123f, f2=0.0f;
@@ -11213,9 +11269,14 @@ void ImGui::ShowTestWindow(bool* opened)
         ImGui::Separator();
         ImGui::Separator();
         const char* names[3] = { "One", "Two", "Three" };
         const char* names[3] = { "One", "Two", "Three" };
         const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
         const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
+        static int selected = -1;
         for (int i = 0; i < 3; i++)
         for (int i = 0; i < 3; i++)
         {
         {
-            ImGui::Text("%04d", i); ImGui::NextColumn();
+            char label[32];
+            sprintf(label, "%04d", i);
+            if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
+                selected = i;
+            ImGui::NextColumn();
             ImGui::Text(names[i]); ImGui::NextColumn();
             ImGui::Text(names[i]); ImGui::NextColumn();
             ImGui::Text(paths[i]); ImGui::NextColumn(); 
             ImGui::Text(paths[i]); ImGui::NextColumn(); 
             ImGui::Text("...."); ImGui::NextColumn();
             ImGui::Text("...."); ImGui::NextColumn();
@@ -11465,6 +11526,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
                 NodeDrawList(window->DrawList, "DrawList");
                 NodeDrawList(window->DrawList, "DrawList");
                 if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
                 if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
                 if (window->DC.ChildWindows.size() > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
                 if (window->DC.ChildWindows.size() > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
+                ImGui::BulletText("Storage: %d bytes", (int)window->StateStorage.Data.size() * sizeof(ImGuiStorage::Pair));
                 ImGui::TreePop();
                 ImGui::TreePop();
             }
             }
         };
         };

+ 19 - 7
imgui.h

@@ -1,4 +1,4 @@
-// ImGui library v1.40 WIP
+// ImGui library v1.41 WIP
 // See .cpp file for documentation.
 // See .cpp file for documentation.
 // See ImGui::ShowTestWindow() for sample code.
 // See ImGui::ShowTestWindow() for sample code.
 // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
 // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@@ -13,7 +13,7 @@
 #include <stdlib.h>         // NULL, malloc, free, qsort, atoi
 #include <stdlib.h>         // NULL, malloc, free, qsort, atoi
 #include <string.h>         // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
 #include <string.h>         // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
 
 
-#define IMGUI_VERSION       "1.40 WIP"
+#define IMGUI_VERSION       "1.41 WIP"
 
 
 // Define assertion handler.
 // Define assertion handler.
 #ifndef IM_ASSERT
 #ifndef IM_ASSERT
@@ -48,6 +48,7 @@ typedef int ImGuiMouseCursor;       // enum ImGuiMouseCursor_
 typedef int ImGuiWindowFlags;       // enum ImGuiWindowFlags_
 typedef int ImGuiWindowFlags;       // enum ImGuiWindowFlags_
 typedef int ImGuiSetCond;           // enum ImGuiSetCond_
 typedef int ImGuiSetCond;           // enum ImGuiSetCond_
 typedef int ImGuiInputTextFlags;    // enum ImGuiInputTextFlags_
 typedef int ImGuiInputTextFlags;    // enum ImGuiInputTextFlags_
+typedef int ImGuiSelectableFlags;   // enum ImGuiSelectableFlags_
 struct ImGuiTextEditCallbackData;   // for advanced uses of InputText() 
 struct ImGuiTextEditCallbackData;   // for advanced uses of InputText() 
 typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
 typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
 
 
@@ -236,7 +237,7 @@ namespace ImGui
     IMGUI_API bool          SmallButton(const char* label);
     IMGUI_API bool          SmallButton(const char* label);
     IMGUI_API bool          InvisibleButton(const char* str_id, const ImVec2& size);
     IMGUI_API bool          InvisibleButton(const char* str_id, const ImVec2& size);
     IMGUI_API void          Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
     IMGUI_API void          Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
-    IMGUI_API bool          ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0),  const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,1), const ImVec4& tint_col = ImVec4(1,1,1,1));    // <0 frame_padding uses default frame padding settings. 0 for no padding
+    IMGUI_API bool          ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0),  const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1));    // <0 frame_padding uses default frame padding settings. 0 for no padding
     IMGUI_API bool          CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false);
     IMGUI_API bool          CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false);
     IMGUI_API bool          Checkbox(const char* label, bool* v);
     IMGUI_API bool          Checkbox(const char* label, bool* v);
     IMGUI_API bool          CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
     IMGUI_API bool          CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
@@ -300,8 +301,8 @@ namespace ImGui
     IMGUI_API void          SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0);          // set next tree node to be opened.
     IMGUI_API void          SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0);          // set next tree node to be opened.
 
 
     // Widgets: Selectable / Lists
     // Widgets: Selectable / Lists
-    IMGUI_API bool          Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0));
-    IMGUI_API bool          Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0));
+    IMGUI_API bool          Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0));  // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height 
+    IMGUI_API bool          Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0));
     IMGUI_API bool          ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
     IMGUI_API bool          ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
     IMGUI_API bool          ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
     IMGUI_API bool          ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
     IMGUI_API bool          ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards.
     IMGUI_API bool          ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards.
@@ -344,6 +345,7 @@ namespace ImGui
     IMGUI_API ImVec2        GetItemRectMin();                                                   // get bounding rect of last item in screen space
     IMGUI_API ImVec2        GetItemRectMin();                                                   // get bounding rect of last item in screen space
     IMGUI_API ImVec2        GetItemRectMax();                                                   // "
     IMGUI_API ImVec2        GetItemRectMax();                                                   // "
     IMGUI_API ImVec2        GetItemRectSize();                                                  // "
     IMGUI_API ImVec2        GetItemRectSize();                                                  // "
+    IMGUI_API bool          IsWindowHovered();
     IMGUI_API bool          IsWindowFocused();                                                  // is current window focused (differentiate child windows from each others)
     IMGUI_API bool          IsWindowFocused();                                                  // is current window focused (differentiate child windows from each others)
     IMGUI_API bool          IsRootWindowFocused();                                              // is current root window focused (top parent window in case of child windows)
     IMGUI_API bool          IsRootWindowFocused();                                              // is current root window focused (top parent window in case of child windows)
     IMGUI_API bool          IsRootWindowOrAnyChildFocused();                                    // is current root window or any of its child (including current window) focused
     IMGUI_API bool          IsRootWindowOrAnyChildFocused();                                    // is current root window or any of its child (including current window) focused
@@ -442,6 +444,14 @@ enum ImGuiInputTextFlags_
     ImGuiInputTextFlags_CallbackCharFilter  = 1 << 9    // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
     ImGuiInputTextFlags_CallbackCharFilter  = 1 << 9    // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
 };
 };
 
 
+// Flags for ImGui::Selectable()
+enum ImGuiSelectableFlags_
+{
+    // Default: 0
+    ImGuiSelectableFlags_DontClosePopups    = 1 << 0,   // Clicking this don't close parent popup window
+    ImGuiSelectableFlags_SpanAllColumns     = 1 << 1    // Selectable frame can span all columns (text will still fit in current column)
+};
+
 // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
 // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
 enum ImGuiKey_
 enum ImGuiKey_
 {
 {
@@ -1112,7 +1122,8 @@ struct ImFont
         signed short    XOffset, YOffset;
         signed short    XOffset, YOffset;
         float           U0, V0, U1, V1;     // Texture coordinates
         float           U0, V0, U1, V1;     // Texture coordinates
     };
     };
-    float               BaseLine;           // Distance from top to bottom of e.g. 'A' [0..FontSize]
+    float               Ascent;             // Distance from top to bottom of e.g. 'A' [0..FontSize]
+    float               Descent;            // 
     ImFontAtlas*        ContainerAtlas;     // What we has been loaded into
     ImFontAtlas*        ContainerAtlas;     // What we has been loaded into
     ImVector<Glyph>     Glyphs;
     ImVector<Glyph>     Glyphs;
     const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
     const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
@@ -1125,9 +1136,10 @@ struct ImFont
     IMGUI_API ~ImFont();
     IMGUI_API ~ImFont();
     IMGUI_API void              Clear();
     IMGUI_API void              Clear();
     IMGUI_API void              BuildLookupTable();
     IMGUI_API void              BuildLookupTable();
+    IMGUI_API float             GetCharAdvance(unsigned short c) const  { return ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] : FallbackXAdvance; }
     IMGUI_API const Glyph*      FindGlyph(unsigned short c) const;
     IMGUI_API const Glyph*      FindGlyph(unsigned short c) const;
     IMGUI_API void              SetFallbackChar(ImWchar c);
     IMGUI_API void              SetFallbackChar(ImWchar c);
-    IMGUI_API bool              IsLoaded() const        { return ContainerAtlas != NULL; }
+    IMGUI_API bool              IsLoaded() const                        { return ContainerAtlas != NULL; }
 
 
     // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
     // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
     // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
     // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.