mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Refactor: Moved Scrollbar function from imgui.cpp to imgui_widgets.cpp, added file index (#2036)
This commit is contained in:
parent
728b2ef026
commit
df37a156e8
110
imgui.cpp
110
imgui.cpp
@ -5508,116 +5508,6 @@ void ImGui::End()
|
|||||||
SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
|
SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical scrollbar
|
|
||||||
// The entire piece of code below is rather confusing because:
|
|
||||||
// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
|
|
||||||
// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar
|
|
||||||
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
|
|
||||||
void ImGui::Scrollbar(ImGuiLayoutType direction)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
|
||||||
|
|
||||||
const bool horizontal = (direction == ImGuiLayoutType_Horizontal);
|
|
||||||
const ImGuiStyle& style = g.Style;
|
|
||||||
const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY");
|
|
||||||
|
|
||||||
// Render background
|
|
||||||
bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX);
|
|
||||||
float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f;
|
|
||||||
const ImRect window_rect = window->Rect();
|
|
||||||
const float border_size = window->WindowBorderSize;
|
|
||||||
ImRect bb = horizontal
|
|
||||||
? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size)
|
|
||||||
: ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size);
|
|
||||||
if (!horizontal)
|
|
||||||
bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f);
|
|
||||||
if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int window_rounding_corners;
|
|
||||||
if (horizontal)
|
|
||||||
window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight);
|
|
||||||
else
|
|
||||||
window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight);
|
|
||||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners);
|
|
||||||
bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
|
||||||
|
|
||||||
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
|
||||||
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
|
|
||||||
float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y;
|
|
||||||
float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w;
|
|
||||||
float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y;
|
|
||||||
|
|
||||||
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
|
||||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
|
||||||
IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
|
||||||
const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f);
|
|
||||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v);
|
|
||||||
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
|
|
||||||
|
|
||||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
|
||||||
bool held = false;
|
|
||||||
bool hovered = false;
|
|
||||||
const bool previously_held = (g.ActiveId == id);
|
|
||||||
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
|
||||||
|
|
||||||
float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v);
|
|
||||||
float scroll_ratio = ImSaturate(scroll_v / scroll_max);
|
|
||||||
float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
|
||||||
if (held && grab_h_norm < 1.0f)
|
|
||||||
{
|
|
||||||
float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y;
|
|
||||||
float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
|
|
||||||
float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y;
|
|
||||||
|
|
||||||
// Click position in scrollbar normalized space (0.0f->1.0f)
|
|
||||||
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
|
||||||
SetHoveredID(id);
|
|
||||||
|
|
||||||
bool seek_absolute = false;
|
|
||||||
if (!previously_held)
|
|
||||||
{
|
|
||||||
// On initial click calculate the distance between mouse and the center of the grab
|
|
||||||
if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm)
|
|
||||||
{
|
|
||||||
*click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
seek_absolute = true;
|
|
||||||
*click_delta_to_grab_center_v = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply scroll
|
|
||||||
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position
|
|
||||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm*0.5f) / (1.0f - grab_h_norm));
|
|
||||||
scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
|
|
||||||
if (horizontal)
|
|
||||||
window->Scroll.x = scroll_v;
|
|
||||||
else
|
|
||||||
window->Scroll.y = scroll_v;
|
|
||||||
|
|
||||||
// Update values for rendering
|
|
||||||
scroll_ratio = ImSaturate(scroll_v / scroll_max);
|
|
||||||
grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
|
||||||
|
|
||||||
// Update distance to grab now that we have seeked and saturated
|
|
||||||
if (seek_absolute)
|
|
||||||
*click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render
|
|
||||||
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
|
|
||||||
ImRect grab_rect;
|
|
||||||
if (horizontal)
|
|
||||||
grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y);
|
|
||||||
else
|
|
||||||
grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y));
|
|
||||||
window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::BringWindowToFront(ImGuiWindow* window)
|
void ImGui::BringWindowToFront(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// dear imgui, v1.64 WIP
|
// dear imgui, v1.64 WIP
|
||||||
// (drawing and font code)
|
// (drawing and font code)
|
||||||
|
|
||||||
// Contains implementation for
|
// Index of this file:
|
||||||
// - Default styles
|
// - Default styles
|
||||||
// - ImDrawList
|
// - ImDrawList
|
||||||
// - ImDrawData
|
// - ImDrawData
|
||||||
|
@ -1,6 +1,23 @@
|
|||||||
// dear imgui, v1.64 WIP
|
// dear imgui, v1.64 WIP
|
||||||
// (widgets code)
|
// (widgets code)
|
||||||
|
|
||||||
|
// Index of this file:
|
||||||
|
// - Widgets: Text, etc.
|
||||||
|
// - Widgets: Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc.
|
||||||
|
// - Widgets: ComboBox
|
||||||
|
// - Data Type and Data Formatting Helpers
|
||||||
|
// - Widgets: DragScalar, DragFloat, DragInt, etc.
|
||||||
|
// - Widgets: SliderScalar, SliderFloat, SliderInt, etc.
|
||||||
|
// - Widgets: InputScalar, InputFloat, InputInt, etc.
|
||||||
|
// - Widgets: InputText, InputTextMultiline
|
||||||
|
// - Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
||||||
|
// - Widgets: TreeNode, TreePush, TreePop, etc.
|
||||||
|
// - Widgets: Selectable
|
||||||
|
// - Widgets: ListBox
|
||||||
|
// - Widgets: PlotLines, PlotHistogram
|
||||||
|
// - Widgets: Value
|
||||||
|
// - Widgets: MenuItem, BeginMenu, EndMenu, etc.
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
@ -347,6 +364,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
|||||||
// - ArrowButton()
|
// - ArrowButton()
|
||||||
// - CloseButton() [Internal]
|
// - CloseButton() [Internal]
|
||||||
// - CollapseButton() [Internal]
|
// - CollapseButton() [Internal]
|
||||||
|
// - Scrollbar() [Internal]
|
||||||
// - Image()
|
// - Image()
|
||||||
// - ImageButton()
|
// - ImageButton()
|
||||||
// - Checkbox()
|
// - Checkbox()
|
||||||
@ -673,6 +691,116 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
|||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vertical/Horizontal scrollbar
|
||||||
|
// The entire piece of code below is rather confusing because:
|
||||||
|
// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
|
||||||
|
// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar
|
||||||
|
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
|
||||||
|
void ImGui::Scrollbar(ImGuiLayoutType direction)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
const bool horizontal = (direction == ImGuiLayoutType_Horizontal);
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY");
|
||||||
|
|
||||||
|
// Render background
|
||||||
|
bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX);
|
||||||
|
float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f;
|
||||||
|
const ImRect window_rect = window->Rect();
|
||||||
|
const float border_size = window->WindowBorderSize;
|
||||||
|
ImRect bb = horizontal
|
||||||
|
? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size)
|
||||||
|
: ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size);
|
||||||
|
if (!horizontal)
|
||||||
|
bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f);
|
||||||
|
if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int window_rounding_corners;
|
||||||
|
if (horizontal)
|
||||||
|
window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight);
|
||||||
|
else
|
||||||
|
window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight);
|
||||||
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners);
|
||||||
|
bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
||||||
|
|
||||||
|
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
||||||
|
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
|
||||||
|
float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y;
|
||||||
|
float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w;
|
||||||
|
float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y;
|
||||||
|
|
||||||
|
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
||||||
|
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||||
|
IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||||
|
const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f);
|
||||||
|
const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||||
|
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
|
||||||
|
|
||||||
|
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||||
|
bool held = false;
|
||||||
|
bool hovered = false;
|
||||||
|
const bool previously_held = (g.ActiveId == id);
|
||||||
|
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||||
|
|
||||||
|
float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v);
|
||||||
|
float scroll_ratio = ImSaturate(scroll_v / scroll_max);
|
||||||
|
float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
||||||
|
if (held && grab_h_norm < 1.0f)
|
||||||
|
{
|
||||||
|
float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y;
|
||||||
|
float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
|
||||||
|
float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y;
|
||||||
|
|
||||||
|
// Click position in scrollbar normalized space (0.0f->1.0f)
|
||||||
|
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
||||||
|
SetHoveredID(id);
|
||||||
|
|
||||||
|
bool seek_absolute = false;
|
||||||
|
if (!previously_held)
|
||||||
|
{
|
||||||
|
// On initial click calculate the distance between mouse and the center of the grab
|
||||||
|
if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm)
|
||||||
|
{
|
||||||
|
*click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
seek_absolute = true;
|
||||||
|
*click_delta_to_grab_center_v = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply scroll
|
||||||
|
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position
|
||||||
|
const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm*0.5f) / (1.0f - grab_h_norm));
|
||||||
|
scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
|
||||||
|
if (horizontal)
|
||||||
|
window->Scroll.x = scroll_v;
|
||||||
|
else
|
||||||
|
window->Scroll.y = scroll_v;
|
||||||
|
|
||||||
|
// Update values for rendering
|
||||||
|
scroll_ratio = ImSaturate(scroll_v / scroll_max);
|
||||||
|
grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
||||||
|
|
||||||
|
// Update distance to grab now that we have seeked and saturated
|
||||||
|
if (seek_absolute)
|
||||||
|
*click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render
|
||||||
|
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
|
||||||
|
ImRect grab_rect;
|
||||||
|
if (horizontal)
|
||||||
|
grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y);
|
||||||
|
else
|
||||||
|
grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y));
|
||||||
|
window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
Loading…
Reference in New Issue
Block a user