|
|
@@ -1078,7 +1078,9 @@ static int FindWindowFocusIndex(ImGuiWindow* window);
|
|
|
static void UpdateMouseInputs();
|
|
|
static void UpdateMouseWheel();
|
|
|
static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
|
|
-static void RenderOuterBorders(ImGuiWindow* window);
|
|
|
+static void RenderWindowOuterBorders(ImGuiWindow* window);
|
|
|
+static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
|
|
+static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -4928,7 +4930,7 @@ static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, cons
|
|
|
window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + size_for_clamping, rect.Min + padding) - size_for_clamping);
|
|
|
}
|
|
|
|
|
|
-static void ImGui::RenderOuterBorders(ImGuiWindow* window)
|
|
|
+static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
float rounding = window->WindowRounding;
|
|
|
@@ -4965,6 +4967,134 @@ static void ImGui::RenderOuterBorders(ImGuiWindow* window)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiStyle& style = g.Style;
|
|
|
+ ImGuiWindowFlags flags = window->Flags;
|
|
|
+
|
|
|
+ // Draw window + handle manual resize
|
|
|
+ // As we highlight the title bar when want_focus is set, multiple reappearing windows will have have their title bar highlighted on their reappearing frame.
|
|
|
+ const float window_rounding = window->WindowRounding;
|
|
|
+ const float window_border_size = window->WindowBorderSize;
|
|
|
+ if (window->Collapsed)
|
|
|
+ {
|
|
|
+ // Title bar only
|
|
|
+ float backup_border_size = style.FrameBorderSize;
|
|
|
+ g.Style.FrameBorderSize = window->WindowBorderSize;
|
|
|
+ ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
|
|
|
+ RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding);
|
|
|
+ g.Style.FrameBorderSize = backup_border_size;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Window background
|
|
|
+ if (!(flags & ImGuiWindowFlags_NoBackground))
|
|
|
+ {
|
|
|
+ ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags));
|
|
|
+ float alpha = 1.0f;
|
|
|
+ if (g.NextWindowData.BgAlphaCond != 0)
|
|
|
+ alpha = g.NextWindowData.BgAlphaVal;
|
|
|
+ if (alpha != 1.0f)
|
|
|
+ bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT);
|
|
|
+ window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot);
|
|
|
+ }
|
|
|
+ g.NextWindowData.BgAlphaCond = 0;
|
|
|
+
|
|
|
+ // Title bar
|
|
|
+ if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
|
|
+ {
|
|
|
+ ImU32 title_bar_col = GetColorU32(title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
|
|
|
+ window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Menu bar
|
|
|
+ if (flags & ImGuiWindowFlags_MenuBar)
|
|
|
+ {
|
|
|
+ ImRect menu_bar_rect = window->MenuBarRect();
|
|
|
+ menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
|
|
|
+ window->DrawList->AddRectFilled(menu_bar_rect.Min + ImVec2(window_border_size, 0), menu_bar_rect.Max - ImVec2(window_border_size, 0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top);
|
|
|
+ if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
|
|
|
+ window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Scrollbars
|
|
|
+ if (window->ScrollbarX)
|
|
|
+ Scrollbar(ImGuiAxis_X);
|
|
|
+ if (window->ScrollbarY)
|
|
|
+ Scrollbar(ImGuiAxis_Y);
|
|
|
+
|
|
|
+ // Render resize grips (after their input handling so we don't have a frame of latency)
|
|
|
+ if (!(flags & ImGuiWindowFlags_NoResize))
|
|
|
+ {
|
|
|
+ for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
|
|
|
+ {
|
|
|
+ const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
|
|
|
+ const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
|
|
|
+ window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size)));
|
|
|
+ window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size)));
|
|
|
+ window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12);
|
|
|
+ window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Borders
|
|
|
+ RenderWindowOuterBorders(window);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiStyle& style = g.Style;
|
|
|
+ ImGuiWindowFlags flags = window->Flags;
|
|
|
+
|
|
|
+ // Close & collapse button are on layer 1 (same as menus) and don't default focus
|
|
|
+ const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
|
|
+ window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus;
|
|
|
+ window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
|
|
|
+ window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
|
|
|
+
|
|
|
+ // Collapse button
|
|
|
+ if (!(flags & ImGuiWindowFlags_NoCollapse))
|
|
|
+ if (CollapseButton(window->GetID("#COLLAPSE"), window->Pos))
|
|
|
+ window->WantCollapseToggle = true; // Defer collapsing to next frame as we are too far in the Begin() function
|
|
|
+
|
|
|
+ // Close button
|
|
|
+ if (p_open != NULL)
|
|
|
+ {
|
|
|
+ const float rad = g.FontSize * 0.5f;
|
|
|
+ if (CloseButton(window->GetID("#CLOSE"), ImVec2(window->Pos.x + window->Size.x - style.FramePadding.x - rad, window->Pos.y + style.FramePadding.y + rad), rad + 1))
|
|
|
+ *p_open = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
|
|
+ window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
|
|
|
+ window->DC.ItemFlags = item_flags_backup;
|
|
|
+
|
|
|
+ // Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
|
|
|
+ // FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code..
|
|
|
+ const char* UNSAVED_DOCUMENT_MARKER = "*";
|
|
|
+ const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? CalcTextSize(UNSAVED_DOCUMENT_MARKER, NULL, false).x : 0.0f;
|
|
|
+ const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
|
|
|
+ ImRect text_r = title_bar_rect;
|
|
|
+ float pad_left = (flags & ImGuiWindowFlags_NoCollapse) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x);
|
|
|
+ float pad_right = (p_open == NULL) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x);
|
|
|
+ if (style.WindowTitleAlign.x > 0.0f)
|
|
|
+ pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x);
|
|
|
+ text_r.Min.x += pad_left;
|
|
|
+ text_r.Max.x -= pad_right;
|
|
|
+ ImRect clip_rect = text_r;
|
|
|
+ clip_rect.Max.x = window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x); // Match the size of CloseButton()
|
|
|
+ RenderTextClipped(text_r.Min, text_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect);
|
|
|
+ if (flags & ImGuiWindowFlags_UnsavedDocument)
|
|
|
+ {
|
|
|
+ ImVec2 marker_pos = ImVec2(ImMax(text_r.Min.x, text_r.Min.x + (text_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x) + text_size.x, text_r.Min.y) + ImVec2(2 - marker_size_x, 0.0f);
|
|
|
+ ImVec2 off = ImVec2(0.0f, (float)(int)(-g.FontSize * 0.25f));
|
|
|
+ RenderTextClipped(marker_pos + off, text_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_rect);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
|
|
|
{
|
|
|
window->ParentWindow = parent_window;
|
|
|
@@ -4980,7 +5110,7 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// Push a new ImGui window to add widgets to.
|
|
|
+// Push a new Dear ImGui window to add widgets to.
|
|
|
// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair.
|
|
|
// - Begin/End can be called multiple times during the frame with the same window name to append content.
|
|
|
// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file).
|
|
|
@@ -5298,7 +5428,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
int border_held = -1;
|
|
|
ImU32 resize_grip_col[4] = { 0 };
|
|
|
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // 4
|
|
|
- const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
|
|
|
+ const float resize_grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
|
|
|
if (!window->Collapsed)
|
|
|
UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]);
|
|
|
window->ResizeBorderHeld = (signed char)border_held;
|
|
|
@@ -5309,6 +5439,40 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
else
|
|
|
window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f);
|
|
|
|
|
|
+ // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars.
|
|
|
+ window->SizeFullAtLastBegin = window->SizeFull;
|
|
|
+
|
|
|
+ // UPDATE RECTANGLES
|
|
|
+
|
|
|
+ // Update various regions. Variables they depends on are set above in this function.
|
|
|
+ // FIXME: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
|
|
+ // NB: WindowBorderSize is included in WindowPadding _and_ ScrollbarSizes so we need to cancel one out.
|
|
|
+ window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
|
|
|
+ window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
|
|
|
+ window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x + ImMin(window->ScrollbarSizes.x, window->WindowBorderSize)));
|
|
|
+ window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y + ImMin(window->ScrollbarSizes.y, window->WindowBorderSize)));
|
|
|
+
|
|
|
+ // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
|
|
+ window->OuterRectClipped = window->Rect();
|
|
|
+ window->OuterRectClipped.ClipWith(window->ClipRect);
|
|
|
+
|
|
|
+ // Inner rectangle
|
|
|
+ // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
|
|
|
+ // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior.
|
|
|
+ const ImRect title_bar_rect = window->TitleBarRect();
|
|
|
+ window->InnerMainRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize;
|
|
|
+ window->InnerMainRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
|
|
|
+ window->InnerMainRect.Max.x = window->Pos.x + window->Size.x - ImMax(window->ScrollbarSizes.x, window->WindowBorderSize);
|
|
|
+ window->InnerMainRect.Max.y = window->Pos.y + window->Size.y - ImMax(window->ScrollbarSizes.y, window->WindowBorderSize);
|
|
|
+
|
|
|
+ // Inner clipping rectangle will extend a little bit outside the work region.
|
|
|
+ // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space.
|
|
|
+ // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
|
|
|
+ window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerMainRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
|
|
|
+ window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y);
|
|
|
+ window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
|
|
|
+ window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y);
|
|
|
+
|
|
|
// DRAWING
|
|
|
|
|
|
// Setup draw list and outer clipping rectangle
|
|
|
@@ -5338,77 +5502,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
|
|
|
}
|
|
|
|
|
|
- // Draw window + handle manual resize
|
|
|
- // As we highlight the title bar when want_focus is set, multiple reappearing windows will have have their title bar highlighted on their reappearing frame.
|
|
|
- const float window_rounding = window->WindowRounding;
|
|
|
- const float window_border_size = window->WindowBorderSize;
|
|
|
const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
|
|
|
const bool title_bar_is_highlight = want_focus || (window_to_highlight && window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight);
|
|
|
- const ImRect title_bar_rect = window->TitleBarRect();
|
|
|
- if (window->Collapsed)
|
|
|
- {
|
|
|
- // Title bar only
|
|
|
- float backup_border_size = style.FrameBorderSize;
|
|
|
- g.Style.FrameBorderSize = window->WindowBorderSize;
|
|
|
- ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
|
|
|
- RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding);
|
|
|
- g.Style.FrameBorderSize = backup_border_size;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // Window background
|
|
|
- if (!(flags & ImGuiWindowFlags_NoBackground))
|
|
|
- {
|
|
|
- ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags));
|
|
|
- float alpha = 1.0f;
|
|
|
- if (g.NextWindowData.BgAlphaCond != 0)
|
|
|
- alpha = g.NextWindowData.BgAlphaVal;
|
|
|
- if (alpha != 1.0f)
|
|
|
- bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT);
|
|
|
- window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot);
|
|
|
- }
|
|
|
- g.NextWindowData.BgAlphaCond = 0;
|
|
|
-
|
|
|
- // Title bar
|
|
|
- if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
|
|
- {
|
|
|
- ImU32 title_bar_col = GetColorU32(title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
|
|
|
- window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top);
|
|
|
- }
|
|
|
-
|
|
|
- // Menu bar
|
|
|
- if (flags & ImGuiWindowFlags_MenuBar)
|
|
|
- {
|
|
|
- ImRect menu_bar_rect = window->MenuBarRect();
|
|
|
- menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
|
|
|
- window->DrawList->AddRectFilled(menu_bar_rect.Min+ImVec2(window_border_size,0), menu_bar_rect.Max-ImVec2(window_border_size,0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top);
|
|
|
- if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
|
|
|
- window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
|
|
- }
|
|
|
-
|
|
|
- // Scrollbars
|
|
|
- if (window->ScrollbarX)
|
|
|
- Scrollbar(ImGuiAxis_X);
|
|
|
- if (window->ScrollbarY)
|
|
|
- Scrollbar(ImGuiAxis_Y);
|
|
|
-
|
|
|
- // Render resize grips (after their input handling so we don't have a frame of latency)
|
|
|
- if (!(flags & ImGuiWindowFlags_NoResize))
|
|
|
- {
|
|
|
- for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
|
|
|
- {
|
|
|
- const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
|
|
|
- const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
|
|
|
- window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size)));
|
|
|
- window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size)));
|
|
|
- window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12);
|
|
|
- window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Borders
|
|
|
- RenderOuterBorders(window);
|
|
|
- }
|
|
|
+ RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, resize_grip_count, resize_grip_col, resize_grip_draw_size);
|
|
|
|
|
|
// Draw navigation selection/windowing rectangle border
|
|
|
if (g.NavWindowingTargetAnim == window)
|
|
|
@@ -5424,37 +5520,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f);
|
|
|
}
|
|
|
|
|
|
- // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars.
|
|
|
- window->SizeFullAtLastBegin = window->SizeFull;
|
|
|
-
|
|
|
- // Update various regions. Variables they depends on are set above in this function.
|
|
|
- // FIXME: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
|
|
- // NB: WindowBorderSize is included in WindowPadding _and_ ScrollbarSizes so we need to cancel one out.
|
|
|
- window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
|
|
|
- window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
|
|
|
- window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x + ImMin(window->ScrollbarSizes.x, window->WindowBorderSize)));
|
|
|
- window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y + ImMin(window->ScrollbarSizes.y, window->WindowBorderSize)));
|
|
|
-
|
|
|
- // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
|
|
- window->OuterRectClipped = window->Rect();
|
|
|
- window->OuterRectClipped.ClipWith(window->ClipRect);
|
|
|
-
|
|
|
- // Inner rectangle
|
|
|
- // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
|
|
|
- // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior.
|
|
|
- window->InnerMainRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize;
|
|
|
- window->InnerMainRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
|
|
|
- window->InnerMainRect.Max.x = window->Pos.x + window->Size.x - ImMax(window->ScrollbarSizes.x, window->WindowBorderSize);
|
|
|
- window->InnerMainRect.Max.y = window->Pos.y + window->Size.y - ImMax(window->ScrollbarSizes.y, window->WindowBorderSize);
|
|
|
-
|
|
|
- // Inner clipping rectangle will extend a little bit outside the work region.
|
|
|
- // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space.
|
|
|
- // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
|
|
|
- window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerMainRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
|
|
|
- window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y);
|
|
|
- window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
|
|
|
- window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y);
|
|
|
-
|
|
|
// Setup drawing context
|
|
|
// (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.)
|
|
|
window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x;
|
|
|
@@ -5508,52 +5573,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
|
|
|
// Title bar
|
|
|
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
|
|
- {
|
|
|
- // Close & collapse button are on layer 1 (same as menus) and don't default focus
|
|
|
- const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
|
|
- window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus;
|
|
|
- window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
|
|
|
- window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
|
|
|
-
|
|
|
- // Collapse button
|
|
|
- if (!(flags & ImGuiWindowFlags_NoCollapse))
|
|
|
- if (CollapseButton(window->GetID("#COLLAPSE"), window->Pos))
|
|
|
- window->WantCollapseToggle = true; // Defer collapsing to next frame as we are too far in the Begin() function
|
|
|
-
|
|
|
- // Close button
|
|
|
- if (p_open != NULL)
|
|
|
- {
|
|
|
- const float rad = g.FontSize * 0.5f;
|
|
|
- if (CloseButton(window->GetID("#CLOSE"), ImVec2(window->Pos.x + window->Size.x - style.FramePadding.x - rad, window->Pos.y + style.FramePadding.y + rad), rad + 1))
|
|
|
- *p_open = false;
|
|
|
- }
|
|
|
-
|
|
|
- window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
|
|
- window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
|
|
|
- window->DC.ItemFlags = item_flags_backup;
|
|
|
-
|
|
|
- // Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
|
|
|
- // FIXME: Refactor text alignment facilities along with RenderText helpers, this is too much code..
|
|
|
- const char* UNSAVED_DOCUMENT_MARKER = "*";
|
|
|
- float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? CalcTextSize(UNSAVED_DOCUMENT_MARKER, NULL, false).x : 0.0f;
|
|
|
- ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
|
|
|
- ImRect text_r = title_bar_rect;
|
|
|
- float pad_left = (flags & ImGuiWindowFlags_NoCollapse) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x);
|
|
|
- float pad_right = (p_open == NULL) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x);
|
|
|
- if (style.WindowTitleAlign.x > 0.0f)
|
|
|
- pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x);
|
|
|
- text_r.Min.x += pad_left;
|
|
|
- text_r.Max.x -= pad_right;
|
|
|
- ImRect clip_rect = text_r;
|
|
|
- clip_rect.Max.x = window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x); // Match the size of CloseButton()
|
|
|
- RenderTextClipped(text_r.Min, text_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect);
|
|
|
- if (flags & ImGuiWindowFlags_UnsavedDocument)
|
|
|
- {
|
|
|
- ImVec2 marker_pos = ImVec2(ImMax(text_r.Min.x, text_r.Min.x + (text_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x) + text_size.x, text_r.Min.y) + ImVec2(2 - marker_size_x, 0.0f);
|
|
|
- ImVec2 off = ImVec2(0.0f, (float)(int)(-g.FontSize * 0.25f));
|
|
|
- RenderTextClipped(marker_pos + off, text_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_rect);
|
|
|
- }
|
|
|
- }
|
|
|
+ RenderWindowTitleBarContents(window, title_bar_rect, name, p_open);
|
|
|
|
|
|
// Pressing CTRL+C while holding on a window copy its content to the clipboard
|
|
|
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
|