Browse Source

PushItemWidth() can take negative value to right-align items. Renamed GetItemWidth() to CalcItemWidth()

ocornut 10 years ago
parent
commit
1e9f6cce7f
2 changed files with 39 additions and 31 deletions
  1. 35 27
      imgui.cpp
  2. 4 4
      imgui.h

+ 35 - 27
imgui.cpp

@@ -129,6 +129,7 @@
  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/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior
  - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
  - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
  - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
  - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
  - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions.
  - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions.
@@ -880,11 +881,11 @@ struct ImGuiDrawContext
     bool                    LastItemHovered;
     bool                    LastItemHovered;
     ImVector<ImGuiWindow*>  ChildWindows;
     ImVector<ImGuiWindow*>  ChildWindows;
     ImVector<bool>          AllowKeyboardFocus;
     ImVector<bool>          AllowKeyboardFocus;
-    ImVector<float>         ItemWidth;
+    ImVector<float>         ItemWidth;           // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
     ImVector<float>         TextWrapPos;
     ImVector<float>         TextWrapPos;
     ImGuiColorEditMode      ColorEditMode;
     ImGuiColorEditMode      ColorEditMode;
     ImGuiStorage*           StateStorage;
     ImGuiStorage*           StateStorage;
-    int                     OpenNextNode;
+    int                     OpenNextNode;        // FIXME: Reformulate this feature like SetNextWindowCollapsed() API
 
 
     float                   ColumnsStartX;       // Start position from left of window (increased by TreePush/TreePop, etc.)
     float                   ColumnsStartX;       // Start position from left of window (increased by TreePush/TreePop, etc.)
     float                   ColumnsOffsetX;      // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
     float                   ColumnsOffsetX;      // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
@@ -3056,7 +3057,7 @@ void ImGui::PushItemWidth(float item_width)
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
     item_width = (float)(int)item_width;
     item_width = (float)(int)item_width;
-    window->DC.ItemWidth.push_back(item_width > 0.0f ? item_width : window->ItemWidthDefault);
+    window->DC.ItemWidth.push_back(item_width == 0.0f ? window->ItemWidthDefault : item_width);
 }
 }
 
 
 void ImGui::PopItemWidth()
 void ImGui::PopItemWidth()
@@ -3065,10 +3066,18 @@ void ImGui::PopItemWidth()
     window->DC.ItemWidth.pop_back();
     window->DC.ItemWidth.pop_back();
 }
 }
 
 
-float ImGui::GetItemWidth()
+float ImGui::CalcItemWidth()
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-    return window->DC.ItemWidth.back();
+    float w = window->DC.ItemWidth.back();
+    if (w < 0.0f)
+    {
+        // Align to a right-side limit
+        w = -w;
+        float width_to_right_edge = window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x;
+        w = ImMax(1.0f, width_to_right_edge - w);
+    }
+    return w;
 }
 }
 
 
 static void SetFont(ImFont* font)
 static void SetFont(ImFont* font)
@@ -3373,20 +3382,18 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
 ImVec2 ImGui::GetContentRegionMax()
 ImVec2 ImGui::GetContentRegionMax()
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-
-    ImVec2 m = window->Size - window->WindowPadding();
+    ImVec2 mx = window->Size - window->WindowPadding();
     if (window->DC.ColumnsCount != 1)
     if (window->DC.ColumnsCount != 1)
     {
     {
-        m.x = GetColumnOffset(window->DC.ColumnsCurrent + 1);
-        m.x -= GImGui->Style.WindowPadding.x;
+        mx.x = ImGui::GetColumnOffset(window->DC.ColumnsCurrent + 1);
+        mx.x -= GImGui->Style.WindowPadding.x;
     }
     }
     else
     else
     {
     {
         if (window->ScrollbarY)
         if (window->ScrollbarY)
-            m.x -= GImGui->Style.ScrollBarWidth;
+            mx.x -= GImGui->Style.ScrollBarWidth;
     }
     }
-
-    return m;
+    return mx;
 }
 }
 
 
 ImVec2 ImGui::GetWindowContentRegionMin()
 ImVec2 ImGui::GetWindowContentRegionMin()
@@ -3687,7 +3694,7 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
     if (window->SkipItems)
     if (window->SkipItems)
         return;
         return;
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
-    const float w = window->DC.ItemWidth.back();
+    const float w = ImGui::CalcItemWidth();
 
 
     static char buf[1024];
     static char buf[1024];
     const char* value_text_begin = &buf[0];
     const char* value_text_begin = &buf[0];
@@ -4348,7 +4355,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
 
 
     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 = window->DC.ItemWidth.back();
+    const float w = ImGui::CalcItemWidth();
 
 
     if (!display_format)
     if (!display_format)
         display_format = "%.3f";
         display_format = "%.3f";
@@ -4587,7 +4594,7 @@ static bool SliderFloatN(const char* label, float v[3], int components, float v_
         return false;
         return false;
 
 
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
-    const float w_full = window->DC.ItemWidth.back();
+    const float w_full = ImGui::CalcItemWidth();
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
 
 
@@ -4637,7 +4644,7 @@ static bool SliderIntN(const char* label, int v[3], int components, int v_min, i
         return false;
         return false;
 
 
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
-    const float w_full = window->DC.ItemWidth.back();
+    const float w_full = ImGui::CalcItemWidth();
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
 
 
@@ -4696,7 +4703,7 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett
 
 
     const ImVec2 text_size = ImGui::CalcTextSize(label, NULL, true);
     const ImVec2 text_size = ImGui::CalcTextSize(label, NULL, true);
     if (graph_size.x == 0.0f)
     if (graph_size.x == 0.0f)
-        graph_size.x = window->DC.ItemWidth.back();
+        graph_size.x = ImGui::CalcItemWidth();
     if (graph_size.y == 0.0f)
     if (graph_size.y == 0.0f)
         graph_size.y = text_size.y;
         graph_size.y = text_size.y;
 
 
@@ -5094,7 +5101,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast,
         return false;
         return false;
 
 
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
-    const float w = window->DC.ItemWidth.back();
+    const float w = ImGui::CalcItemWidth();
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
 
 
@@ -5226,7 +5233,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
     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 = window->DC.ItemWidth.back();
+    const float w = ImGui::CalcItemWidth();
 
 
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
@@ -5516,7 +5523,7 @@ static bool InputFloatN(const char* label, float* v, int components, int decimal
         return false;
         return false;
 
 
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
-    const float w_full = window->DC.ItemWidth.back();
+    const float w_full = ImGui::CalcItemWidth();
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
     const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
     const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
 
 
@@ -5617,7 +5624,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
 
 
     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 = window->DC.ItemWidth.back();
+    const float w = ImGui::CalcItemWidth();
 
 
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImVec2 text_size = CalcTextSize(label, NULL, true);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
     const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
@@ -5679,19 +5686,19 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
         combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY"));
         combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY"));
 
 
         // Display items
         // Display items
-        for (int item_idx = 0; item_idx < items_count; item_idx++)
+        for (int i = 0; i < items_count; i++)
         {
         {
-            ImGui::PushID((void*)(intptr_t)item_idx);
-            const bool item_selected = (item_idx == *current_item);
+            ImGui::PushID((void*)(intptr_t)i);
+            const bool item_selected = (i == *current_item);
             const char* item_text;
             const char* item_text;
-            if (!items_getter(data, item_idx, &item_text))
+            if (!items_getter(data, i, &item_text))
                 item_text = "*Unknown item*";
                 item_text = "*Unknown item*";
             if (ImGui::Selectable(item_text, item_selected))
             if (ImGui::Selectable(item_text, item_selected))
             {
             {
                 SetActiveId(0);
                 SetActiveId(0);
                 g.ActiveComboID = 0;
                 g.ActiveComboID = 0;
                 value_changed = true;
                 value_changed = true;
-                *current_item = item_idx;
+                *current_item = i;
             }
             }
             if (item_selected)
             if (item_selected)
             {
             {
@@ -5827,7 +5834,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 = window->DC.ItemWidth.back();
+    const float w_full = ImGui::CalcItemWidth();
     const float square_sz = (window->FontSize() + style.FramePadding.x * 2.0f);
     const float square_sz = (window->FontSize() + style.FramePadding.x * 2.0f);
 
 
     ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
     ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
@@ -6118,6 +6125,7 @@ void ImGui::NextColumn()
     }
     }
 }
 }
 
 
+// FIMXE-OPT: This is called too often. We need to cache offset for active columns set.
 float ImGui::GetColumnOffset(int column_index)
 float ImGui::GetColumnOffset(int column_index)
 {
 {
     ImGuiState& g = *GImGui;
     ImGuiState& g = *GImGui;

+ 4 - 4
imgui.h

@@ -162,8 +162,8 @@ namespace ImGui
     IMGUI_API void          BeginChild(ImGuiID id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);                                 // "
     IMGUI_API void          BeginChild(ImGuiID id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);                                 // "
     IMGUI_API void          EndChild();
     IMGUI_API void          EndChild();
     IMGUI_API bool          GetWindowIsFocused();
     IMGUI_API bool          GetWindowIsFocused();
-    IMGUI_API ImVec2        GetContentRegionMax();                                              // window or current column boundaries
-    IMGUI_API ImVec2        GetWindowContentRegionMin();                                        // window boundaries
+    IMGUI_API ImVec2        GetContentRegionMax();                                              // window or current column boundaries, in windows coordinates
+    IMGUI_API ImVec2        GetWindowContentRegionMin();                                        // window boundaries, in windows coordinates
     IMGUI_API ImVec2        GetWindowContentRegionMax();
     IMGUI_API ImVec2        GetWindowContentRegionMax();
     IMGUI_API ImDrawList*   GetWindowDrawList();                                                // get rendering command-list if you want to append your own draw primitives.
     IMGUI_API ImDrawList*   GetWindowDrawList();                                                // get rendering command-list if you want to append your own draw primitives.
     IMGUI_API ImFont*       GetWindowFont();
     IMGUI_API ImFont*       GetWindowFont();
@@ -195,9 +195,9 @@ namespace ImGui
     IMGUI_API void          PopStyleVar(int count = 1);
     IMGUI_API void          PopStyleVar(int count = 1);
 
 
     // Parameters stacks (current window)
     // Parameters stacks (current window)
-    IMGUI_API void          PushItemWidth(float item_width);                                    // width of items for the common item+label case. default to ~2/3 of windows width.
+    IMGUI_API void          PushItemWidth(float item_width);                                    // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window
     IMGUI_API void          PopItemWidth();
     IMGUI_API void          PopItemWidth();
-    IMGUI_API float         GetItemWidth();
+    IMGUI_API float         CalcItemWidth();                                                    // width of item given pushed settings and current cursor position
     IMGUI_API void          PushAllowKeyboardFocus(bool v);                                     // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
     IMGUI_API void          PushAllowKeyboardFocus(bool v);                                     // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
     IMGUI_API void          PopAllowKeyboardFocus();
     IMGUI_API void          PopAllowKeyboardFocus();
     IMGUI_API void          PushTextWrapPos(float wrap_pos_x = 0.0f);                           // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space.
     IMGUI_API void          PushTextWrapPos(float wrap_pos_x = 0.0f);                           // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space.