Added GetScrollPosY(), GetScrollMaxY() (mentioned in #150)

docking
ocornut 10 years ago
parent a5daea9408
commit 2af8e0238c

@ -1122,7 +1122,8 @@ struct ImGuiWindow
ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Pos; // Position rounded-up to nearest pixel
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFull; // Size when non collapsed
ImVec2 SizeContentsFit; // Size of contents (extents reach by the drawing cursor) - may not fit within Size. ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame
ImVec2 SizeContentsCurrent; // Size of contents, currently extending
float ScrollY; float ScrollY;
float NextScrollY; float NextScrollY;
bool ScrollbarY; bool ScrollbarY;
@ -1464,7 +1465,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
Flags = 0; Flags = 0;
PosFloat = Pos = ImVec2(0.0f, 0.0f); PosFloat = Pos = ImVec2(0.0f, 0.0f);
Size = SizeFull = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f);
SizeContentsFit = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsCurrent = ImVec2(0.0f, 0.0f);
ScrollY = 0.0f; ScrollY = 0.0f;
NextScrollY = 0.0f; NextScrollY = 0.0f;
ScrollbarY = false; ScrollbarY = false;
@ -2802,6 +2803,10 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
window->LastFrameDrawn = current_frame; window->LastFrameDrawn = current_frame;
window->ClipRectStack.resize(0); window->ClipRectStack.resize(0);
// Reset contents size for auto-fitting
window->SizeContents = window->SizeContentsCurrent;
window->SizeContentsCurrent = ImVec2(0.0f, 0.0f);
if (flags & ImGuiWindowFlags_ChildWindow) if (flags & ImGuiWindowFlags_ChildWindow)
{ {
parent_window->DC.ChildWindows.push_back(window); parent_window->DC.ChildWindows.push_back(window);
@ -2896,7 +2901,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
window->ScrollY = window->NextScrollY; window->ScrollY = window->NextScrollY;
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, (float)window->SizeContentsFit.y - window->SizeFull.y)); window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, (float)window->SizeContents.y - window->SizeFull.y));
window->NextScrollY = window->ScrollY; window->NextScrollY = window->ScrollY;
// At this point we don't have a clipping rectangle setup yet, so we can test and draw in title bar // At this point we don't have a clipping rectangle setup yet, so we can test and draw in title bar
@ -2936,12 +2941,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
{ {
// Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose.
const ImVec2 size_auto_fit = window->SizeContentsFit + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); const ImVec2 size_auto_fit = window->SizeContents + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
window->SizeFull = size_auto_fit; window->SizeFull = size_auto_fit;
} }
else else
{ {
const ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding)); const ImVec2 size_auto_fit = ImClamp(window->SizeContents + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding));
if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
{ {
// Don't continuously mark settings as dirty, the size of the window doesn't need to be stored. // Don't continuously mark settings as dirty, the size of the window doesn't need to be stored.
@ -2989,7 +2994,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
} }
// Scrollbar // Scrollbar
window->ScrollbarY = (window->SizeContentsFit.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarY = (window->SizeContents.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar);
// Window background // Window background
if (bg_alpha > 0.0f) if (bg_alpha > 0.0f)
@ -3025,7 +3030,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
scrollbar_bb.Expand(ImVec2(-3,-3)); scrollbar_bb.Expand(ImVec2(-3,-3));
const float scrollbar_height = scrollbar_bb.GetHeight(); const float scrollbar_height = scrollbar_bb.GetHeight();
const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContentsFit.y, window->Size.y)); const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContents.y, window->Size.y));
const float grab_size_y_pixels = ImMax(style.GrabMinSize, scrollbar_height * grab_size_y_norm); const float grab_size_y_pixels = ImMax(style.GrabMinSize, scrollbar_height * grab_size_y_norm);
// Handle input right away (none of the code above is relying on scrolling position) // Handle input right away (none of the code above is relying on scrolling position)
@ -3039,13 +3044,13 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
{ {
g.HoveredId = scrollbar_id; g.HoveredId = scrollbar_id;
const float pos_y_norm = ImSaturate((g.IO.MousePos.y - (scrollbar_bb.Min.y + grab_size_y_pixels*0.5f)) / (scrollbar_height - grab_size_y_pixels)); const float pos_y_norm = ImSaturate((g.IO.MousePos.y - (scrollbar_bb.Min.y + grab_size_y_pixels*0.5f)) / (scrollbar_height - grab_size_y_pixels));
window->ScrollY = (float)(int)(pos_y_norm * (window->SizeContentsFit.y - window->Size.y)); window->ScrollY = (float)(int)(pos_y_norm * (window->SizeContents.y - window->Size.y));
window->NextScrollY = window->ScrollY; window->NextScrollY = window->ScrollY;
} }
} }
// Normalized height of the grab // Normalized height of the grab
const float pos_y_norm = ImSaturate(window->ScrollY / ImMax(0.0f, window->SizeContentsFit.y - window->Size.y)); const float pos_y_norm = ImSaturate(window->ScrollY / ImMax(0.0f, window->SizeContents.y - window->Size.y));
const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
window->DrawList->AddRectFilled( window->DrawList->AddRectFilled(
ImVec2(scrollbar_bb.Min.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y - grab_size_y_pixels, pos_y_norm)), ImVec2(scrollbar_bb.Min.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y - grab_size_y_pixels, pos_y_norm)),
@ -3095,8 +3100,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg
window->DC.TreeDepth = 0; window->DC.TreeDepth = 0;
window->DC.StateStorage = &window->StateStorage; window->DC.StateStorage = &window->StateStorage;
// Reset contents size for auto-fitting
window->SizeContentsFit = ImVec2(0.0f, 0.0f);
if (window->AutoFitFrames > 0) if (window->AutoFitFrames > 0)
window->AutoFitFrames--; window->AutoFitFrames--;
@ -3677,21 +3680,21 @@ void ImGui::SetCursorPos(const ImVec2& pos)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->DC.CursorPos = window->Pos + pos; window->DC.CursorPos = window->Pos + pos;
window->SizeContentsFit = ImMax(window->SizeContentsFit, pos + ImVec2(0.0f, window->ScrollY)); window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, pos + ImVec2(0.0f, window->ScrollY));
} }
void ImGui::SetCursorPosX(float x) void ImGui::SetCursorPosX(float x)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->DC.CursorPos.x = window->Pos.x + x; window->DC.CursorPos.x = window->Pos.x + x;
window->SizeContentsFit.x = ImMax(window->SizeContentsFit.x, x); window->SizeContentsCurrent.x = ImMax(window->SizeContentsCurrent.x, x);
} }
void ImGui::SetCursorPosY(float y) void ImGui::SetCursorPosY(float y)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->DC.CursorPos.y = window->Pos.y + y; window->DC.CursorPos.y = window->Pos.y + y;
window->SizeContentsFit.y = ImMax(window->SizeContentsFit.y, y + window->ScrollY); window->SizeContentsCurrent.y = ImMax(window->SizeContentsCurrent.y, y + window->ScrollY);
} }
ImVec2 ImGui::GetCursorScreenPos() ImVec2 ImGui::GetCursorScreenPos()
@ -3706,6 +3709,18 @@ void ImGui::SetCursorScreenPos(const ImVec2& screen_pos)
window->DC.CursorPos = screen_pos; window->DC.CursorPos = screen_pos;
} }
float ImGui::GetScrollPosY()
{
ImGuiWindow* window = GetCurrentWindow();
return window->ScrollY;
}
float ImGui::GetScrollMaxY()
{
ImGuiWindow* window = GetCurrentWindow();
return window->SizeContents.y - window->SizeFull.y;
}
void ImGui::SetScrollPosHere() void ImGui::SetScrollPosHere()
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -6413,7 +6428,7 @@ static void ItemSize(ImVec2 size, ImVec2* adjust_vertical_offset)
window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
window->SizeContentsFit = ImMax(window->SizeContentsFit, ImVec2(window->DC.CursorPosPrevLine.x - window->Pos.x, window->DC.CursorPos.y + window->ScrollY - window->Pos.y)); window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, ImVec2(window->DC.CursorPosPrevLine.x - window->Pos.x, window->DC.CursorPos.y + window->ScrollY - window->Pos.y));
window->DC.PrevLineHeight = line_height; window->DC.PrevLineHeight = line_height;
window->DC.CurrentLineHeight = 0.0f; window->DC.CurrentLineHeight = 0.0f;

@ -190,6 +190,8 @@ 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 IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most
IMGUI_API float GetScrollPosY(); // get scrolling position (0..GetScrollMaxY())
IMGUI_API float GetScrollMaxY(); // get maximum scrolling position == ContentSize.Y - WindowSize.Y
IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position. IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
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).

Loading…
Cancel
Save