Browse Source

Added SetScrollY(), SetScrollFromPosY(). Renamed SetScrollPosHere() to SetScrollFromCursorPos(). (#150)

ocornut 10 years ago
parent
commit
4eba6cd470
2 changed files with 43 additions and 24 deletions
  1. 37 21
      imgui.cpp
  2. 6 3
      imgui.h

+ 37 - 21
imgui.cpp

@@ -136,7 +136,8 @@
  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/07/01 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount.
+ - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete).
+ - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount.
  - 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 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/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 GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
@@ -339,7 +340,6 @@
  - window: resizing from any sides? + mouse cursor directives for app.
  - window: resizing from any sides? + mouse cursor directives for app.
  - window: get size/pos helpers given names (see discussion in #249)
  - window: get size/pos helpers given names (see discussion in #249)
  - scrolling: add horizontal scroll
  - scrolling: add horizontal scroll
-!- scrolling: set scrolling given a position.
 !- scrolling: allow immediately effective change of scroll if we haven't appended items yet
 !- 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.
@@ -1419,7 +1419,7 @@ struct ImGuiWindow
     ImVec2                  WindowPadding;                      // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect
     ImVec2                  WindowPadding;                      // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect
     ImGuiID                 MoveID;                             // == window->GetID("#MOVE")
     ImGuiID                 MoveID;                             // == window->GetID("#MOVE")
     float                   ScrollY;
     float                   ScrollY;
-    float                   ScrollTargetRelY;                   // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (-1.0f for no change)
+    float                   ScrollTargetRelY;                   // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
     float                   ScrollTargetCenterRatioY;           // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
     float                   ScrollTargetCenterRatioY;           // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
     bool                    ScrollbarY;
     bool                    ScrollbarY;
     bool                    Active;                             // Set to true on Begin()
     bool                    Active;                             // Set to true on Begin()
@@ -1786,7 +1786,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
     SizeContents = ImVec2(0.0f, 0.0f);
     SizeContents = ImVec2(0.0f, 0.0f);
     WindowPadding = ImVec2(0.0f, 0.0f);
     WindowPadding = ImVec2(0.0f, 0.0f);
     ScrollY = 0.0f;
     ScrollY = 0.0f;
-    ScrollTargetRelY = -1.0f;
+    ScrollTargetRelY = FLT_MAX;
     ScrollTargetCenterRatioY = 0.5f;
     ScrollTargetCenterRatioY = 0.5f;
     ScrollbarY = false;
     ScrollbarY = false;
     Active = WasActive = false;
     Active = WasActive = false;
@@ -3858,11 +3858,11 @@ 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
-        if (window->ScrollTargetRelY >= 0.0f)
+        if (window->ScrollTargetRelY < FLT_MAX)
         {
         {
             float center_ratio_y = window->ScrollTargetCenterRatioY;
             float center_ratio_y = window->ScrollTargetCenterRatioY;
             window->ScrollY = window->ScrollTargetRelY - ((1.0f - center_ratio_y) * window->TitleBarHeight()) - (center_ratio_y * window->SizeFull.y);
             window->ScrollY = window->ScrollTargetRelY - ((1.0f - center_ratio_y) * window->TitleBarHeight()) - (center_ratio_y * window->SizeFull.y);
-            window->ScrollTargetRelY = -1.0f;
+            window->ScrollTargetRelY = FLT_MAX;
         }
         }
         window->ScrollY = ImMax(window->ScrollY, 0.0f);
         window->ScrollY = ImMax(window->ScrollY, 0.0f);
         if (!window->Collapsed && !window->SkipItems)
         if (!window->Collapsed && !window->SkipItems)
@@ -4505,8 +4505,7 @@ bool ImGui::IsRootWindowOrAnyChildFocused()
 
 
 float ImGui::GetWindowWidth()
 float ImGui::GetWindowWidth()
 {
 {
-    ImGuiState& g = *GImGui;
-    ImGuiWindow* window = g.CurrentWindow;
+    ImGuiWindow* window = GImGui->CurrentWindow;
     return window->Size.x;
     return window->Size.x;
 }
 }
 
 
@@ -4828,19 +4827,31 @@ float ImGui::GetScrollMaxY()
     return window->SizeContents.y - window->SizeFull.y;
     return window->SizeContents.y - window->SizeFull.y;
 }
 }
 
 
-void ImGui::SetScrollPosHere(float center_y_ratio)
+void ImGui::SetScrollY(float scroll_y)
+{
+    ImGuiWindow* window = GetCurrentWindow();
+    window->ScrollTargetRelY = scroll_y + window->TitleBarHeight(); // title bar height cancelled out when using ScrollTargetRelY
+    window->ScrollTargetCenterRatioY = 0.0f;
+}
+
+void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio)
 {
 {
     // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
     // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
-    ImGuiState& g = *GImGui;
-    IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-    window->ScrollTargetRelY = (float)(int)(window->ScrollY + window->DC.CursorPosPrevLine.y - window->Pos.y + (window->DC.PrevLineHeight) * center_y_ratio);
-    window->ScrollTargetRelY += g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f;
+    IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
+    window->ScrollTargetRelY = (float)(int)(pos_y + window->ScrollY);
     if (center_y_ratio <= 0.0f && window->ScrollTargetRelY <= window->WindowPadding.y)    // Minor hack to make "scroll to top" take account of WindowPadding, else it would scroll to (WindowPadding.y - ItemSpacing.y)
     if (center_y_ratio <= 0.0f && window->ScrollTargetRelY <= window->WindowPadding.y)    // Minor hack to make "scroll to top" take account of WindowPadding, else it would scroll to (WindowPadding.y - ItemSpacing.y)
         window->ScrollTargetRelY = 0.0f;
         window->ScrollTargetRelY = 0.0f;
     window->ScrollTargetCenterRatioY = center_y_ratio;
     window->ScrollTargetCenterRatioY = center_y_ratio;
 }
 }
 
 
+void ImGui::SetScrollFromCursorPos(float center_y_ratio)
+{
+    ImGuiWindow* window = GetCurrentWindow();
+    float target_y = window->DC.CursorPosPrevLine.y + (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
+    ImGui::SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio);
+}
+
 void ImGui::SetKeyboardFocusHere(int offset)
 void ImGui::SetKeyboardFocusHere(int offset)
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
@@ -7751,7 +7762,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
                     *current_item = i;
                     *current_item = i;
                 }
                 }
                 if (item_selected && menu_toggled)
                 if (item_selected && menu_toggled)
-                    ImGui::SetScrollPosHere();
+                    ImGui::SetScrollFromCursorPos();
                 ImGui::PopID();
                 ImGui::PopID();
             }
             }
             ImGui::EndPopup();
             ImGui::EndPopup();
@@ -11300,10 +11311,10 @@ void ImGui::ShowTestWindow(bool* opened)
             {
             {
                 ImGui::Text("%04d: scrollable region", i);
                 ImGui::Text("%04d: scrollable region", i);
                 if (goto_line && line == i)
                 if (goto_line && line == i)
-                    ImGui::SetScrollPosHere();
+                    ImGui::SetScrollFromCursorPos();
             }
             }
             if (goto_line && line >= 100)
             if (goto_line && line >= 100)
-                ImGui::SetScrollPosHere();
+                ImGui::SetScrollFromCursorPos();
             ImGui::EndChild();
             ImGui::EndChild();
 
 
             ImGui::SameLine();
             ImGui::SameLine();
@@ -11497,11 +11508,14 @@ void ImGui::ShowTestWindow(bool* opened)
 
 
         if (ImGui::TreeNode("Scrolling"))
         if (ImGui::TreeNode("Scrolling"))
         {
         {
-            ImGui::TextWrapped("Use SetScrollPosHere() to scroll to a given position.");
+            ImGui::TextWrapped("Use SetScrollFromPos() or SetScrollFromCursorPos() to scroll to a given position.");
             static bool track = true;
             static bool track = true;
-            static int track_line = 50;
+            static int track_line = 50, scroll_to_px = 200;
             ImGui::Checkbox("Track", &track);
             ImGui::Checkbox("Track", &track);
-            ImGui::SameLine(); ImGui::SliderInt("##line", &track_line, 0, 99, "Line %.0f");
+            ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 9999, "Line %.0f");
+            bool scroll_to = ImGui::Button("Scroll To");
+            ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px");
+            if (scroll_to) track = false;
 
 
             for (int i = 0; i < 3; i++)
             for (int i = 0; i < 3; i++)
             {
             {
@@ -11509,11 +11523,13 @@ void ImGui::ShowTestWindow(bool* opened)
                 ImGui::BeginGroup();
                 ImGui::BeginGroup();
                 ImGui::Text(i == 0 ? "Top" : i == 1 ? "Center" : "Bottom");
                 ImGui::Text(i == 0 ? "Top" : i == 1 ? "Center" : "Bottom");
                 ImGui::BeginChild(ImGui::GetID((void *)i), ImVec2(ImGui::GetWindowWidth() * 0.25f, 200.0f), true);
                 ImGui::BeginChild(ImGui::GetID((void *)i), ImVec2(ImGui::GetWindowWidth() * 0.25f, 200.0f), true);
+                if (scroll_to)
+                    ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.50f);
                 for (int line = 0; line < 100; line++)
                 for (int line = 0; line < 100; line++)
                 {
                 {
                     ImGui::Text("Line %d", line);
                     ImGui::Text("Line %d", line);
                     if (track && line == track_line)
                     if (track && line == track_line)
-                        ImGui::SetScrollPosHere(i * 0.50f); // 0.0f,0.5f,1.0f
+                        ImGui::SetScrollFromCursorPos(i * 0.50f); // 0.0f:top, 0.5f:center, 1.0f:bottom
                 }
                 }
                 ImGui::EndChild();
                 ImGui::EndChild();
                 ImGui::EndGroup();
                 ImGui::EndGroup();
@@ -12272,7 +12288,7 @@ struct ExampleAppConsole
             ImGui::PopStyleColor();
             ImGui::PopStyleColor();
         }
         }
         if (ScrollToBottom)
         if (ScrollToBottom)
-            ImGui::SetScrollPosHere();
+            ImGui::SetScrollFromCursorPos();
         ScrollToBottom = false;
         ScrollToBottom = false;
         ImGui::PopStyleVar();
         ImGui::PopStyleVar();
         ImGui::EndChild();
         ImGui::EndChild();

+ 6 - 3
imgui.h

@@ -135,9 +135,11 @@ namespace ImGui
     IMGUI_API void          SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0);   // set named window collapsed state
     IMGUI_API void          SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0);   // set named window collapsed state
     IMGUI_API void          SetWindowFocus(const char* name);                                              // set named window to be focused / front-most. use NULL to remove focus.
     IMGUI_API void          SetWindowFocus(const char* name);                                              // set named window to be focused / front-most. use NULL to remove focus.
 
 
-    IMGUI_API float         GetScrollY();                                                       // get scrolling position [0..GetScrollMaxY()]
-    IMGUI_API float         GetScrollMaxY();                                                    // get maximum scrolling position == ContentSize.Y - WindowSize.Y
-    IMGUI_API void          SetScrollPosHere(float center_y_ratio = 0.5f);                      // adjust scrolling position to make the current cursor position visible. center_y_ratio=0.0: top, =0.5: center, =1.0: bottom.
+    IMGUI_API float         GetScrollY();                                                       // get scrolling amount [0..GetScrollMaxY()]
+    IMGUI_API float         GetScrollMaxY();                                                    // get maximum scrolling amount == ContentSize.Y - WindowSize.Y
+    IMGUI_API void          SetScrollY(float scroll_y);                                         // set scrolling amount [0..GetScrollMaxY()]
+    IMGUI_API void          SetScrollFromCursorPos(float center_y_ratio = 0.5f);                // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom.
+    IMGUI_API void          SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f);        // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions.
     IMGUI_API void          SetKeyboardFocusHere(int offset = 0);                               // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget
     IMGUI_API void          SetKeyboardFocusHere(int offset = 0);                               // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget
     IMGUI_API void          SetStateStorage(ImGuiStorage* tree);                                // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
     IMGUI_API void          SetStateStorage(ImGuiStorage* tree);                                // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
     IMGUI_API ImGuiStorage* GetStateStorage();
     IMGUI_API ImGuiStorage* GetStateStorage();
@@ -409,6 +411,7 @@ namespace ImGui
     static inline bool      IsClipped(const ImVec2& size) { return !IsRectVisible(size); }     // OBSOLETE 1.38+
     static inline bool      IsClipped(const ImVec2& size) { return !IsRectVisible(size); }     // OBSOLETE 1.38+
     static inline bool      IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+
     static inline bool      IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+
     static inline bool      IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); }  // OBSOLETE 1.36+
     static inline bool      IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); }  // OBSOLETE 1.36+
+    static inline void      SetScrollPosHere() { SetScrollFromCursorPos(); }                   // OBSOLETE 1.42+
 #endif
 #endif
 
 
 } // namespace ImGui
 } // namespace ImGui