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

This commit is contained in:
ocornut 2015-07-02 20:53:45 -06:00
parent b54cb1c24c
commit 4eba6cd470
2 changed files with 43 additions and 24 deletions

View File

@ -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 = GImGui->CurrentWindow;
ImGuiWindow* window = g.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); IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
window->ScrollTargetRelY += g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.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();

View File

@ -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 GetScrollY(); // get scrolling amount [0..GetScrollMaxY()]
IMGUI_API float GetScrollMaxY(); // get maximum scrolling position == ContentSize.Y - WindowSize.Y IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount == 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 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