Add new editor product shell baseline
This commit is contained in:
@@ -13,7 +13,8 @@ UIEditorCommandEvaluationResult MakeEvaluationResult(
|
||||
std::string displayName,
|
||||
UIEditorWorkspaceCommand workspaceCommand,
|
||||
UIEditorWorkspaceCommandResult previewResult,
|
||||
std::string message) {
|
||||
std::string message,
|
||||
UIEditorCommandKind kind) {
|
||||
UIEditorCommandEvaluationResult result = {};
|
||||
result.code = code;
|
||||
result.executable = executable;
|
||||
@@ -22,6 +23,7 @@ UIEditorCommandEvaluationResult MakeEvaluationResult(
|
||||
result.workspaceCommand = std::move(workspaceCommand);
|
||||
result.previewResult = std::move(previewResult);
|
||||
result.message = std::move(message);
|
||||
result.kind = kind;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -32,7 +34,8 @@ UIEditorCommandDispatchResult BuildDispatchResult(
|
||||
std::string displayName,
|
||||
UIEditorWorkspaceCommand workspaceCommand,
|
||||
UIEditorWorkspaceCommandResult commandResult,
|
||||
std::string message) {
|
||||
std::string message,
|
||||
UIEditorCommandKind kind) {
|
||||
UIEditorCommandDispatchResult result = {};
|
||||
result.status = status;
|
||||
result.commandExecuted = commandExecuted;
|
||||
@@ -41,6 +44,7 @@ UIEditorCommandDispatchResult BuildDispatchResult(
|
||||
result.workspaceCommand = std::move(workspaceCommand);
|
||||
result.commandResult = std::move(commandResult);
|
||||
result.message = std::move(message);
|
||||
result.kind = kind;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,8 @@ UIEditorCommandEvaluationResult UIEditorCommandDispatcher::Evaluate(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
"Command registry invalid: " + validation.message);
|
||||
"Command registry invalid: " + validation.message,
|
||||
UIEditorCommandKind::Workspace);
|
||||
}
|
||||
|
||||
const UIEditorCommandDescriptor* descriptor =
|
||||
@@ -93,7 +98,38 @@ UIEditorCommandEvaluationResult UIEditorCommandDispatcher::Evaluate(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
"Editor command '" + std::string(commandId) + "' is not registered.");
|
||||
"Editor command '" + std::string(commandId) + "' is not registered.",
|
||||
UIEditorCommandKind::Workspace);
|
||||
}
|
||||
|
||||
if (descriptor->kind == UIEditorCommandKind::Host) {
|
||||
if (m_hostCommandHandler == nullptr) {
|
||||
return MakeEvaluationResult(
|
||||
UIEditorCommandEvaluationCode::MissingHostCommandHandler,
|
||||
false,
|
||||
descriptor->commandId,
|
||||
descriptor->displayName,
|
||||
{},
|
||||
{},
|
||||
"Host command handler is not attached for '" + descriptor->commandId + "'.",
|
||||
descriptor->kind);
|
||||
}
|
||||
|
||||
const UIEditorHostCommandEvaluationResult hostEvaluation =
|
||||
m_hostCommandHandler->EvaluateHostCommand(descriptor->commandId);
|
||||
return MakeEvaluationResult(
|
||||
hostEvaluation.executable
|
||||
? UIEditorCommandEvaluationCode::None
|
||||
: UIEditorCommandEvaluationCode::HostCommandDisabled,
|
||||
hostEvaluation.executable,
|
||||
descriptor->commandId,
|
||||
descriptor->displayName,
|
||||
{},
|
||||
{},
|
||||
hostEvaluation.message.empty()
|
||||
? std::string("Host command evaluated.")
|
||||
: hostEvaluation.message,
|
||||
descriptor->kind);
|
||||
}
|
||||
|
||||
UIEditorWorkspaceCommand workspaceCommand = {};
|
||||
@@ -110,13 +146,14 @@ UIEditorCommandEvaluationResult UIEditorCommandDispatcher::Evaluate(
|
||||
case UIEditorCommandPanelSource::ActivePanel:
|
||||
if (controller.GetWorkspace().activePanelId.empty()) {
|
||||
return MakeEvaluationResult(
|
||||
UIEditorCommandEvaluationCode::MissingActivePanel,
|
||||
false,
|
||||
descriptor->commandId,
|
||||
descriptor->displayName,
|
||||
{},
|
||||
{},
|
||||
"Editor command '" + descriptor->commandId + "' requires an active panel.");
|
||||
UIEditorCommandEvaluationCode::MissingActivePanel,
|
||||
false,
|
||||
descriptor->commandId,
|
||||
descriptor->displayName,
|
||||
{},
|
||||
{},
|
||||
"Editor command '" + descriptor->commandId + "' requires an active panel.",
|
||||
descriptor->kind);
|
||||
}
|
||||
workspaceCommand.panelId = controller.GetWorkspace().activePanelId;
|
||||
break;
|
||||
@@ -133,7 +170,8 @@ UIEditorCommandEvaluationResult UIEditorCommandDispatcher::Evaluate(
|
||||
descriptor->displayName,
|
||||
std::move(workspaceCommand),
|
||||
std::move(previewResult),
|
||||
"Editor command resolved.");
|
||||
"Editor command resolved.",
|
||||
descriptor->kind);
|
||||
}
|
||||
|
||||
UIEditorCommandDispatchResult UIEditorCommandDispatcher::Dispatch(
|
||||
@@ -149,7 +187,38 @@ UIEditorCommandDispatchResult UIEditorCommandDispatcher::Dispatch(
|
||||
evaluation.displayName,
|
||||
evaluation.workspaceCommand,
|
||||
evaluation.previewResult,
|
||||
evaluation.message);
|
||||
evaluation.message,
|
||||
evaluation.kind);
|
||||
}
|
||||
|
||||
if (evaluation.kind == UIEditorCommandKind::Host) {
|
||||
if (m_hostCommandHandler == nullptr) {
|
||||
return BuildDispatchResult(
|
||||
UIEditorCommandDispatchStatus::Rejected,
|
||||
false,
|
||||
evaluation.commandId,
|
||||
evaluation.displayName,
|
||||
{},
|
||||
{},
|
||||
"Host command handler is not attached.",
|
||||
evaluation.kind);
|
||||
}
|
||||
|
||||
const UIEditorHostCommandDispatchResult hostDispatch =
|
||||
m_hostCommandHandler->DispatchHostCommand(evaluation.commandId);
|
||||
return BuildDispatchResult(
|
||||
hostDispatch.commandExecuted
|
||||
? UIEditorCommandDispatchStatus::Dispatched
|
||||
: UIEditorCommandDispatchStatus::Rejected,
|
||||
hostDispatch.commandExecuted,
|
||||
evaluation.commandId,
|
||||
evaluation.displayName,
|
||||
{},
|
||||
{},
|
||||
hostDispatch.message.empty()
|
||||
? std::string("Host command dispatched.")
|
||||
: hostDispatch.message,
|
||||
evaluation.kind);
|
||||
}
|
||||
|
||||
UIEditorWorkspaceCommandResult commandResult =
|
||||
@@ -168,7 +237,8 @@ UIEditorCommandDispatchResult UIEditorCommandDispatcher::Dispatch(
|
||||
std::move(commandResult),
|
||||
commandExecuted
|
||||
? "Editor command dispatched."
|
||||
: "Editor command dispatch was rejected.");
|
||||
: "Editor command dispatch was rejected.",
|
||||
evaluation.kind);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor
|
||||
|
||||
@@ -46,6 +46,17 @@ std::string_view GetUIEditorCommandPanelSourceName(UIEditorCommandPanelSource so
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string_view GetUIEditorCommandKindName(UIEditorCommandKind kind) {
|
||||
switch (kind) {
|
||||
case UIEditorCommandKind::Workspace:
|
||||
return "Workspace";
|
||||
case UIEditorCommandKind::Host:
|
||||
return "Host";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const UIEditorCommandDescriptor* FindUIEditorCommandDescriptor(
|
||||
const UIEditorCommandRegistry& registry,
|
||||
std::string_view commandId) {
|
||||
@@ -80,6 +91,17 @@ UIEditorCommandRegistryValidationResult ValidateUIEditorCommandRegistry(
|
||||
"Editor command id '" + command.commandId + "' is duplicated.");
|
||||
}
|
||||
|
||||
if (command.kind == UIEditorCommandKind::Host) {
|
||||
if (command.workspaceCommand.panelSource != UIEditorCommandPanelSource::None ||
|
||||
!command.workspaceCommand.panelId.empty()) {
|
||||
return MakeValidationError(
|
||||
UIEditorCommandRegistryValidationCode::UnexpectedPanelSource,
|
||||
"Host editor command '" + command.commandId +
|
||||
"' must not define workspace panel routing.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool requiresPanelId =
|
||||
CommandKindRequiresPanelId(command.workspaceCommand.kind);
|
||||
switch (command.workspaceCommand.panelSource) {
|
||||
|
||||
@@ -23,13 +23,8 @@ using ::XCEngine::UI::Layout::UITabStripMeasureItem;
|
||||
using ::XCEngine::UI::Layout::UILayoutAxis;
|
||||
using ::XCEngine::UI::Widgets::ExpandUISplitterHandleHitRect;
|
||||
|
||||
constexpr std::string_view kStandalonePanelPlaceholder = "DockHost standalone panel";
|
||||
constexpr std::string_view kStandalonePanelActiveFooter = "Active panel";
|
||||
constexpr std::string_view kStandalonePanelInactiveFooter = "Panel placeholder";
|
||||
constexpr std::string_view kStandalonePanelActiveDetail = "Active panel body is ready for composition";
|
||||
constexpr std::string_view kStandalonePanelIdleDetail = "Select the header or body to activate this panel";
|
||||
constexpr std::string_view kTabContentPlaceholder = "DockHost tab content placeholder";
|
||||
constexpr std::string_view kTabContentDetailPrefix = "Selected panel: ";
|
||||
|
||||
struct DockMeasureResult {
|
||||
bool visible = false;
|
||||
@@ -583,35 +578,6 @@ UIColor ResolveSplitterColor(const UIEditorDockHostSplitterLayout& splitter, con
|
||||
return palette.splitterColor;
|
||||
}
|
||||
|
||||
void AppendPlaceholderText(
|
||||
UIDrawList& drawList,
|
||||
const UIRect& bodyRect,
|
||||
std::string title,
|
||||
std::string detailLine,
|
||||
std::string extraLine,
|
||||
const UIEditorDockHostPalette& palette,
|
||||
const UIEditorDockHostMetrics& metrics) {
|
||||
if (bodyRect.width <= 0.0f || bodyRect.height <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawList.AddText(
|
||||
UIPoint(bodyRect.x, bodyRect.y),
|
||||
std::move(title),
|
||||
palette.placeholderTitleColor,
|
||||
16.0f);
|
||||
drawList.AddText(
|
||||
UIPoint(bodyRect.x, bodyRect.y + metrics.placeholderLineGap),
|
||||
std::move(detailLine),
|
||||
palette.placeholderTextColor,
|
||||
12.0f);
|
||||
drawList.AddText(
|
||||
UIPoint(bodyRect.x, bodyRect.y + metrics.placeholderLineGap * 2.0f),
|
||||
std::move(extraLine),
|
||||
palette.placeholderMutedColor,
|
||||
12.0f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const UIEditorDockHostSplitterLayout* FindUIEditorDockHostSplitterLayout(
|
||||
@@ -792,14 +758,6 @@ void AppendUIEditorDockHostForeground(
|
||||
if (UsesExternalBodyPresentation(options, panel.panelId)) {
|
||||
continue;
|
||||
}
|
||||
AppendPlaceholderText(
|
||||
drawList,
|
||||
panel.frameLayout.bodyRect,
|
||||
panel.title,
|
||||
std::string(kStandalonePanelPlaceholder),
|
||||
panel.active ? std::string(kStandalonePanelActiveDetail) : std::string(kStandalonePanelIdleDetail),
|
||||
palette,
|
||||
metrics);
|
||||
}
|
||||
|
||||
const UIEditorPanelFrameMetrics tabContentFrameMetrics =
|
||||
@@ -830,25 +788,9 @@ void AppendUIEditorDockHostForeground(
|
||||
palette.panelFramePalette,
|
||||
tabContentFrameMetrics);
|
||||
|
||||
std::string selectedTitle = "(none)";
|
||||
for (const UIEditorDockHostTabItemLayout& item : tabStack.items) {
|
||||
if (item.panelId == tabStack.selectedPanelId) {
|
||||
selectedTitle = item.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UsesExternalBodyPresentation(options, tabStack.selectedPanelId)) {
|
||||
continue;
|
||||
}
|
||||
AppendPlaceholderText(
|
||||
drawList,
|
||||
tabStack.contentFrameLayout.bodyRect,
|
||||
selectedTitle,
|
||||
std::string(kTabContentPlaceholder),
|
||||
std::string(kTabContentDetailPrefix) + tabStack.selectedPanelId,
|
||||
palette,
|
||||
metrics);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace XCEngine::UI::Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::UI::UIColor;
|
||||
using ::XCEngine::UI::UIPoint;
|
||||
using ::XCEngine::UI::UIRect;
|
||||
using Widgets::AppendUIEditorMenuBarBackground;
|
||||
using Widgets::AppendUIEditorMenuBarForeground;
|
||||
@@ -29,11 +31,170 @@ UIRect InsetRect(const UIRect& rect, float inset) {
|
||||
(std::max)(0.0f, rect.height - insetY * 2.0f));
|
||||
}
|
||||
|
||||
UIEditorShellToolbarLayout BuildUIEditorShellToolbarLayout(
|
||||
const UIRect& bounds,
|
||||
const std::vector<UIEditorShellToolbarButton>& buttons,
|
||||
const UIEditorShellToolbarMetrics& metrics) {
|
||||
UIEditorShellToolbarLayout layout = {};
|
||||
layout.bounds = bounds;
|
||||
if (buttons.empty() || bounds.width <= 0.0f || bounds.height <= 0.0f) {
|
||||
return layout;
|
||||
}
|
||||
|
||||
const float buttonWidth = ClampNonNegative(metrics.buttonWidth);
|
||||
const float buttonHeight = ClampNonNegative(metrics.buttonHeight);
|
||||
const float buttonGap = ClampNonNegative(metrics.buttonGap);
|
||||
const float groupPaddingX = ClampNonNegative(metrics.groupPaddingX);
|
||||
const float groupPaddingY = ClampNonNegative(metrics.groupPaddingY);
|
||||
const float totalButtonWidth =
|
||||
buttonWidth * static_cast<float>(buttons.size()) +
|
||||
buttonGap * static_cast<float>((std::max)(std::ptrdiff_t(0), static_cast<std::ptrdiff_t>(buttons.size()) - 1));
|
||||
const float groupWidth = totalButtonWidth + groupPaddingX * 2.0f;
|
||||
const float groupHeight =
|
||||
(std::min)(bounds.height, buttonHeight + groupPaddingY * 2.0f);
|
||||
|
||||
layout.groupRect = UIRect(
|
||||
bounds.x + (std::max)(0.0f, (bounds.width - groupWidth) * 0.5f),
|
||||
bounds.y + (std::max)(0.0f, (bounds.height - groupHeight) * 0.5f),
|
||||
(std::min)(groupWidth, bounds.width),
|
||||
groupHeight);
|
||||
|
||||
const float buttonY =
|
||||
layout.groupRect.y + (std::max)(0.0f, (layout.groupRect.height - buttonHeight) * 0.5f);
|
||||
float buttonX = layout.groupRect.x + groupPaddingX;
|
||||
layout.buttonRects.reserve(buttons.size());
|
||||
for (std::size_t index = 0; index < buttons.size(); ++index) {
|
||||
layout.buttonRects.push_back(UIRect(buttonX, buttonY, buttonWidth, buttonHeight));
|
||||
buttonX += buttonWidth + buttonGap;
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void AppendPlayGlyph(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIRect& rect,
|
||||
const UIColor& color,
|
||||
float thickness) {
|
||||
const UIPoint a(rect.x + rect.width * 0.38f, rect.y + rect.height * 0.27f);
|
||||
const UIPoint b(rect.x + rect.width * 0.38f, rect.y + rect.height * 0.73f);
|
||||
const UIPoint c(rect.x + rect.width * 0.70f, rect.y + rect.height * 0.50f);
|
||||
drawList.AddLine(a, b, color, thickness);
|
||||
drawList.AddLine(a, c, color, thickness);
|
||||
drawList.AddLine(b, c, color, thickness);
|
||||
}
|
||||
|
||||
void AppendPauseGlyph(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIRect& rect,
|
||||
const UIColor& color,
|
||||
float thickness) {
|
||||
const float top = rect.y + rect.height * 0.26f;
|
||||
const float bottom = rect.y + rect.height * 0.74f;
|
||||
const float left = rect.x + rect.width * 0.40f;
|
||||
const float right = rect.x + rect.width * 0.60f;
|
||||
drawList.AddLine(UIPoint(left, top), UIPoint(left, bottom), color, thickness);
|
||||
drawList.AddLine(UIPoint(right, top), UIPoint(right, bottom), color, thickness);
|
||||
}
|
||||
|
||||
void AppendStepGlyph(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIRect& rect,
|
||||
const UIColor& color,
|
||||
float thickness) {
|
||||
const UIPoint a(rect.x + rect.width * 0.30f, rect.y + rect.height * 0.27f);
|
||||
const UIPoint b(rect.x + rect.width * 0.30f, rect.y + rect.height * 0.73f);
|
||||
const UIPoint c(rect.x + rect.width * 0.58f, rect.y + rect.height * 0.50f);
|
||||
const float barX = rect.x + rect.width * 0.70f;
|
||||
drawList.AddLine(a, b, color, thickness);
|
||||
drawList.AddLine(a, c, color, thickness);
|
||||
drawList.AddLine(b, c, color, thickness);
|
||||
drawList.AddLine(
|
||||
UIPoint(barX, rect.y + rect.height * 0.25f),
|
||||
UIPoint(barX, rect.y + rect.height * 0.75f),
|
||||
color,
|
||||
thickness);
|
||||
}
|
||||
|
||||
void AppendToolbarGlyph(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIRect& rect,
|
||||
UIEditorShellToolbarGlyph glyph,
|
||||
const UIColor& color,
|
||||
float thickness) {
|
||||
switch (glyph) {
|
||||
case UIEditorShellToolbarGlyph::Play:
|
||||
AppendPlayGlyph(drawList, rect, color, thickness);
|
||||
break;
|
||||
case UIEditorShellToolbarGlyph::Pause:
|
||||
AppendPauseGlyph(drawList, rect, color, thickness);
|
||||
break;
|
||||
case UIEditorShellToolbarGlyph::Step:
|
||||
AppendStepGlyph(drawList, rect, color, thickness);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AppendUIEditorShellToolbar(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const UIEditorShellToolbarLayout& layout,
|
||||
const std::vector<UIEditorShellToolbarButton>& buttons,
|
||||
const UIEditorShellToolbarPalette& palette,
|
||||
const UIEditorShellToolbarMetrics& metrics) {
|
||||
if (layout.bounds.width <= 0.0f || layout.bounds.height <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawList.AddFilledRect(layout.bounds, palette.barColor);
|
||||
drawList.AddLine(
|
||||
UIPoint(layout.bounds.x, layout.bounds.y + layout.bounds.height - 1.0f),
|
||||
UIPoint(layout.bounds.x + layout.bounds.width, layout.bounds.y + layout.bounds.height - 1.0f),
|
||||
palette.groupBorderColor,
|
||||
metrics.borderThickness);
|
||||
|
||||
if (buttons.empty() || layout.groupRect.width <= 0.0f || layout.groupRect.height <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawList.AddFilledRect(
|
||||
layout.groupRect,
|
||||
palette.groupColor,
|
||||
metrics.groupCornerRounding);
|
||||
drawList.AddRectOutline(
|
||||
layout.groupRect,
|
||||
palette.groupBorderColor,
|
||||
metrics.borderThickness,
|
||||
metrics.groupCornerRounding);
|
||||
|
||||
const std::size_t buttonCount = (std::min)(buttons.size(), layout.buttonRects.size());
|
||||
for (std::size_t index = 0; index < buttonCount; ++index) {
|
||||
const UIRect& buttonRect = layout.buttonRects[index];
|
||||
drawList.AddFilledRect(
|
||||
buttonRect,
|
||||
palette.buttonColor,
|
||||
metrics.buttonCornerRounding);
|
||||
drawList.AddRectOutline(
|
||||
buttonRect,
|
||||
palette.buttonBorderColor,
|
||||
metrics.borderThickness,
|
||||
metrics.buttonCornerRounding);
|
||||
AppendToolbarGlyph(
|
||||
drawList,
|
||||
buttonRect,
|
||||
buttons[index].glyph,
|
||||
palette.iconColor,
|
||||
metrics.iconThickness);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
const UIRect& bounds,
|
||||
const std::vector<Widgets::UIEditorMenuBarItem>& menuBarItems,
|
||||
const std::vector<UIEditorShellToolbarButton>& toolbarButtons,
|
||||
const std::vector<Widgets::UIEditorStatusBarSegment>& statusSegments,
|
||||
const UIEditorShellComposeMetrics& metrics) {
|
||||
UIEditorShellComposeLayout layout = {};
|
||||
@@ -45,17 +206,35 @@ UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
layout.contentRect = InsetRect(layout.bounds, metrics.outerPadding);
|
||||
|
||||
const float menuBarHeight = ClampNonNegative(metrics.menuBarMetrics.barHeight);
|
||||
const float toolbarHeight = ClampNonNegative(metrics.toolbarMetrics.barHeight);
|
||||
const float statusBarHeight = ClampNonNegative(metrics.statusBarMetrics.barHeight);
|
||||
const float sectionGap = ClampNonNegative(metrics.sectionGap);
|
||||
const bool hasMenuBar = menuBarHeight > 0.0f && !menuBarItems.empty();
|
||||
const bool hasToolbar = toolbarHeight > 0.0f && !toolbarButtons.empty();
|
||||
const bool hasStatusBar = statusBarHeight > 0.0f && !statusSegments.empty();
|
||||
|
||||
float gapCount = 0.0f;
|
||||
if (hasMenuBar) {
|
||||
gapCount += 1.0f;
|
||||
}
|
||||
if (hasToolbar) {
|
||||
gapCount += 1.0f;
|
||||
}
|
||||
if (hasStatusBar) {
|
||||
gapCount += 1.0f;
|
||||
}
|
||||
|
||||
const float availableHeight = layout.contentRect.height;
|
||||
const float combinedBars = menuBarHeight + statusBarHeight;
|
||||
const float gapBudget = combinedBars > 0.0f ? sectionGap * 2.0f : 0.0f;
|
||||
const float clampedGapBudget = (std::min)(gapBudget, availableHeight);
|
||||
const float consumedHeight =
|
||||
(hasMenuBar ? menuBarHeight : 0.0f) +
|
||||
(hasToolbar ? toolbarHeight : 0.0f) +
|
||||
(hasStatusBar ? statusBarHeight : 0.0f) +
|
||||
sectionGap * gapCount;
|
||||
const float workspaceHeight =
|
||||
(std::max)(0.0f, availableHeight - combinedBars - clampedGapBudget);
|
||||
(std::max)(0.0f, availableHeight - consumedHeight);
|
||||
|
||||
float cursorY = layout.contentRect.y;
|
||||
if (menuBarHeight > 0.0f) {
|
||||
if (hasMenuBar) {
|
||||
layout.menuBarRect = UIRect(
|
||||
layout.contentRect.x,
|
||||
cursorY,
|
||||
@@ -64,13 +243,22 @@ UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
cursorY += menuBarHeight + sectionGap;
|
||||
}
|
||||
|
||||
if (hasToolbar) {
|
||||
layout.toolbarRect = UIRect(
|
||||
layout.contentRect.x,
|
||||
cursorY,
|
||||
layout.contentRect.width,
|
||||
toolbarHeight);
|
||||
cursorY += toolbarHeight + sectionGap;
|
||||
}
|
||||
|
||||
layout.workspaceRect = UIRect(
|
||||
layout.contentRect.x,
|
||||
cursorY,
|
||||
layout.contentRect.width,
|
||||
workspaceHeight);
|
||||
|
||||
if (statusBarHeight > 0.0f) {
|
||||
if (hasStatusBar) {
|
||||
layout.statusBarRect = UIRect(
|
||||
layout.contentRect.x,
|
||||
layout.contentRect.y + layout.contentRect.height - statusBarHeight,
|
||||
@@ -80,6 +268,8 @@ UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
|
||||
layout.menuBarLayout =
|
||||
BuildUIEditorMenuBarLayout(layout.menuBarRect, menuBarItems, metrics.menuBarMetrics);
|
||||
layout.toolbarLayout =
|
||||
BuildUIEditorShellToolbarLayout(layout.toolbarRect, toolbarButtons, metrics.toolbarMetrics);
|
||||
layout.statusBarLayout =
|
||||
BuildUIEditorStatusBarLayout(layout.statusBarRect, statusSegments, metrics.statusBarMetrics);
|
||||
return layout;
|
||||
@@ -98,6 +288,7 @@ UIEditorShellComposeRequest ResolveUIEditorShellComposeRequest(
|
||||
request.layout = BuildUIEditorShellComposeLayout(
|
||||
bounds,
|
||||
model.menuBarItems,
|
||||
model.toolbarButtons,
|
||||
model.statusSegments,
|
||||
metrics);
|
||||
request.workspaceRequest = ResolveUIEditorWorkspaceComposeRequest(
|
||||
@@ -113,6 +304,10 @@ UIEditorShellComposeRequest ResolveUIEditorShellComposeRequest(
|
||||
request.layout.menuBarRect,
|
||||
model.menuBarItems,
|
||||
metrics.menuBarMetrics);
|
||||
request.layout.toolbarLayout = BuildUIEditorShellToolbarLayout(
|
||||
request.layout.toolbarRect,
|
||||
model.toolbarButtons,
|
||||
metrics.toolbarMetrics);
|
||||
request.layout.statusBarLayout = BuildUIEditorStatusBarLayout(
|
||||
request.layout.statusBarRect,
|
||||
model.statusSegments,
|
||||
@@ -135,6 +330,7 @@ UIEditorShellComposeFrame UpdateUIEditorShellCompose(
|
||||
frame.layout = BuildUIEditorShellComposeLayout(
|
||||
bounds,
|
||||
model.menuBarItems,
|
||||
model.toolbarButtons,
|
||||
model.statusSegments,
|
||||
metrics);
|
||||
frame.workspaceFrame = UpdateUIEditorWorkspaceCompose(
|
||||
@@ -152,6 +348,10 @@ UIEditorShellComposeFrame UpdateUIEditorShellCompose(
|
||||
frame.layout.menuBarRect,
|
||||
model.menuBarItems,
|
||||
metrics.menuBarMetrics);
|
||||
frame.layout.toolbarLayout = BuildUIEditorShellToolbarLayout(
|
||||
frame.layout.toolbarRect,
|
||||
model.toolbarButtons,
|
||||
metrics.toolbarMetrics);
|
||||
frame.layout.statusBarLayout = BuildUIEditorStatusBarLayout(
|
||||
frame.layout.statusBarRect,
|
||||
model.statusSegments,
|
||||
@@ -191,6 +391,13 @@ void AppendUIEditorShellCompose(
|
||||
palette.menuBarPalette,
|
||||
metrics.menuBarMetrics);
|
||||
|
||||
AppendUIEditorShellToolbar(
|
||||
drawList,
|
||||
frame.layout.toolbarLayout,
|
||||
model.toolbarButtons,
|
||||
palette.toolbarPalette,
|
||||
metrics.toolbarMetrics);
|
||||
|
||||
AppendUIEditorWorkspaceCompose(
|
||||
drawList,
|
||||
frame.workspaceFrame,
|
||||
|
||||
@@ -168,6 +168,7 @@ UIEditorShellComposeModel BuildShellComposeModel(
|
||||
const std::vector<Widgets::UIEditorMenuBarItem>& menuBarItems) {
|
||||
UIEditorShellComposeModel shellModel = {};
|
||||
shellModel.menuBarItems = menuBarItems;
|
||||
shellModel.toolbarButtons = model.toolbarButtons;
|
||||
shellModel.statusSegments = model.statusSegments;
|
||||
shellModel.workspacePresentations = model.workspacePresentations;
|
||||
return shellModel;
|
||||
@@ -486,6 +487,7 @@ UIEditorShellInteractionModel ResolveUIEditorShellInteractionModel(
|
||||
controller,
|
||||
services.shortcutManager);
|
||||
}
|
||||
model.toolbarButtons = definition.toolbarButtons;
|
||||
model.statusSegments = definition.statusSegments;
|
||||
model.workspacePresentations = definition.workspacePresentations;
|
||||
return model;
|
||||
|
||||
Reference in New Issue
Block a user