diff --git a/engine/include/XCEngine/UI/Layout/UITabStripLayout.h b/engine/include/XCEngine/UI/Layout/UITabStripLayout.h index 199e6a5b..f10602cf 100644 --- a/engine/include/XCEngine/UI/Layout/UITabStripLayout.h +++ b/engine/include/XCEngine/UI/Layout/UITabStripLayout.h @@ -106,20 +106,43 @@ inline UITabStripLayoutResult ArrangeUITabStrip( const float gap = (std::max)(0.0f, metrics.tabGap); const float totalGapWidth = gap * static_cast(desiredHeaderWidths.size() - 1u); const float availableTabsWidth = (std::max)(0.0f, bounds.width - totalGapWidth); + const float minTabWidth = (std::max)(0.0f, metrics.tabMinWidth); + + std::vector resolvedHeaderWidths = {}; + resolvedHeaderWidths.reserve(desiredHeaderWidths.size()); float totalDesiredWidth = 0.0f; + float totalMinimumWidth = 0.0f; for (float width : desiredHeaderWidths) { - totalDesiredWidth += (std::max)(0.0f, width); + const float desiredWidth = (std::max)((std::max)(0.0f, width), minTabWidth); + resolvedHeaderWidths.push_back(desiredWidth); + totalDesiredWidth += desiredWidth; + totalMinimumWidth += minTabWidth; } - const float scale = totalDesiredWidth > 0.0f && totalDesiredWidth > availableTabsWidth - ? availableTabsWidth / totalDesiredWidth - : 1.0f; + if (totalDesiredWidth > availableTabsWidth && totalDesiredWidth > 0.0f) { + if (totalMinimumWidth > 0.0f && totalMinimumWidth >= availableTabsWidth) { + const float minWidthScale = availableTabsWidth / totalMinimumWidth; + for (float& width : resolvedHeaderWidths) { + width = minTabWidth * minWidthScale; + } + } else { + const float totalShrinkableWidth = totalDesiredWidth - totalMinimumWidth; + const float overflowWidth = totalDesiredWidth - availableTabsWidth; + const float excessScale = totalShrinkableWidth > 0.0f + ? ((std::max)(totalShrinkableWidth - overflowWidth, 0.0f) / totalShrinkableWidth) + : 0.0f; + for (float& width : resolvedHeaderWidths) { + const float shrinkableWidth = (std::max)(width - minTabWidth, 0.0f); + width = minTabWidth + shrinkableWidth * excessScale; + } + } + } float cursorX = bounds.x; for (std::size_t index = 0; index < desiredHeaderWidths.size(); ++index) { const float width = totalDesiredWidth > 0.0f - ? (std::max)(0.0f, desiredHeaderWidths[index]) * scale + ? resolvedHeaderWidths[index] : availableTabsWidth / static_cast(desiredHeaderWidths.size()); result.tabHeaderRects[index] = UIRect(cursorX, bounds.y, width, headerHeight); cursorX += width + gap; diff --git a/new_editor/app/Platform/Win32/EditorWindowChromeController.cpp b/new_editor/app/Platform/Win32/EditorWindowChromeController.cpp index 97211569..d78c911b 100644 --- a/new_editor/app/Platform/Win32/EditorWindowChromeController.cpp +++ b/new_editor/app/Platform/Win32/EditorWindowChromeController.cpp @@ -112,13 +112,18 @@ bool IsToolWindow(const EditorWindow& window) { return ::XCEngine::UI::UISize(640.0f, 360.0f); } -float ResolveDetachedTabWidth(std::string_view text) { +float ResolveDetachedTabWidth( + std::string_view text, + const UIEditorTextMeasurer* textMeasurer) { const Widgets::UIEditorTabStripMetrics& metrics = ResolveUIEditorTabStripMetrics(); Widgets::UIEditorTabStripItem item = {}; item.title = std::string(text); - const float desiredLabelWidth = - Widgets::ResolveUIEditorTabStripDesiredHeaderLabelWidth(item, metrics); - return MeasureUITabStripHeaderWidth(desiredLabelWidth, metrics.layoutMetrics); + const float measuredLabelWidth = + Widgets::ResolveUIEditorTabStripMeasuredLabelWidth( + item, + metrics, + textMeasurer); + return MeasureUITabStripHeaderWidth(measuredLabelWidth, metrics.layoutMetrics); } bool HasSingleVisibleRootTab(const UIEditorWorkspaceController& controller) { @@ -710,7 +715,9 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa float clientWidthDips) const { float leadingOccupiedRight = 0.0f; if (ShouldUseDetachedTitleBarTabStrip(window)) { - leadingOccupiedRight = ResolveDetachedTabWidth(ResolveDetachedTitleTabText(window)); + leadingOccupiedRight = ResolveDetachedTabWidth( + ResolveDetachedTitleTabText(window), + &window.m_runtime->GetTextMeasurer()); } return Host::BuildBorderlessWindowChromeLayout( diff --git a/new_editor/include/XCEditor/Collections/UIEditorTabStrip.h b/new_editor/include/XCEditor/Collections/UIEditorTabStrip.h index a6d5efb2..8d642fa2 100644 --- a/new_editor/include/XCEditor/Collections/UIEditorTabStrip.h +++ b/new_editor/include/XCEditor/Collections/UIEditorTabStrip.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include @@ -18,7 +20,8 @@ inline constexpr std::size_t UIEditorTabStripInvalidIndex = struct UIEditorTabStripItem { std::string tabId = {}; std::string title = {}; - float desiredHeaderLabelWidth = 0.0f; + // Pure glyph advance for the rendered title. Header padding is added by layout. + float measuredLabelWidth = 0.0f; }; struct UIEditorTabStripState { @@ -85,9 +88,10 @@ struct UIEditorTabStripHitTarget { std::size_t index = UIEditorTabStripInvalidIndex; }; -float ResolveUIEditorTabStripDesiredHeaderLabelWidth( +float ResolveUIEditorTabStripMeasuredLabelWidth( const UIEditorTabStripItem& item, - const UIEditorTabStripMetrics& metrics = {}); + const UIEditorTabStripMetrics& metrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); std::size_t ResolveUIEditorTabStripSelectedIndex( const std::vector& items, diff --git a/new_editor/include/XCEditor/Docking/UIEditorDockHost.h b/new_editor/include/XCEditor/Docking/UIEditorDockHost.h index c16663a7..d74f1e16 100644 --- a/new_editor/include/XCEditor/Docking/UIEditorDockHost.h +++ b/new_editor/include/XCEditor/Docking/UIEditorDockHost.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -93,6 +94,8 @@ struct UIEditorDockHostPalette { struct UIEditorDockHostTabItemLayout { std::string panelId = {}; std::string title = {}; + // Cached title measurement used consistently by layout, hit testing and rendering. + float measuredLabelWidth = 0.0f; bool active = false; }; @@ -161,7 +164,8 @@ UIEditorDockHostLayout BuildUIEditorDockHostLayout( const UIEditorWorkspaceModel& workspace, const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state = {}, - const UIEditorDockHostMetrics& metrics = {}); + const UIEditorDockHostMetrics& metrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); UIEditorDockHostHitTarget HitTestUIEditorDockHost( const UIEditorDockHostLayout& layout, @@ -201,7 +205,8 @@ void AppendUIEditorDockHost( const UIEditorDockHostState& state = {}, const UIEditorDockHostForegroundOptions& foregroundOptions = {}, const UIEditorDockHostPalette& palette = {}, - const UIEditorDockHostMetrics& metrics = {}); + const UIEditorDockHostMetrics& metrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); void AppendUIEditorDockHost( ::XCEngine::UI::UIDrawList& drawList, @@ -211,6 +216,7 @@ void AppendUIEditorDockHost( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostPalette& palette, - const UIEditorDockHostMetrics& metrics = {}); + const UIEditorDockHostMetrics& metrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); } // namespace XCEngine::UI::Editor::Widgets diff --git a/new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h b/new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h index aa05e973..505b8c69 100644 --- a/new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h +++ b/new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h @@ -53,6 +53,7 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction( UIEditorWorkspaceController& controller, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, - const Widgets::UIEditorDockHostMetrics& metrics = {}); + const Widgets::UIEditorDockHostMetrics& metrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); } // namespace XCEngine::UI::Editor diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h b/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h index a5bea042..c60e7dec 100644 --- a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h +++ b/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -91,7 +92,8 @@ UIEditorWorkspaceComposeRequest ResolveUIEditorWorkspaceComposeRequest( const std::vector& presentations, const Widgets::UIEditorDockHostState& dockHostState = {}, const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {}, - const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {}); + const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose( UIEditorWorkspaceComposeState& state, @@ -112,7 +114,8 @@ UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose( const Widgets::UIEditorDockHostState& dockHostState = {}, const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {}, const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {}, - const UIEditorWorkspaceInputOwner* inputOwner = nullptr); + const UIEditorWorkspaceInputOwner* inputOwner = nullptr, + const UIEditorTextMeasurer* textMeasurer = nullptr); std::vector CollectUIEditorWorkspaceComposeExternalBodyPanelIds( const UIEditorWorkspaceComposeFrame& frame); diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h b/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h index e494636d..7c969327 100644 --- a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h +++ b/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -47,6 +48,7 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction( const UIEditorWorkspaceInteractionModel& model, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {}, - const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {}); + const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {}, + const UIEditorTextMeasurer* textMeasurer = nullptr); } // namespace XCEngine::UI::Editor diff --git a/new_editor/src/Collections/UIEditorTabStrip.cpp b/new_editor/src/Collections/UIEditorTabStrip.cpp index eb5cbb9c..514643df 100644 --- a/new_editor/src/Collections/UIEditorTabStrip.cpp +++ b/new_editor/src/Collections/UIEditorTabStrip.cpp @@ -63,8 +63,8 @@ std::size_t ResolveSelectedIndex( float ResolveEstimatedLabelWidth( const UIEditorTabStripItem& item, const UIEditorTabStripMetrics& metrics) { - if (item.desiredHeaderLabelWidth > 0.0f) { - return item.desiredHeaderLabelWidth; + if (item.measuredLabelWidth > 0.0f) { + return item.measuredLabelWidth; } const float baseGlyphWidth = ClampNonNegative(metrics.estimatedGlyphWidth); @@ -248,14 +248,21 @@ void AppendSelectedTabBottomBorderMask( } // namespace -float ResolveUIEditorTabStripDesiredHeaderLabelWidth( +float ResolveUIEditorTabStripMeasuredLabelWidth( const UIEditorTabStripItem& item, - const UIEditorTabStripMetrics& metrics) { - const float labelWidth = ResolveEstimatedLabelWidth(item, metrics); - const float horizontalPadding = ClampNonNegative(metrics.layoutMetrics.tabHorizontalPadding); - const float extraLeftInset = (std::max)(ClampNonNegative(metrics.labelInsetX) - horizontalPadding, 0.0f); - (void)item; - return labelWidth + extraLeftInset; + const UIEditorTabStripMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { + float labelWidth = item.measuredLabelWidth; + if (labelWidth <= 0.0f && + textMeasurer != nullptr && + !item.title.empty()) { + labelWidth = textMeasurer->MeasureTextWidth( + UIEditorTextMeasureRequest { item.title, kHeaderFontSize }); + } + if (labelWidth <= 0.0f) { + labelWidth = ResolveEstimatedLabelWidth(item, metrics); + } + return labelWidth; } std::size_t ResolveUIEditorTabStripSelectedIndex( @@ -293,7 +300,7 @@ UIEditorTabStripLayout BuildUIEditorTabStripLayout( for (const UIEditorTabStripItem& item : items) { desiredHeaderWidths.push_back( MeasureUITabStripHeaderWidth( - ResolveUIEditorTabStripDesiredHeaderLabelWidth(item, metrics), + ResolveUIEditorTabStripMeasuredLabelWidth(item, metrics), metrics.layoutMetrics)); } diff --git a/new_editor/src/Docking/DockHostInteractionHelpers.cpp b/new_editor/src/Docking/DockHostInteractionHelpers.cpp index baa24a93..ad56a3de 100644 --- a/new_editor/src/Docking/DockHostInteractionHelpers.cpp +++ b/new_editor/src/Docking/DockHostInteractionHelpers.cpp @@ -195,6 +195,7 @@ std::vector BuildTabStripItems( UIEditorTabStripItem item = {}; item.tabId = itemLayout.panelId; item.title = itemLayout.title; + item.measuredLabelWidth = itemLayout.measuredLabelWidth; items.push_back(std::move(item)); } diff --git a/new_editor/src/Docking/DockHostMeasure.cpp b/new_editor/src/Docking/DockHostMeasure.cpp index ce8852c7..031998eb 100644 --- a/new_editor/src/Docking/DockHostMeasure.cpp +++ b/new_editor/src/Docking/DockHostMeasure.cpp @@ -19,7 +19,8 @@ DockHostNodeMeasureResult MeasureDockHostTabStackNode( const UIEditorWorkspaceNode& node, const UIEditorPanelRegistry& panelRegistry, const UIEditorWorkspaceSession& session, - const Widgets::UIEditorDockHostMetrics& metrics) { + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { (void)panelRegistry; std::vector measureItems = {}; for (const UIEditorWorkspaceNode& child : node.children) { @@ -33,7 +34,10 @@ DockHostNodeMeasureResult MeasureDockHostTabStackNode( item.title = child.panel.title; UITabStripMeasureItem measureItem = {}; measureItem.desiredHeaderLabelWidth = - ResolveUIEditorTabStripDesiredHeaderLabelWidth(item, metrics.tabStripMetrics); + ResolveUIEditorTabStripMeasuredLabelWidth( + item, + metrics.tabStripMetrics, + textMeasurer); measureItem.desiredContentSize = MeasureDockTabContentMinimumSize(metrics); measureItem.minimumContentSize = MeasureDockTabContentMinimumSize(metrics); measureItems.push_back(std::move(measureItem)); @@ -55,11 +59,22 @@ DockHostNodeMeasureResult MeasureDockHostSplitNode( const UIEditorWorkspaceNode& node, const UIEditorPanelRegistry& panelRegistry, const UIEditorWorkspaceSession& session, - const Widgets::UIEditorDockHostMetrics& metrics) { + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { const DockHostNodeMeasureResult primary = - MeasureDockHostNode(node.children[0], panelRegistry, session, metrics); + MeasureDockHostNode( + node.children[0], + panelRegistry, + session, + metrics, + textMeasurer); const DockHostNodeMeasureResult secondary = - MeasureDockHostNode(node.children[1], panelRegistry, session, metrics); + MeasureDockHostNode( + node.children[1], + panelRegistry, + session, + metrics, + textMeasurer); if (!primary.visible && !secondary.visible) { return {}; @@ -141,14 +156,25 @@ DockHostNodeMeasureResult MeasureDockHostNode( const UIEditorWorkspaceNode& node, const UIEditorPanelRegistry& panelRegistry, const UIEditorWorkspaceSession& session, - const Widgets::UIEditorDockHostMetrics& metrics) { + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { switch (node.kind) { case UIEditorWorkspaceNodeKind::Panel: return {}; case UIEditorWorkspaceNodeKind::TabStack: - return MeasureDockHostTabStackNode(node, panelRegistry, session, metrics); + return MeasureDockHostTabStackNode( + node, + panelRegistry, + session, + metrics, + textMeasurer); case UIEditorWorkspaceNodeKind::Split: - return MeasureDockHostSplitNode(node, panelRegistry, session, metrics); + return MeasureDockHostSplitNode( + node, + panelRegistry, + session, + metrics, + textMeasurer); } return {}; diff --git a/new_editor/src/Docking/DockHostMeasureInternal.h b/new_editor/src/Docking/DockHostMeasureInternal.h index 0e1f4059..11f48eac 100644 --- a/new_editor/src/Docking/DockHostMeasureInternal.h +++ b/new_editor/src/Docking/DockHostMeasureInternal.h @@ -30,6 +30,7 @@ DockHostNodeMeasureResult MeasureDockHostNode( const UIEditorWorkspaceNode& node, const UIEditorPanelRegistry& panelRegistry, const UIEditorWorkspaceSession& session, - const Widgets::UIEditorDockHostMetrics& metrics); + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer = nullptr); } // namespace XCEngine::UI::Editor::Internal diff --git a/new_editor/src/Docking/DockHostRendering.cpp b/new_editor/src/Docking/DockHostRendering.cpp index 2cb4168c..6d2e1012 100644 --- a/new_editor/src/Docking/DockHostRendering.cpp +++ b/new_editor/src/Docking/DockHostRendering.cpp @@ -87,6 +87,7 @@ void AppendUIEditorDockHostForeground( UIEditorTabStripItem tabItem = {}; tabItem.tabId = item.panelId; tabItem.title = item.title; + tabItem.measuredLabelWidth = item.measuredLabelWidth; tabItems.push_back(std::move(tabItem)); } @@ -138,9 +139,17 @@ void AppendUIEditorDockHost( const UIEditorDockHostState& state, const UIEditorDockHostForegroundOptions& foregroundOptions, const UIEditorDockHostPalette& palette, - const UIEditorDockHostMetrics& metrics) { + const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { const UIEditorDockHostLayout layout = - BuildUIEditorDockHostLayout(bounds, panelRegistry, workspace, session, state, metrics); + BuildUIEditorDockHostLayout( + bounds, + panelRegistry, + workspace, + session, + state, + metrics, + textMeasurer); AppendUIEditorDockHostBackground(drawList, layout, palette, metrics); AppendUIEditorDockHostForeground(drawList, layout, foregroundOptions, palette, metrics); } @@ -153,7 +162,8 @@ void AppendUIEditorDockHost( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostPalette& palette, - const UIEditorDockHostMetrics& metrics) { + const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { AppendUIEditorDockHost( drawList, bounds, @@ -163,7 +173,8 @@ void AppendUIEditorDockHost( state, UIEditorDockHostForegroundOptions{}, palette, - metrics); + metrics, + textMeasurer); } } // namespace XCEngine::UI::Editor::Widgets diff --git a/new_editor/src/Docking/UIEditorDockHost.cpp b/new_editor/src/Docking/UIEditorDockHost.cpp index 72196064..135f58e5 100644 --- a/new_editor/src/Docking/UIEditorDockHost.cpp +++ b/new_editor/src/Docking/UIEditorDockHost.cpp @@ -114,6 +114,7 @@ void LayoutNodeRecursive( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer, UIEditorDockHostLayout& layout); void LayoutTabStackNode( @@ -124,6 +125,7 @@ void LayoutTabStackNode( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer, UIEditorDockHostLayout& layout) { (void)panelRegistry; std::vector visibleChildIndices = {}; @@ -146,12 +148,16 @@ void LayoutTabStackNode( UIEditorDockHostTabItemLayout itemLayout = {}; itemLayout.panelId = child.panel.panelId; itemLayout.title = child.panel.title; - itemLayout.active = workspace.activePanelId == child.panel.panelId; - tabStackLayout.items.push_back(itemLayout); - UIEditorTabStripItem tabItem = {}; tabItem.tabId = itemLayout.panelId; tabItem.title = itemLayout.title; + tabItem.measuredLabelWidth = ResolveUIEditorTabStripMeasuredLabelWidth( + tabItem, + metrics.tabStripMetrics, + textMeasurer); + itemLayout.measuredLabelWidth = tabItem.measuredLabelWidth; + itemLayout.active = workspace.activePanelId == child.panel.panelId; + tabStackLayout.items.push_back(itemLayout); tabStripItems.push_back(std::move(tabItem)); } @@ -190,11 +196,22 @@ void LayoutSplitNode( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer, UIEditorDockHostLayout& layout) { const auto primaryMeasure = - Internal::MeasureDockHostNode(node.children[0], panelRegistry, session, metrics); + Internal::MeasureDockHostNode( + node.children[0], + panelRegistry, + session, + metrics, + textMeasurer); const auto secondaryMeasure = - Internal::MeasureDockHostNode(node.children[1], panelRegistry, session, metrics); + Internal::MeasureDockHostNode( + node.children[1], + panelRegistry, + session, + metrics, + textMeasurer); if (!primaryMeasure.visible && !secondaryMeasure.visible) { return; @@ -209,6 +226,7 @@ void LayoutSplitNode( session, state, metrics, + textMeasurer, layout); return; } @@ -222,6 +240,7 @@ void LayoutSplitNode( session, state, metrics, + textMeasurer, layout); return; } @@ -262,6 +281,7 @@ void LayoutSplitNode( session, state, metrics, + textMeasurer, layout); LayoutNodeRecursive( node.children[1], @@ -271,6 +291,7 @@ void LayoutSplitNode( session, state, metrics, + textMeasurer, layout); } @@ -282,6 +303,7 @@ void LayoutNodeRecursive( const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer, UIEditorDockHostLayout& layout) { switch (node.kind) { case UIEditorWorkspaceNodeKind::Panel: @@ -295,6 +317,7 @@ void LayoutNodeRecursive( session, state, metrics, + textMeasurer, layout); return; case UIEditorWorkspaceNodeKind::Split: @@ -306,6 +329,7 @@ void LayoutNodeRecursive( session, state, metrics, + textMeasurer, layout); return; } @@ -433,7 +457,8 @@ UIEditorDockHostLayout BuildUIEditorDockHostLayout( const UIEditorWorkspaceModel& workspace, const UIEditorWorkspaceSession& session, const UIEditorDockHostState& state, - const UIEditorDockHostMetrics& metrics) { + const UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { UIEditorDockHostLayout layout = {}; layout.bounds = UIRect( bounds.x, @@ -450,6 +475,7 @@ UIEditorDockHostLayout BuildUIEditorDockHostLayout( session, state, metrics, + textMeasurer, layout); layout.dropPreview = ResolveDropPreviewLayout(layout, state); return layout; diff --git a/new_editor/src/Docking/UIEditorDockHostInteraction.cpp b/new_editor/src/Docking/UIEditorDockHostInteraction.cpp index 3e6b3b72..bc7bec24 100644 --- a/new_editor/src/Docking/UIEditorDockHostInteraction.cpp +++ b/new_editor/src/Docking/UIEditorDockHostInteraction.cpp @@ -32,7 +32,8 @@ Widgets::UIEditorDockHostLayout RebuildDockHostLayout( UIEditorDockHostInteractionState& state, UIEditorWorkspaceController& controller, const ::XCEngine::UI::UIRect& bounds, - const Widgets::UIEditorDockHostMetrics& metrics) { + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { Internal::SyncDockHostTabStripVisualStates(state); Widgets::UIEditorDockHostLayout layout = BuildUIEditorDockHostLayout( bounds, @@ -40,7 +41,8 @@ Widgets::UIEditorDockHostLayout RebuildDockHostLayout( controller.GetWorkspace(), controller.GetSession(), state.dockHostState, - metrics); + metrics, + textMeasurer); if (Internal::PruneTabStripInteractionEntries(state, layout)) { Internal::SyncDockHostTabStripVisualStates(state); layout = BuildUIEditorDockHostLayout( @@ -49,7 +51,8 @@ Widgets::UIEditorDockHostLayout RebuildDockHostLayout( controller.GetWorkspace(), controller.GetSession(), state.dockHostState, - metrics); + metrics, + textMeasurer); } Internal::SyncHoverTarget(state, layout); return layout; @@ -411,9 +414,10 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction( UIEditorWorkspaceController& controller, const ::XCEngine::UI::UIRect& bounds, const std::vector& inputEvents, - const Widgets::UIEditorDockHostMetrics& metrics) { + const Widgets::UIEditorDockHostMetrics& metrics, + const UIEditorTextMeasurer* textMeasurer) { Widgets::UIEditorDockHostLayout layout = - RebuildDockHostLayout(state, controller, bounds, metrics); + RebuildDockHostLayout(state, controller, bounds, metrics, textMeasurer); UIEditorDockHostInteractionResult interactionResult = {}; for (const UIInputEvent& event : inputEvents) { @@ -564,7 +568,12 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction( } if (ShouldRebuildDockHostLayoutForNextEvent(eventResult)) { - layout = RebuildDockHostLayout(state, controller, bounds, metrics); + layout = RebuildDockHostLayout( + state, + controller, + bounds, + metrics, + textMeasurer); } else { Internal::SyncHoverTarget(state, layout); } @@ -577,7 +586,12 @@ UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction( } } - layout = RebuildDockHostLayout(state, controller, bounds, metrics); + layout = RebuildDockHostLayout( + state, + controller, + bounds, + metrics, + textMeasurer); if (interactionResult.hitTarget.kind == UIEditorDockHostHitTargetKind::None) { interactionResult.hitTarget = state.dockHostState.hoveredTarget; } diff --git a/new_editor/src/Shell/UIEditorShellInteraction.cpp b/new_editor/src/Shell/UIEditorShellInteraction.cpp index 5e83a517..8d698f8a 100644 --- a/new_editor/src/Shell/UIEditorShellInteraction.cpp +++ b/new_editor/src/Shell/UIEditorShellInteraction.cpp @@ -740,7 +740,9 @@ UIEditorShellInteractionFrame UpdateUIEditorShellInteraction( request.shellRequest.layout.workspaceRect, workspaceModel, workspaceInputEvents, - metrics.shellMetrics.dockHostMetrics); + metrics.shellMetrics.dockHostMetrics, + metrics.shellMetrics.viewportMetrics, + services.textMeasurer); state.composeState.workspaceState = state.workspaceInteractionState.composeState; const Internal::RequestHit finalHit = Internal::HitTestRequest( diff --git a/new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp b/new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp index f178be37..8a4c9503 100644 --- a/new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp +++ b/new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp @@ -189,14 +189,16 @@ UIEditorWorkspaceComposeRequest ResolveUIEditorWorkspaceComposeRequest( const std::vector& presentations, const Widgets::UIEditorDockHostState& dockHostState, const Widgets::UIEditorDockHostMetrics& dockHostMetrics, - const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) { + const Widgets::UIEditorViewportSlotMetrics& viewportMetrics, + const UIEditorTextMeasurer* textMeasurer) { const Widgets::UIEditorDockHostLayout dockHostLayout = BuildUIEditorDockHostLayout( bounds, panelRegistry, workspace, session, dockHostState, - dockHostMetrics); + dockHostMetrics, + textMeasurer); return ResolveUIEditorWorkspaceComposeRequest( dockHostLayout, panelRegistry, @@ -268,7 +270,8 @@ UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose( const Widgets::UIEditorDockHostState& dockHostState, const Widgets::UIEditorDockHostMetrics& dockHostMetrics, const Widgets::UIEditorViewportSlotMetrics& viewportMetrics, - const UIEditorWorkspaceInputOwner* inputOwner) { + const UIEditorWorkspaceInputOwner* inputOwner, + const UIEditorTextMeasurer* textMeasurer) { const UIEditorWorkspaceComposeRequest request = ResolveUIEditorWorkspaceComposeRequest( bounds, panelRegistry, @@ -277,7 +280,8 @@ UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose( presentations, dockHostState, dockHostMetrics, - viewportMetrics); + viewportMetrics, + textMeasurer); return UpdateUIEditorWorkspaceCompose( state, request, diff --git a/new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp b/new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp index 9932292e..63c691d7 100644 --- a/new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp +++ b/new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp @@ -64,7 +64,8 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction( const UIEditorWorkspaceInteractionModel& model, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const Widgets::UIEditorDockHostMetrics& dockHostMetrics, - const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) { + const Widgets::UIEditorViewportSlotMetrics& viewportMetrics, + const UIEditorTextMeasurer* textMeasurer) { UIEditorWorkspaceInteractionFrame frame = {}; frame.previousInputOwner = state.inputOwner; frame.dockHostFrame = UpdateUIEditorDockHostInteraction( @@ -72,7 +73,8 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction( controller, bounds, inputEvents, - dockHostMetrics); + dockHostMetrics, + textMeasurer); const UIEditorWorkspaceComposeRequest previewRequest = ResolveUIEditorWorkspaceComposeRequest( @@ -110,7 +112,8 @@ UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction( controller.GetWorkspace(), controller.GetSession(), state.dockHostInteractionState.dockHostState, - dockHostMetrics); + dockHostMetrics, + textMeasurer); } frame.dockHostFrame.layout = composeRequest.dockHostLayout;