|
|
@@ -3451,12 +3451,12 @@ void ImGui::UpdateMouseWheel()
|
|
|
return;
|
|
|
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
|
|
|
return;
|
|
|
- ImGuiWindow* window = g.HoveredWindow;
|
|
|
|
|
|
// Zoom / Scale window
|
|
|
// FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
|
|
|
- if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling && !window->Collapsed)
|
|
|
+ if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling && !g.HoveredWindow->Collapsed)
|
|
|
{
|
|
|
+ ImGuiWindow* window = g.HoveredWindow;
|
|
|
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
|
|
|
const float scale = new_font_scale / window->FontWindowScale;
|
|
|
window->FontWindowScale = new_font_scale;
|
|
|
@@ -3471,31 +3471,36 @@ void ImGui::UpdateMouseWheel()
|
|
|
}
|
|
|
|
|
|
// Mouse wheel scrolling
|
|
|
- // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
|
|
|
- while ((window->Flags & ImGuiWindowFlags_ChildWindow) && (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs) && window->ParentWindow)
|
|
|
- window = window->ParentWindow;
|
|
|
- const bool scroll_allowed = !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs);
|
|
|
- if (scroll_allowed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f) && !g.IO.KeyCtrl)
|
|
|
- {
|
|
|
- ImVec2 max_step = window->InnerRect.GetSize() * 0.67f;
|
|
|
+ // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent
|
|
|
+ // FIXME: Lock scrolling window while not moving (see #2604)
|
|
|
|
|
|
- // Vertical Mouse Wheel Scrolling (hold Shift to scroll horizontally)
|
|
|
- if (g.IO.MouseWheel != 0.0f && !g.IO.KeyShift)
|
|
|
- {
|
|
|
- float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step.y));
|
|
|
- SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * scroll_step);
|
|
|
- }
|
|
|
- else if (g.IO.MouseWheel != 0.0f && g.IO.KeyShift)
|
|
|
+ // Vertical Mouse Wheel scrolling
|
|
|
+ const float wheel_y = (g.IO.MouseWheel != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f;
|
|
|
+ if (wheel_y != 0.0f && !g.IO.KeyCtrl)
|
|
|
+ {
|
|
|
+ ImGuiWindow* window = g.HoveredWindow;
|
|
|
+ while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
|
|
|
+ window = window->ParentWindow;
|
|
|
+ if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
|
|
{
|
|
|
- float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step.x));
|
|
|
- SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheel * scroll_step);
|
|
|
+ float max_step = window->InnerRect.GetHeight() * 0.67f;
|
|
|
+ float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
|
|
|
+ SetWindowScrollY(window, window->Scroll.y - wheel_y * scroll_step);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // Horizontal Mouse Wheel Scrolling (for hardware that supports it)
|
|
|
- if (g.IO.MouseWheelH != 0.0f && !g.IO.KeyShift)
|
|
|
+ // Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held
|
|
|
+ const float wheel_x = (g.IO.MouseWheelH != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheelH : (g.IO.MouseWheel != 0.0f && g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f;
|
|
|
+ if (wheel_x != 0.0f && !g.IO.KeyCtrl)
|
|
|
+ {
|
|
|
+ ImGuiWindow* window = g.HoveredWindow;
|
|
|
+ while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
|
|
|
+ window = window->ParentWindow;
|
|
|
+ if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
|
|
{
|
|
|
- float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step.x));
|
|
|
- SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_step);
|
|
|
+ float max_step = window->InnerRect.GetWidth() * 0.67f;
|
|
|
+ float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
|
|
|
+ SetWindowScrollX(window, window->Scroll.x - wheel_x * scroll_step);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -4843,7 +4848,12 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool s
|
|
|
if (window->ScrollTarget.x < FLT_MAX)
|
|
|
{
|
|
|
float cr_x = window->ScrollTargetCenterRatio.x;
|
|
|
- scroll.x = window->ScrollTarget.x - cr_x * window->InnerRect.GetWidth();
|
|
|
+ float target_x = window->ScrollTarget.x;
|
|
|
+ if (snap_on_edges && cr_x <= 0.0f && target_x <= window->WindowPadding.x)
|
|
|
+ target_x = 0.0f;
|
|
|
+ else if (snap_on_edges && cr_x >= 1.0f && target_x >= window->ContentSize.x + window->WindowPadding.x + GImGui->Style.ItemSpacing.x)
|
|
|
+ target_x = window->ContentSize.x + window->WindowPadding.x * 2.0f;
|
|
|
+ scroll.x = target_x - cr_x * window->InnerRect.GetWidth();
|
|
|
}
|
|
|
if (window->ScrollTarget.y < FLT_MAX)
|
|
|
{
|
|
|
@@ -6854,6 +6864,15 @@ void ImGui::SetScrollY(float scroll_y)
|
|
|
window->ScrollTargetCenterRatio.y = 0.0f;
|
|
|
}
|
|
|
|
|
|
+void ImGui::SetScrollFromPosX(float local_x, float center_x_ratio)
|
|
|
+{
|
|
|
+ // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
|
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
|
+ IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
|
|
|
+ window->ScrollTarget.x = (float)(int)(local_x + window->Scroll.x);
|
|
|
+ window->ScrollTargetCenterRatio.x = center_x_ratio;
|
|
|
+}
|
|
|
+
|
|
|
void ImGui::SetScrollFromPosY(float local_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
|
|
|
@@ -6863,6 +6882,16 @@ void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
|
|
|
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
|
|
}
|
|
|
|
|
|
+// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
|
|
|
+void ImGui::SetScrollHereX(float center_x_ratio)
|
|
|
+{
|
|
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
|
+ float target_x = window->DC.LastItemRect.Min.x - window->Pos.x; // Left of last item, in window space
|
|
|
+ float last_item_width = window->DC.LastItemRect.GetWidth();
|
|
|
+ target_x += (last_item_width * center_x_ratio) + (GImGui->Style.ItemSpacing.x * (center_x_ratio - 0.5f) * 2.0f); // Precisely aim before, in the middle or after the last item.
|
|
|
+ SetScrollFromPosX(target_x, center_x_ratio);
|
|
|
+}
|
|
|
+
|
|
|
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
|
|
|
void ImGui::SetScrollHereY(float center_y_ratio)
|
|
|
{
|
|
|
@@ -9913,6 +9942,7 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {}
|
|
|
// [SECTION] METRICS/DEBUG WINDOW
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+#ifndef IMGUI_DISABLE_METRICS_WINDOW
|
|
|
void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
{
|
|
|
if (!ImGui::Begin("Dear ImGui Metrics", p_open))
|
|
|
@@ -9921,10 +9951,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- enum { RT_OuterRect, RT_OuterRectClipped, RT_InnerRect, RT_InnerClipRect, RT_WorkRect, RT_Contents, RT_ContentsRegionRect, RT_Count };
|
|
|
+ enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Contents, WRT_ContentsRegionRect, WRT_Count }; // Windows Rect Type
|
|
|
+ const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Contents", "ContentsRegionRect" };
|
|
|
+
|
|
|
static bool show_windows_begin_order = false;
|
|
|
static bool show_windows_rects = false;
|
|
|
- static int show_windows_rect_type = RT_WorkRect;
|
|
|
+ static int show_windows_rect_type = WRT_WorkRect;
|
|
|
static bool show_drawcmd_clip_rects = true;
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
@@ -9937,15 +9969,15 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
|
|
|
struct Funcs
|
|
|
{
|
|
|
- static ImRect GetRect(ImGuiWindow* window, int rect_type)
|
|
|
+ static ImRect GetWindowRect(ImGuiWindow* window, int rect_type)
|
|
|
{
|
|
|
- if (rect_type == RT_OuterRect) { return window->Rect(); }
|
|
|
- else if (rect_type == RT_OuterRectClipped) { return window->OuterRectClipped; }
|
|
|
- else if (rect_type == RT_InnerRect) { return window->InnerRect; }
|
|
|
- else if (rect_type == RT_InnerClipRect) { return window->InnerClipRect; }
|
|
|
- else if (rect_type == RT_WorkRect) { return window->WorkRect; }
|
|
|
- else if (rect_type == RT_Contents) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
|
|
|
- else if (rect_type == RT_ContentsRegionRect) { return window->ContentsRegionRect; }
|
|
|
+ if (rect_type == WRT_OuterRect) { return window->Rect(); }
|
|
|
+ else if (rect_type == WRT_OuterRectClipped) { return window->OuterRectClipped; }
|
|
|
+ else if (rect_type == WRT_InnerRect) { return window->InnerRect; }
|
|
|
+ else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; }
|
|
|
+ else if (rect_type == WRT_WorkRect) { return window->WorkRect; }
|
|
|
+ else if (rect_type == WRT_Contents) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
|
|
|
+ else if (rect_type == WRT_ContentsRegionRect) { return window->ContentsRegionRect; }
|
|
|
IM_ASSERT(0);
|
|
|
return ImRect();
|
|
|
}
|
|
|
@@ -10152,16 +10184,15 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
ImGui::Checkbox("Show windows rectangles", &show_windows_rects);
|
|
|
ImGui::SameLine();
|
|
|
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 12);
|
|
|
- const char* rects_names[RT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Contents", "ContentsRegionRect" };
|
|
|
- show_windows_rects |= ImGui::Combo("##rects_type", &show_windows_rect_type, rects_names, RT_Count);
|
|
|
+ show_windows_rects |= ImGui::Combo("##show_windows_rect_type", &show_windows_rect_type, wrt_rects_names, WRT_Count);
|
|
|
if (show_windows_rects && g.NavWindow)
|
|
|
{
|
|
|
ImGui::BulletText("'%s':", g.NavWindow->Name);
|
|
|
ImGui::Indent();
|
|
|
- for (int n = 0; n < RT_Count; n++)
|
|
|
+ for (int rect_n = 0; rect_n < WRT_Count; rect_n++)
|
|
|
{
|
|
|
- ImRect r = Funcs::GetRect(g.NavWindow, n);
|
|
|
- ImGui::Text("(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), rects_names[n]);
|
|
|
+ ImRect r = Funcs::GetWindowRect(g.NavWindow, rect_n);
|
|
|
+ ImGui::Text("(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), wrt_rects_names[rect_n]);
|
|
|
}
|
|
|
ImGui::Unindent();
|
|
|
}
|
|
|
@@ -10179,7 +10210,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
ImDrawList* draw_list = GetForegroundDrawList(window);
|
|
|
if (show_windows_rects)
|
|
|
{
|
|
|
- ImRect r = Funcs::GetRect(window, show_windows_rect_type);
|
|
|
+ ImRect r = Funcs::GetWindowRect(window, show_windows_rect_type);
|
|
|
draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255));
|
|
|
}
|
|
|
if (show_windows_begin_order && !(window->Flags & ImGuiWindowFlags_ChildWindow))
|
|
|
@@ -10194,6 +10225,11 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
}
|
|
|
ImGui::End();
|
|
|
}
|
|
|
+#else
|
|
|
+void ImGui::ShowMetricsWindow(bool*)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|