refactor(new_editor/app): reorganize host structure and add smoke test

This commit is contained in:
2026-04-15 08:24:06 +08:00
parent 3617b4840b
commit 9e5954cf0a
235 changed files with 11157 additions and 10028 deletions

View File

@@ -1,216 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorWorkspaceModel.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <XCEditor/Shell/UIEditorPanelFrame.h>
#include <XCEditor/Collections/UIEditorTabStrip.h>
#include <XCEngine/UI/Layout/UISplitterLayout.h>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor::Widgets {
enum class UIEditorDockHostHitTargetKind : std::uint8_t {
None = 0,
SplitterHandle,
TabStripBackground,
Tab,
TabCloseButton,
PanelHeader,
PanelBody,
PanelFooter,
PanelCloseButton
};
struct UIEditorDockHostHitTarget {
UIEditorDockHostHitTargetKind kind = UIEditorDockHostHitTargetKind::None;
std::string nodeId = {};
std::string panelId = {};
std::size_t index = UIEditorTabStripInvalidIndex;
};
struct UIEditorDockHostTabStripVisualState {
std::string nodeId = {};
UIEditorTabStripState state = {};
};
struct UIEditorDockHostDropPreviewState {
bool visible = false;
std::string sourceNodeId = {};
std::string sourcePanelId = {};
std::string targetNodeId = {};
UIEditorWorkspaceDockPlacement placement =
UIEditorWorkspaceDockPlacement::Center;
std::size_t insertionIndex = UIEditorTabStripInvalidIndex;
};
struct UIEditorDockHostState {
bool focused = false;
UIEditorDockHostHitTarget hoveredTarget = {};
std::string activeSplitterNodeId = {};
std::vector<UIEditorDockHostTabStripVisualState> tabStripStates = {};
UIEditorDockHostDropPreviewState dropPreview = {};
};
struct UIEditorDockHostMetrics {
::XCEngine::UI::Layout::UISplitterMetrics splitterMetrics =
::XCEngine::UI::Layout::UISplitterMetrics{ 2.0f, 10.0f };
UIEditorTabStripMetrics tabStripMetrics = {};
UIEditorPanelFrameMetrics panelFrameMetrics = {};
::XCEngine::UI::UISize minimumStandalonePanelBodySize =
::XCEngine::UI::UISize(180.0f, 140.0f);
::XCEngine::UI::UISize minimumTabContentBodySize =
::XCEngine::UI::UISize(260.0f, 180.0f);
float splitterHandleRounding = 0.0f;
float placeholderLineGap = 22.0f;
};
struct UIEditorDockHostPalette {
UIEditorTabStripPalette tabStripPalette = {};
UIEditorPanelFramePalette panelFramePalette = {};
::XCEngine::UI::UIColor splitterColor =
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
::XCEngine::UI::UIColor splitterHoveredColor =
::XCEngine::UI::UIColor(0.16f, 0.16f, 0.16f, 1.0f);
::XCEngine::UI::UIColor splitterActiveColor =
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
::XCEngine::UI::UIColor placeholderTitleColor =
::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f);
::XCEngine::UI::UIColor placeholderTextColor =
::XCEngine::UI::UIColor(0.72f, 0.72f, 0.72f, 1.0f);
::XCEngine::UI::UIColor placeholderMutedColor =
::XCEngine::UI::UIColor(0.62f, 0.62f, 0.62f, 1.0f);
::XCEngine::UI::UIColor dropPreviewFillColor =
::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 0.06f);
::XCEngine::UI::UIColor dropPreviewBorderColor =
::XCEngine::UI::UIColor(0.95f, 0.95f, 0.95f, 0.55f);
};
struct UIEditorDockHostTabItemLayout {
std::string panelId = {};
std::string title = {};
bool closable = true;
bool active = false;
};
struct UIEditorDockHostSplitterLayout {
std::string nodeId = {};
UIEditorWorkspaceSplitAxis axis = UIEditorWorkspaceSplitAxis::Horizontal;
::XCEngine::UI::UIRect bounds = {};
::XCEngine::UI::UIRect handleHitRect = {};
::XCEngine::UI::Layout::UISplitterConstraints constraints = {};
::XCEngine::UI::Layout::UISplitterMetrics metrics = {};
::XCEngine::UI::Layout::UISplitterLayoutResult splitterLayout = {};
bool hovered = false;
bool active = false;
};
struct UIEditorDockHostTabStackLayout {
std::string nodeId = {};
std::string selectedPanelId = {};
::XCEngine::UI::UIRect bounds = {};
std::vector<UIEditorDockHostTabItemLayout> items = {};
UIEditorTabStripState tabStripState = {};
UIEditorTabStripLayout tabStripLayout = {};
UIEditorPanelFrameState contentFrameState = {};
UIEditorPanelFrameLayout contentFrameLayout = {};
};
struct UIEditorDockHostDropPreviewLayout {
bool visible = false;
std::string targetNodeId = {};
UIEditorWorkspaceDockPlacement placement =
UIEditorWorkspaceDockPlacement::Center;
std::size_t insertionIndex = UIEditorTabStripInvalidIndex;
::XCEngine::UI::UIRect previewRect = {};
};
struct UIEditorDockHostLayout {
::XCEngine::UI::UIRect bounds = {};
std::vector<UIEditorDockHostSplitterLayout> splitters = {};
std::vector<UIEditorDockHostTabStackLayout> tabStacks = {};
UIEditorDockHostDropPreviewLayout dropPreview = {};
};
enum class UIEditorDockHostCursorKind : std::uint8_t {
Arrow = 0,
ResizeEW,
ResizeNS
};
// Allows higher-level compose to own panel body presentation while DockHost
// keeps drawing the surrounding chrome/frame.
struct UIEditorDockHostForegroundOptions {
std::vector<std::string> externalBodyPanelIds = {};
};
const UIEditorDockHostSplitterLayout* FindUIEditorDockHostSplitterLayout(
const UIEditorDockHostLayout& layout,
std::string_view nodeId);
UIEditorDockHostCursorKind ResolveUIEditorDockHostCursorKind(
const UIEditorDockHostLayout& layout);
UIEditorDockHostLayout BuildUIEditorDockHostLayout(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const UIEditorDockHostState& state = {},
const UIEditorDockHostMetrics& metrics = {});
UIEditorDockHostDropPreviewLayout ResolveUIEditorDockHostDropPreviewLayout(
const UIEditorDockHostLayout& layout,
const UIEditorDockHostDropPreviewState& state);
UIEditorDockHostHitTarget HitTestUIEditorDockHost(
const UIEditorDockHostLayout& layout,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorDockHostBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorDockHostLayout& layout,
const UIEditorDockHostPalette& palette = {},
const UIEditorDockHostMetrics& metrics = {});
void AppendUIEditorDockHostForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorDockHostLayout& layout,
const UIEditorDockHostForegroundOptions& options = {},
const UIEditorDockHostPalette& palette = {},
const UIEditorDockHostMetrics& metrics = {});
void AppendUIEditorDockHostForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorDockHostLayout& layout,
const UIEditorDockHostPalette& palette,
const UIEditorDockHostMetrics& metrics = {});
void AppendUIEditorDockHost(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const UIEditorDockHostState& state = {},
const UIEditorDockHostForegroundOptions& foregroundOptions = {},
const UIEditorDockHostPalette& palette = {},
const UIEditorDockHostMetrics& metrics = {});
void AppendUIEditorDockHost(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const UIEditorDockHostState& state,
const UIEditorDockHostPalette& palette,
const UIEditorDockHostMetrics& metrics = {});
} // namespace XCEngine::UI::Editor::Widgets

View File

@@ -1,58 +0,0 @@
#pragma once
#include <XCEditor/Collections/UIEditorTabStripInteraction.h>
#include <XCEditor/Shell/UIEditorWorkspaceController.h>
#include <XCEditor/Shell/UIEditorDockHost.h>
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Widgets/UISplitterInteraction.h>
#include <string>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorDockHostTabStripInteractionEntry {
std::string nodeId = {};
UIEditorTabStripInteractionState state = {};
};
struct UIEditorDockHostInteractionState {
Widgets::UIEditorDockHostState dockHostState = {};
::XCEngine::UI::Widgets::UISplitterDragState splitterDragState = {};
std::vector<UIEditorDockHostTabStripInteractionEntry> tabStripInteractions = {};
std::string activeTabDragNodeId = {};
std::string activeTabDragPanelId = {};
::XCEngine::UI::UIPoint pointerPosition = {};
bool hasPointerPosition = false;
};
struct UIEditorDockHostInteractionResult {
bool consumed = false;
bool commandExecuted = false;
bool layoutChanged = false;
bool detachRequested = false;
bool requestPointerCapture = false;
bool releasePointerCapture = false;
Widgets::UIEditorDockHostHitTarget hitTarget = {};
std::string activeSplitterNodeId = {};
std::string detachedNodeId = {};
std::string detachedPanelId = {};
UIEditorWorkspaceCommandResult commandResult = {};
UIEditorWorkspaceLayoutOperationResult layoutResult = {};
};
struct UIEditorDockHostInteractionFrame {
Widgets::UIEditorDockHostLayout layout = {};
UIEditorDockHostInteractionResult result = {};
bool focused = false;
};
UIEditorDockHostInteractionFrame UpdateUIEditorDockHostInteraction(
UIEditorDockHostInteractionState& state,
UIEditorWorkspaceController& controller,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostMetrics& metrics = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,121 +0,0 @@
#pragma once
#include <XCEngine/UI/DrawData.h>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace XCEngine::UI::Editor::Widgets {
inline constexpr std::size_t UIEditorMenuBarInvalidIndex =
static_cast<std::size_t>(-1);
struct UIEditorMenuBarItem {
std::string menuId = {};
std::string label = {};
bool enabled = true;
float desiredLabelWidth = 0.0f;
};
struct UIEditorMenuBarState {
std::size_t openIndex = UIEditorMenuBarInvalidIndex;
std::size_t hoveredIndex = UIEditorMenuBarInvalidIndex;
bool focused = false;
};
struct UIEditorMenuBarMetrics {
float barHeight = 24.0f;
float horizontalInset = 0.0f;
float verticalInset = 2.0f;
float buttonGap = 1.0f;
float buttonPaddingX = 7.0f;
float labelFontSize = 13.0f;
float estimatedGlyphWidth = 6.5f;
float labelInsetY = -1.5f;
float barCornerRounding = 0.0f;
float buttonCornerRounding = 0.75f;
float baseBorderThickness = 1.0f;
float focusedBorderThickness = 1.0f;
float openBorderThickness = 1.0f;
};
struct UIEditorMenuBarPalette {
::XCEngine::UI::UIColor barColor =
::XCEngine::UI::UIColor(1.0f, 1.0f, 1.0f, 1.0f);
::XCEngine::UI::UIColor buttonColor =
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
::XCEngine::UI::UIColor buttonHoveredColor =
::XCEngine::UI::UIColor(0.88f, 0.88f, 0.88f, 1.0f);
::XCEngine::UI::UIColor buttonOpenColor =
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
::XCEngine::UI::UIColor focusedBorderColor =
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
::XCEngine::UI::UIColor openBorderColor =
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
::XCEngine::UI::UIColor textPrimary =
::XCEngine::UI::UIColor(0.08f, 0.08f, 0.08f, 1.0f);
::XCEngine::UI::UIColor textMuted =
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
::XCEngine::UI::UIColor textDisabled =
::XCEngine::UI::UIColor(0.50f, 0.50f, 0.50f, 1.0f);
};
struct UIEditorMenuBarLayout {
::XCEngine::UI::UIRect bounds = {};
::XCEngine::UI::UIRect contentRect = {};
std::vector<::XCEngine::UI::UIRect> buttonRects = {};
};
enum class UIEditorMenuBarHitTargetKind : std::uint8_t {
None = 0,
BarBackground,
Button
};
struct UIEditorMenuBarHitTarget {
UIEditorMenuBarHitTargetKind kind = UIEditorMenuBarHitTargetKind::None;
std::size_t index = UIEditorMenuBarInvalidIndex;
};
float ResolveUIEditorMenuBarDesiredButtonWidth(
const UIEditorMenuBarItem& item,
const UIEditorMenuBarMetrics& metrics = {});
UIEditorMenuBarLayout BuildUIEditorMenuBarLayout(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorMenuBarItem>& items,
const UIEditorMenuBarMetrics& metrics = {});
UIEditorMenuBarHitTarget HitTestUIEditorMenuBar(
const UIEditorMenuBarLayout& layout,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorMenuBarBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorMenuBarLayout& layout,
const std::vector<UIEditorMenuBarItem>& items,
const UIEditorMenuBarState& state,
const UIEditorMenuBarPalette& palette = {},
const UIEditorMenuBarMetrics& metrics = {});
void AppendUIEditorMenuBarForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorMenuBarLayout& layout,
const std::vector<UIEditorMenuBarItem>& items,
const UIEditorMenuBarState& state,
const UIEditorMenuBarPalette& palette = {},
const UIEditorMenuBarMetrics& metrics = {});
void AppendUIEditorMenuBar(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorMenuBarItem>& items,
const UIEditorMenuBarState& state,
const UIEditorMenuBarPalette& palette = {},
const UIEditorMenuBarMetrics& metrics = {});
} // namespace XCEngine::UI::Editor::Widgets

View File

@@ -1,116 +0,0 @@
#pragma once
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
class UIEditorShortcutManager;
enum class UIEditorMenuItemKind : std::uint8_t {
Command = 0,
Separator,
Submenu
};
enum class UIEditorMenuCheckedStateSource : std::uint8_t {
None = 0,
PanelOpen,
PanelVisible,
PanelActive
};
struct UIEditorMenuCheckedStateBinding {
UIEditorMenuCheckedStateSource source = UIEditorMenuCheckedStateSource::None;
std::string panelId = {};
};
struct UIEditorMenuItemDescriptor {
UIEditorMenuItemKind kind = UIEditorMenuItemKind::Command;
std::string itemId = {};
std::string label = {};
std::string commandId = {};
UIEditorMenuCheckedStateBinding checkedState = {};
std::vector<UIEditorMenuItemDescriptor> children = {};
};
struct UIEditorMenuDescriptor {
std::string menuId = {};
std::string label = {};
std::vector<UIEditorMenuItemDescriptor> items = {};
};
struct UIEditorMenuModel {
std::vector<UIEditorMenuDescriptor> menus = {};
};
enum class UIEditorMenuModelValidationCode : std::uint8_t {
None = 0,
InvalidCommandRegistry,
EmptyMenuId,
EmptyMenuLabel,
DuplicateMenuId,
EmptyCommandId,
UnknownCommandId,
MissingItemLabel,
CommandItemHasChildren,
SubmenuMissingLabel,
SubmenuEmptyChildren,
SubmenuHasCommandId,
SeparatorHasCommandId,
SeparatorHasChildren,
UnexpectedCheckedState,
MissingCheckedStatePanelId
};
struct UIEditorMenuModelValidationResult {
UIEditorMenuModelValidationCode code = UIEditorMenuModelValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorMenuModelValidationCode::None;
}
};
struct UIEditorResolvedMenuItem {
UIEditorMenuItemKind kind = UIEditorMenuItemKind::Command;
std::string itemId = {};
std::string label = {};
std::string commandId = {};
std::string commandDisplayName = {};
std::string shortcutText = {};
bool enabled = true;
bool checked = false;
UIEditorWorkspaceCommandStatus previewStatus =
UIEditorWorkspaceCommandStatus::Rejected;
std::string message = {};
std::vector<UIEditorResolvedMenuItem> children = {};
};
struct UIEditorResolvedMenuDescriptor {
std::string menuId = {};
std::string label = {};
std::vector<UIEditorResolvedMenuItem> items = {};
};
struct UIEditorResolvedMenuModel {
std::vector<UIEditorResolvedMenuDescriptor> menus = {};
};
std::string_view GetUIEditorMenuItemKindName(UIEditorMenuItemKind kind);
UIEditorMenuModelValidationResult ValidateUIEditorMenuModel(
const UIEditorMenuModel& model,
const UIEditorCommandRegistry& commandRegistry);
UIEditorResolvedMenuModel BuildUIEditorResolvedMenuModel(
const UIEditorMenuModel& model,
const UIEditorCommandDispatcher& commandDispatcher,
const UIEditorWorkspaceController& controller,
const UIEditorShortcutManager* shortcutManager = nullptr);
} // namespace XCEngine::UI::Editor

View File

@@ -1,136 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorMenuModel.h>
#include <XCEngine/UI/DrawData.h>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor::Widgets {
inline constexpr std::size_t UIEditorMenuPopupInvalidIndex =
static_cast<std::size_t>(-1);
struct UIEditorMenuPopupItem {
std::string itemId = {};
::XCEngine::UI::Editor::UIEditorMenuItemKind kind =
::XCEngine::UI::Editor::UIEditorMenuItemKind::Command;
std::string label = {};
std::string shortcutText = {};
bool enabled = true;
bool checked = false;
bool hasSubmenu = false;
float desiredLabelWidth = 0.0f;
float desiredShortcutWidth = 0.0f;
};
struct UIEditorMenuPopupState {
std::size_t hoveredIndex = UIEditorMenuPopupInvalidIndex;
std::size_t submenuOpenIndex = UIEditorMenuPopupInvalidIndex;
bool focused = false;
};
struct UIEditorMenuPopupMetrics {
float contentPaddingX = 2.0f;
float contentPaddingY = 3.0f;
float itemHeight = 24.0f;
float separatorHeight = 7.0f;
float checkColumnWidth = 12.0f;
float shortcutGap = 14.0f;
float submenuIndicatorWidth = 12.0f;
float rowCornerRounding = 2.5f;
float popupCornerRounding = 4.0f;
float labelInsetX = 4.0f;
float labelInsetY = -1.0f;
float labelFontSize = 13.0f;
float shortcutInsetRight = 8.0f;
float estimatedGlyphWidth = 7.0f;
float glyphFontSize = 12.0f;
float separatorThickness = 1.0f;
float borderThickness = 1.0f;
};
struct UIEditorMenuPopupPalette {
::XCEngine::UI::UIColor popupColor =
::XCEngine::UI::UIColor(0.97f, 0.97f, 0.97f, 1.0f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.62f, 0.62f, 0.62f, 1.0f);
::XCEngine::UI::UIColor itemHoverColor =
::XCEngine::UI::UIColor(0.86f, 0.86f, 0.86f, 1.0f);
::XCEngine::UI::UIColor itemOpenColor =
::XCEngine::UI::UIColor(0.82f, 0.82f, 0.82f, 1.0f);
::XCEngine::UI::UIColor separatorColor =
::XCEngine::UI::UIColor(0.78f, 0.78f, 0.78f, 1.0f);
::XCEngine::UI::UIColor textPrimary =
::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f);
::XCEngine::UI::UIColor textMuted =
::XCEngine::UI::UIColor(0.34f, 0.34f, 0.34f, 1.0f);
::XCEngine::UI::UIColor textDisabled =
::XCEngine::UI::UIColor(0.58f, 0.58f, 0.58f, 1.0f);
::XCEngine::UI::UIColor glyphColor =
::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f);
};
struct UIEditorMenuPopupLayout {
::XCEngine::UI::UIRect popupRect = {};
::XCEngine::UI::UIRect contentRect = {};
std::vector<::XCEngine::UI::UIRect> itemRects = {};
};
enum class UIEditorMenuPopupHitTargetKind : std::uint8_t {
None = 0,
PopupSurface,
Item
};
struct UIEditorMenuPopupHitTarget {
UIEditorMenuPopupHitTargetKind kind = UIEditorMenuPopupHitTargetKind::None;
std::size_t index = UIEditorMenuPopupInvalidIndex;
};
float ResolveUIEditorMenuPopupDesiredWidth(
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupMetrics& metrics = {});
float MeasureUIEditorMenuPopupHeight(
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupMetrics& metrics = {});
UIEditorMenuPopupLayout BuildUIEditorMenuPopupLayout(
const ::XCEngine::UI::UIRect& popupRect,
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupMetrics& metrics = {});
UIEditorMenuPopupHitTarget HitTestUIEditorMenuPopup(
const UIEditorMenuPopupLayout& layout,
const std::vector<UIEditorMenuPopupItem>& items,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorMenuPopupBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorMenuPopupLayout& layout,
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupState& state,
const UIEditorMenuPopupPalette& palette = {},
const UIEditorMenuPopupMetrics& metrics = {});
void AppendUIEditorMenuPopupForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorMenuPopupLayout& layout,
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupState& state,
const UIEditorMenuPopupPalette& palette = {},
const UIEditorMenuPopupMetrics& metrics = {});
void AppendUIEditorMenuPopup(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& popupRect,
const std::vector<UIEditorMenuPopupItem>& items,
const UIEditorMenuPopupState& state,
const UIEditorMenuPopupPalette& palette = {},
const UIEditorMenuPopupMetrics& metrics = {});
} // namespace XCEngine::UI::Editor::Widgets

View File

@@ -1,106 +0,0 @@
#pragma once
#include <XCEngine/UI/Input/UIInputPath.h>
#include <XCEngine/UI/Widgets/UIPopupOverlayModel.h>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorMenuPopupState {
std::string popupId = {};
std::string menuId = {};
std::string itemId = {};
[[nodiscard]] bool IsRootPopup() const {
return itemId.empty();
}
};
struct UIEditorMenuSessionMutationResult {
bool changed = false;
std::string openRootMenuId = {};
std::string openedPopupId = {};
std::vector<std::string> closedPopupIds = {};
::XCEngine::UI::Widgets::UIPopupDismissReason dismissReason =
::XCEngine::UI::Widgets::UIPopupDismissReason::None;
[[nodiscard]] bool HasOpenMenu() const {
return !openRootMenuId.empty();
}
};
class UIEditorMenuSession {
public:
const ::XCEngine::UI::Widgets::UIPopupOverlayModel& GetPopupOverlayModel() const {
return m_popupOverlayModel;
}
const std::vector<UIEditorMenuPopupState>& GetPopupStates() const {
return m_popupStates;
}
const std::vector<std::string>& GetOpenSubmenuItemIds() const {
return m_openSubmenuItemIds;
}
std::string_view GetOpenRootMenuId() const {
return m_openRootMenuId;
}
[[nodiscard]] bool HasOpenMenu() const {
return !m_openRootMenuId.empty();
}
[[nodiscard]] bool IsMenuOpen(std::string_view menuId) const {
return !m_openRootMenuId.empty() && m_openRootMenuId == menuId;
}
[[nodiscard]] bool IsPopupOpen(std::string_view popupId) const;
const UIEditorMenuPopupState* FindPopupState(std::string_view popupId) const;
void Reset();
UIEditorMenuSessionMutationResult OpenRootMenu(
std::string_view menuId,
::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
UIEditorMenuSessionMutationResult OpenMenuBarRoot(
std::string_view menuId,
::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
UIEditorMenuSessionMutationResult HoverMenuBarRoot(
std::string_view menuId,
::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
UIEditorMenuSessionMutationResult HoverSubmenu(
std::string_view itemId,
::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
UIEditorMenuSessionMutationResult CloseAll(
::XCEngine::UI::Widgets::UIPopupDismissReason dismissReason =
::XCEngine::UI::Widgets::UIPopupDismissReason::Programmatic);
UIEditorMenuSessionMutationResult DismissFromEscape();
UIEditorMenuSessionMutationResult DismissFromPointerDown(
const UIInputPath& hitPath);
UIEditorMenuSessionMutationResult DismissFromFocusLoss(
const UIInputPath& focusedPath);
private:
UIEditorMenuSessionMutationResult BuildResult(
const ::XCEngine::UI::Widgets::UIPopupOverlayMutationResult& mutation) const;
void RemoveClosedPopupStates(const std::vector<std::string>& closedPopupIds);
void RebuildDerivedState();
std::string m_openRootMenuId = {};
::XCEngine::UI::Widgets::UIPopupOverlayModel m_popupOverlayModel = {};
std::vector<UIEditorMenuPopupState> m_popupStates = {};
std::vector<std::string> m_openSubmenuItemIds = {};
};
} // namespace XCEngine::UI::Editor

View File

@@ -1,88 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorDockHost.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorPanelContentHostEventKind : std::uint8_t {
Mounted = 0,
Unmounted,
BoundsChanged
};
std::string_view GetUIEditorPanelContentHostEventKindName(
UIEditorPanelContentHostEventKind kind);
bool IsUIEditorPanelPresentationExternallyHosted(UIEditorPanelPresentationKind kind);
struct UIEditorPanelContentHostBinding {
std::string panelId = {};
UIEditorPanelPresentationKind kind = UIEditorPanelPresentationKind::Placeholder;
};
struct UIEditorPanelContentHostMountRequest {
std::string panelId = {};
UIEditorPanelPresentationKind kind = UIEditorPanelPresentationKind::Placeholder;
::XCEngine::UI::UIRect bounds = {};
};
struct UIEditorPanelContentHostRequest {
std::vector<UIEditorPanelContentHostMountRequest> mountRequests = {};
};
struct UIEditorPanelContentHostPanelState {
std::string panelId = {};
UIEditorPanelPresentationKind kind = UIEditorPanelPresentationKind::Placeholder;
bool mounted = false;
::XCEngine::UI::UIRect bounds = {};
};
struct UIEditorPanelContentHostState {
std::vector<UIEditorPanelContentHostPanelState> panelStates = {};
};
struct UIEditorPanelContentHostEvent {
UIEditorPanelContentHostEventKind kind = UIEditorPanelContentHostEventKind::Mounted;
std::string panelId = {};
UIEditorPanelPresentationKind presentationKind = UIEditorPanelPresentationKind::Placeholder;
::XCEngine::UI::UIRect bounds = {};
};
struct UIEditorPanelContentHostFrame {
std::vector<UIEditorPanelContentHostPanelState> panelStates = {};
std::vector<UIEditorPanelContentHostEvent> events = {};
};
const UIEditorPanelContentHostMountRequest* FindUIEditorPanelContentHostMountRequest(
const UIEditorPanelContentHostRequest& request,
std::string_view panelId);
const UIEditorPanelContentHostPanelState* FindUIEditorPanelContentHostPanelState(
const UIEditorPanelContentHostState& state,
std::string_view panelId);
const UIEditorPanelContentHostPanelState* FindUIEditorPanelContentHostPanelState(
const UIEditorPanelContentHostFrame& frame,
std::string_view panelId);
UIEditorPanelContentHostRequest ResolveUIEditorPanelContentHostRequest(
const Widgets::UIEditorDockHostLayout& dockHostLayout,
const UIEditorPanelRegistry& panelRegistry,
const std::vector<UIEditorPanelContentHostBinding>& bindings);
UIEditorPanelContentHostFrame UpdateUIEditorPanelContentHost(
UIEditorPanelContentHostState& state,
const UIEditorPanelContentHostRequest& request,
const UIEditorPanelRegistry& panelRegistry,
const std::vector<UIEditorPanelContentHostBinding>& bindings);
std::vector<std::string> CollectMountedUIEditorPanelContentHostPanelIds(
const UIEditorPanelContentHostFrame& frame);
} // namespace XCEngine::UI::Editor

View File

@@ -1,160 +0,0 @@
#pragma once
#include <XCEngine/UI/DrawData.h>
#include <cstdint>
#include <string_view>
namespace XCEngine::UI::Editor::Widgets {
enum class UIEditorPanelFrameAction : std::uint8_t {
None = 0,
Pin,
Close
};
enum class UIEditorPanelFrameHitTarget : std::uint8_t {
None = 0,
Header,
Body,
Footer,
PinButton,
CloseButton
};
struct UIEditorPanelFrameState {
bool active = false;
bool hovered = false;
bool focused = false;
bool pinned = false;
bool closable = true;
bool pinnable = true;
bool showFooter = false;
bool pinHovered = false;
bool closeHovered = false;
};
struct UIEditorPanelFrameText {
std::string_view title = {};
std::string_view subtitle = {};
std::string_view footer = {};
};
struct UIEditorPanelFrameMetrics {
float cornerRounding = 0.0f;
float headerHeight = 28.0f;
float footerHeight = 18.0f;
float contentPadding = 8.0f;
float titleInsetX = 9.0f;
float titleInsetY = 6.0f;
float subtitleInsetY = 16.0f;
float footerInsetX = 9.0f;
float footerInsetY = 3.0f;
float actionButtonExtent = 14.0f;
float actionInsetX = 8.0f;
float actionGap = 4.0f;
float baseBorderThickness = 1.0f;
float hoveredBorderThickness = 1.0f;
float activeBorderThickness = 1.0f;
float focusedBorderThickness = 1.0f;
};
struct UIEditorPanelFramePalette {
::XCEngine::UI::UIColor surfaceColor =
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
::XCEngine::UI::UIColor headerColor =
::XCEngine::UI::UIColor(0.20f, 0.20f, 0.20f, 1.0f);
::XCEngine::UI::UIColor footerColor =
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.23f, 0.23f, 0.23f, 1.0f);
::XCEngine::UI::UIColor hoveredBorderColor =
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
::XCEngine::UI::UIColor activeBorderColor =
::XCEngine::UI::UIColor(0.32f, 0.32f, 0.32f, 1.0f);
::XCEngine::UI::UIColor focusedBorderColor =
::XCEngine::UI::UIColor(0.36f, 0.36f, 0.36f, 1.0f);
::XCEngine::UI::UIColor textPrimary =
::XCEngine::UI::UIColor(0.86f, 0.86f, 0.86f, 1.0f);
::XCEngine::UI::UIColor textSecondary =
::XCEngine::UI::UIColor(0.64f, 0.64f, 0.64f, 1.0f);
::XCEngine::UI::UIColor textMuted =
::XCEngine::UI::UIColor(0.58f, 0.58f, 0.58f, 1.0f);
::XCEngine::UI::UIColor actionButtonColor =
::XCEngine::UI::UIColor(0.21f, 0.21f, 0.21f, 1.0f);
::XCEngine::UI::UIColor actionButtonHoveredColor =
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
::XCEngine::UI::UIColor actionButtonSelectedColor =
::XCEngine::UI::UIColor(0.27f, 0.27f, 0.27f, 1.0f);
::XCEngine::UI::UIColor actionButtonBorderColor =
::XCEngine::UI::UIColor(0.29f, 0.29f, 0.29f, 1.0f);
::XCEngine::UI::UIColor actionGlyphColor =
::XCEngine::UI::UIColor(0.82f, 0.82f, 0.82f, 1.0f);
};
struct UIEditorPanelFrameLayout {
::XCEngine::UI::UIRect frameRect = {};
::XCEngine::UI::UIRect headerRect = {};
::XCEngine::UI::UIRect bodyRect = {};
::XCEngine::UI::UIRect footerRect = {};
::XCEngine::UI::UIRect pinButtonRect = {};
::XCEngine::UI::UIRect closeButtonRect = {};
bool hasFooter = false;
bool showPinButton = false;
bool showCloseButton = false;
};
bool IsUIEditorPanelFramePointInside(
const ::XCEngine::UI::UIRect& rect,
const ::XCEngine::UI::UIPoint& point);
bool IsUIEditorPanelFramePinButtonVisible(const UIEditorPanelFrameState& state);
bool IsUIEditorPanelFrameCloseButtonVisible(const UIEditorPanelFrameState& state);
UIEditorPanelFrameLayout BuildUIEditorPanelFrameLayout(
const ::XCEngine::UI::UIRect& frameRect,
const UIEditorPanelFrameState& state,
const UIEditorPanelFrameMetrics& metrics = {});
::XCEngine::UI::UIColor ResolveUIEditorPanelFrameBorderColor(
const UIEditorPanelFrameState& state,
const UIEditorPanelFramePalette& palette = {});
float ResolveUIEditorPanelFrameBorderThickness(
const UIEditorPanelFrameState& state,
const UIEditorPanelFrameMetrics& metrics = {});
UIEditorPanelFrameAction HitTestUIEditorPanelFrameAction(
const UIEditorPanelFrameLayout& layout,
const UIEditorPanelFrameState& state,
const ::XCEngine::UI::UIPoint& point);
UIEditorPanelFrameHitTarget HitTestUIEditorPanelFrame(
const UIEditorPanelFrameLayout& layout,
const UIEditorPanelFrameState& state,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorPanelFrameBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorPanelFrameLayout& layout,
const UIEditorPanelFrameState& state,
const UIEditorPanelFramePalette& palette = {},
const UIEditorPanelFrameMetrics& metrics = {});
void AppendUIEditorPanelFrameForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorPanelFrameLayout& layout,
const UIEditorPanelFrameState& state,
const UIEditorPanelFrameText& text,
const UIEditorPanelFramePalette& palette = {},
const UIEditorPanelFrameMetrics& metrics = {});
void AppendUIEditorPanelFrame(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& frameRect,
const UIEditorPanelFrameState& state,
const UIEditorPanelFrameText& text,
const UIEditorPanelFramePalette& palette = {},
const UIEditorPanelFrameMetrics& metrics = {});
} // namespace XCEngine::UI::Editor::Widgets

View File

@@ -1,68 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorPanelHostLifecycleEventKind : std::uint8_t {
Attached = 0,
Detached,
Shown,
Hidden,
Activated,
Deactivated,
FocusGained,
FocusLost
};
std::string_view GetUIEditorPanelHostLifecycleEventKindName(
UIEditorPanelHostLifecycleEventKind kind);
struct UIEditorPanelHostState {
std::string panelId = {};
bool attached = false;
bool visible = false;
bool active = false;
bool focused = false;
};
struct UIEditorPanelHostLifecycleEvent {
UIEditorPanelHostLifecycleEventKind kind = UIEditorPanelHostLifecycleEventKind::Attached;
std::string panelId = {};
};
struct UIEditorPanelHostLifecycleState {
std::vector<UIEditorPanelHostState> panelStates = {};
};
struct UIEditorPanelHostLifecycleRequest {
std::string focusedPanelId = {};
};
struct UIEditorPanelHostLifecycleFrame {
std::vector<UIEditorPanelHostState> panelStates = {};
std::vector<UIEditorPanelHostLifecycleEvent> events = {};
};
const UIEditorPanelHostState* FindUIEditorPanelHostState(
const UIEditorPanelHostLifecycleState& state,
std::string_view panelId);
const UIEditorPanelHostState* FindUIEditorPanelHostState(
const UIEditorPanelHostLifecycleFrame& frame,
std::string_view panelId);
UIEditorPanelHostLifecycleFrame UpdateUIEditorPanelHostLifecycle(
UIEditorPanelHostLifecycleState& state,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const UIEditorPanelHostLifecycleRequest& request = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,54 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorPanelPresentationKind : std::uint8_t {
Placeholder = 0,
ViewportShell,
HostedContent
};
struct UIEditorPanelDescriptor {
std::string panelId = {};
std::string defaultTitle = {};
UIEditorPanelPresentationKind presentationKind = UIEditorPanelPresentationKind::Placeholder;
bool placeholder = true;
bool canHide = true;
bool canClose = true;
};
struct UIEditorPanelRegistry {
std::vector<UIEditorPanelDescriptor> panels = {};
};
enum class UIEditorPanelRegistryValidationCode : std::uint8_t {
None = 0,
EmptyPanelId,
EmptyDefaultTitle,
DuplicatePanelId
};
struct UIEditorPanelRegistryValidationResult {
UIEditorPanelRegistryValidationCode code = UIEditorPanelRegistryValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorPanelRegistryValidationCode::None;
}
};
UIEditorPanelRegistry BuildDefaultEditorShellPanelRegistry();
const UIEditorPanelDescriptor* FindUIEditorPanelDescriptor(
const UIEditorPanelRegistry& registry,
std::string_view panelId);
UIEditorPanelRegistryValidationResult ValidateUIEditorPanelRegistry(
const UIEditorPanelRegistry& registry);
} // namespace XCEngine::UI::Editor

View File

@@ -1,11 +1,11 @@
#pragma once
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
#include <XCEditor/Shell/UIEditorMenuModel.h>
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Menu/UIEditorMenuModel.h>
#include <XCEditor/Panels/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Shell/UIEditorWorkspaceModel.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <XCEditor/Workspace/UIEditorWorkspaceModel.h>
#include <XCEditor/Workspace/UIEditorWorkspaceSession.h>
#include <cstdint>
#include <filesystem>

View File

@@ -1,7 +1,7 @@
#pragma once
#include <XCEditor/Shell/UIEditorWorkspaceCompose.h>
#include <XCEditor/Shell/UIEditorMenuBar.h>
#include <XCEditor/Workspace/UIEditorWorkspaceCompose.h>
#include <XCEditor/Menu/UIEditorMenuBar.h>
#include <XCEditor/Shell/UIEditorStatusBar.h>
namespace XCEngine::UI::Editor {
@@ -39,17 +39,17 @@ struct UIEditorShellToolbarMetrics {
struct UIEditorShellToolbarPalette {
::XCEngine::UI::UIColor barColor =
::XCEngine::UI::UIColor(0.13f, 0.13f, 0.13f, 1.0f);
::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f);
::XCEngine::UI::UIColor groupColor =
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor(0.11f, 0.11f, 0.11f, 1.0f);
::XCEngine::UI::UIColor groupBorderColor =
::XCEngine::UI::UIColor(0.25f, 0.25f, 0.25f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor buttonColor =
::XCEngine::UI::UIColor(0.19f, 0.19f, 0.19f, 1.0f);
::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f);
::XCEngine::UI::UIColor buttonBorderColor =
::XCEngine::UI::UIColor(0.29f, 0.29f, 0.29f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor iconColor =
::XCEngine::UI::UIColor(0.82f, 0.82f, 0.82f, 1.0f);
::XCEngine::UI::UIColor(0.88f, 0.88f, 0.88f, 1.0f);
};
struct UIEditorShellComposeModel {
@@ -78,9 +78,9 @@ struct UIEditorShellComposeMetrics {
struct UIEditorShellComposePalette {
::XCEngine::UI::UIColor surfaceColor =
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f);
::XCEngine::UI::UIColor surfaceBorderColor =
::XCEngine::UI::UIColor(0.27f, 0.27f, 0.27f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
Widgets::UIEditorMenuBarPalette menuBarPalette = {};
UIEditorShellToolbarPalette toolbarPalette = {};
Widgets::UIEditorDockHostPalette dockHostPalette = {};

View File

@@ -1,12 +1,12 @@
#pragma once
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
#include <XCEditor/Shell/UIEditorMenuModel.h>
#include <XCEditor/Shell/UIEditorMenuSession.h>
#include <XCEditor/Menu/UIEditorMenuModel.h>
#include <XCEditor/Menu/UIEditorMenuSession.h>
#include <XCEditor/Shell/UIEditorShellCompose.h>
#include <XCEditor/Shell/UIEditorWorkspaceController.h>
#include <XCEditor/Shell/UIEditorWorkspaceInteraction.h>
#include <XCEditor/Shell/UIEditorMenuPopup.h>
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
#include <XCEditor/Workspace/UIEditorWorkspaceInteraction.h>
#include <XCEditor/Menu/UIEditorMenuPopup.h>
#include <XCEngine/UI/DrawData.h>

View File

@@ -64,27 +64,27 @@ struct UIEditorStatusBarMetrics {
struct UIEditorStatusBarPalette {
::XCEngine::UI::UIColor surfaceColor =
::XCEngine::UI::UIColor(0.16f, 0.16f, 0.16f, 1.0f);
::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.23f, 0.23f, 0.23f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor focusedBorderColor =
::XCEngine::UI::UIColor(0.35f, 0.35f, 0.35f, 1.0f);
::XCEngine::UI::UIColor(0.19f, 0.19f, 0.19f, 1.0f);
::XCEngine::UI::UIColor segmentColor =
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f);
::XCEngine::UI::UIColor segmentHoveredColor =
::XCEngine::UI::UIColor(0.22f, 0.22f, 0.22f, 1.0f);
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
::XCEngine::UI::UIColor segmentActiveColor =
::XCEngine::UI::UIColor(0.25f, 0.25f, 0.25f, 1.0f);
::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f);
::XCEngine::UI::UIColor segmentBorderColor =
::XCEngine::UI::UIColor(0.29f, 0.29f, 0.29f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor separatorColor =
::XCEngine::UI::UIColor(0.27f, 0.27f, 0.27f, 1.0f);
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor textPrimary =
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f);
::XCEngine::UI::UIColor textMuted =
::XCEngine::UI::UIColor(0.62f, 0.62f, 0.62f, 1.0f);
::XCEngine::UI::UIColor textAccent =
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
::XCEngine::UI::UIColor(0.94f, 0.94f, 0.94f, 1.0f);
};
struct UIEditorStatusBarLayout {

View File

@@ -3,7 +3,7 @@
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
#include <XCEditor/Shell/UIEditorShellAsset.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Shell/UIEditorWorkspaceController.h>
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
#include <XCEngine/UI/Runtime/UIScreenTypes.h>

View File

@@ -1,67 +0,0 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <cstdint>
#include <unordered_set>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorViewportInputBridgeConfig {
bool focusOnPointerDownInside = true;
bool clearFocusOnPointerDownOutside = true;
bool capturePointerOnPointerDownInside = true;
};
struct UIEditorViewportInputBridgeState {
bool hovered = false;
bool focused = false;
bool captured = false;
::XCEngine::UI::UIPointerButton captureButton = ::XCEngine::UI::UIPointerButton::None;
::XCEngine::UI::UIPoint lastScreenPointerPosition = {};
::XCEngine::UI::UIPoint lastLocalPointerPosition = {};
bool hasPointerPosition = false;
::XCEngine::UI::UIInputModifiers modifiers = {};
std::unordered_set<std::int32_t> pressedKeys = {};
std::uint8_t pointerButtonsDownMask = 0;
};
struct UIEditorViewportInputBridgeFrame {
bool hovered = false;
bool focused = false;
bool captured = false;
bool pointerInside = false;
bool pointerMoved = false;
bool pointerPressedInside = false;
bool pointerReleasedInside = false;
bool focusGained = false;
bool focusLost = false;
bool captureStarted = false;
bool captureEnded = false;
::XCEngine::UI::UIPointerButton changedPointerButton = ::XCEngine::UI::UIPointerButton::None;
::XCEngine::UI::UIPoint screenPointerPosition = {};
::XCEngine::UI::UIPoint localPointerPosition = {};
::XCEngine::UI::UIPoint pointerDelta = {};
float wheelDelta = 0.0f;
::XCEngine::UI::UIInputModifiers modifiers = {};
std::vector<std::int32_t> pressedKeyCodes = {};
std::vector<std::int32_t> releasedKeyCodes = {};
std::vector<std::uint32_t> characters = {};
};
bool IsUIEditorViewportInputBridgeKeyDown(
const UIEditorViewportInputBridgeState& state,
std::int32_t keyCode);
bool IsUIEditorViewportInputBridgePointerButtonDown(
const UIEditorViewportInputBridgeState& state,
::XCEngine::UI::UIPointerButton button);
UIEditorViewportInputBridgeFrame UpdateUIEditorViewportInputBridge(
UIEditorViewportInputBridgeState& state,
const ::XCEngine::UI::UIRect& inputRect,
const std::vector<::XCEngine::UI::UIInputEvent>& events,
const UIEditorViewportInputBridgeConfig& config = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,57 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorViewportInputBridge.h>
#include <XCEditor/Shell/UIEditorViewportSlot.h>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorViewportShellVisualState {
std::size_t hoveredToolIndex = Widgets::UIEditorViewportSlotInvalidIndex;
std::size_t activeToolIndex = Widgets::UIEditorViewportSlotInvalidIndex;
Widgets::UIEditorStatusBarState statusBarState = {};
};
struct UIEditorViewportShellSpec {
Widgets::UIEditorViewportSlotChrome chrome = {};
std::vector<Widgets::UIEditorViewportSlotToolItem> toolItems = {};
std::vector<Widgets::UIEditorStatusBarSegment> statusSegments = {};
UIEditorViewportInputBridgeConfig inputBridgeConfig = {};
UIEditorViewportShellVisualState visualState = {};
};
struct UIEditorViewportShellModel {
UIEditorViewportShellSpec spec = {};
Widgets::UIEditorViewportSlotFrame frame = {};
};
struct UIEditorViewportShellRequest {
Widgets::UIEditorViewportSlotLayout slotLayout = {};
::XCEngine::UI::UISize requestedViewportSize = {};
};
struct UIEditorViewportShellState {
UIEditorViewportInputBridgeState inputBridgeState = {};
};
struct UIEditorViewportShellFrame {
Widgets::UIEditorViewportSlotLayout slotLayout = {};
Widgets::UIEditorViewportSlotState slotState = {};
UIEditorViewportInputBridgeFrame inputFrame = {};
::XCEngine::UI::UISize requestedViewportSize = {};
};
UIEditorViewportShellRequest ResolveUIEditorViewportShellRequest(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorViewportShellSpec& spec,
const Widgets::UIEditorViewportSlotMetrics& metrics = {});
UIEditorViewportShellFrame UpdateUIEditorViewportShell(
UIEditorViewportShellState& state,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorViewportShellModel& model,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorViewportSlotMetrics& metrics = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,203 +0,0 @@
#pragma once
#include <XCEngine/UI/DrawData.h>
#include <XCEditor/Shell/UIEditorStatusBar.h>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor::Widgets {
inline constexpr std::size_t UIEditorViewportSlotInvalidIndex =
static_cast<std::size_t>(-1);
enum class UIEditorViewportSlotToolSlot : std::uint8_t {
Leading = 0,
Trailing
};
enum class UIEditorViewportSlotHitTargetKind : std::uint8_t {
None = 0,
TopBar,
Title,
ToolItem,
Surface,
BottomBar,
StatusSegment,
StatusSeparator
};
struct UIEditorViewportSlotFrame {
::XCEngine::UI::UITextureHandle texture = {};
::XCEngine::UI::UISize requestedSize = {};
::XCEngine::UI::UISize presentedSize = {};
bool hasTexture = false;
std::string statusText = {};
};
struct UIEditorViewportSlotChrome {
std::string_view title = {};
std::string_view subtitle = {};
bool showTopBar = true;
bool showBottomBar = true;
float topBarHeight = 24.0f;
float bottomBarHeight = 22.0f;
};
struct UIEditorViewportSlotToolItem {
std::string itemId = {};
std::string label = {};
UIEditorViewportSlotToolSlot slot = UIEditorViewportSlotToolSlot::Trailing;
bool enabled = true;
bool selected = false;
float desiredWidth = 0.0f;
};
struct UIEditorViewportSlotState {
bool focused = false;
bool surfaceHovered = false;
bool surfaceActive = false;
bool inputCaptured = false;
std::size_t hoveredToolIndex = UIEditorViewportSlotInvalidIndex;
std::size_t activeToolIndex = UIEditorViewportSlotInvalidIndex;
UIEditorStatusBarState statusBarState = {};
};
struct UIEditorViewportSlotMetrics {
float cornerRounding = 0.0f;
float outerBorderThickness = 1.0f;
float focusedBorderThickness = 1.0f;
float topBarPaddingX = 8.0f;
float topBarPaddingY = 4.0f;
float toolPaddingX = 8.0f;
float toolGap = 4.0f;
float toolCornerRounding = 2.0f;
float titleGap = 6.0f;
float titleInsetY = 5.0f;
float subtitleInsetY = 14.0f;
float estimatedGlyphWidth = 6.5f;
float surfaceInset = 0.0f;
float surfaceBorderThickness = 1.0f;
float focusedSurfaceBorderThickness = 1.0f;
};
struct UIEditorViewportSlotPalette {
::XCEngine::UI::UIColor frameColor =
::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f);
::XCEngine::UI::UIColor topBarColor =
::XCEngine::UI::UIColor(0.20f, 0.20f, 0.20f, 1.0f);
::XCEngine::UI::UIColor surfaceColor =
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
::XCEngine::UI::UIColor surfaceHoverOverlayColor =
::XCEngine::UI::UIColor(0.22f, 0.22f, 0.22f, 0.24f);
::XCEngine::UI::UIColor surfaceActiveOverlayColor =
::XCEngine::UI::UIColor(0.34f, 0.34f, 0.34f, 0.18f);
::XCEngine::UI::UIColor captureOverlayColor =
::XCEngine::UI::UIColor(0.70f, 0.70f, 0.70f, 0.10f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.23f, 0.23f, 0.23f, 1.0f);
::XCEngine::UI::UIColor focusedBorderColor =
::XCEngine::UI::UIColor(0.36f, 0.36f, 0.36f, 1.0f);
::XCEngine::UI::UIColor surfaceBorderColor =
::XCEngine::UI::UIColor(0.22f, 0.22f, 0.22f, 1.0f);
::XCEngine::UI::UIColor surfaceHoveredBorderColor =
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
::XCEngine::UI::UIColor surfaceActiveBorderColor =
::XCEngine::UI::UIColor(0.33f, 0.33f, 0.33f, 1.0f);
::XCEngine::UI::UIColor surfaceCapturedBorderColor =
::XCEngine::UI::UIColor(0.38f, 0.38f, 0.38f, 1.0f);
::XCEngine::UI::UIColor toolColor =
::XCEngine::UI::UIColor(0.21f, 0.21f, 0.21f, 1.0f);
::XCEngine::UI::UIColor toolHoveredColor =
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
::XCEngine::UI::UIColor toolSelectedColor =
::XCEngine::UI::UIColor(0.27f, 0.27f, 0.27f, 1.0f);
::XCEngine::UI::UIColor toolDisabledColor =
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
::XCEngine::UI::UIColor toolBorderColor =
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
::XCEngine::UI::UIColor textPrimary =
::XCEngine::UI::UIColor(0.86f, 0.86f, 0.86f, 1.0f);
::XCEngine::UI::UIColor textSecondary =
::XCEngine::UI::UIColor(0.68f, 0.68f, 0.68f, 1.0f);
::XCEngine::UI::UIColor textMuted =
::XCEngine::UI::UIColor(0.58f, 0.58f, 0.58f, 1.0f);
::XCEngine::UI::UIColor imageTint =
::XCEngine::UI::UIColor(1.0f, 1.0f, 1.0f, 1.0f);
UIEditorStatusBarPalette statusBarPalette = {};
};
struct UIEditorViewportSlotLayout {
::XCEngine::UI::UIRect bounds = {};
::XCEngine::UI::UIRect topBarRect = {};
::XCEngine::UI::UIRect titleRect = {};
::XCEngine::UI::UIRect subtitleRect = {};
::XCEngine::UI::UIRect toolbarLeadingRect = {};
::XCEngine::UI::UIRect toolbarTrailingRect = {};
::XCEngine::UI::UIRect surfaceRect = {};
::XCEngine::UI::UIRect textureRect = {};
::XCEngine::UI::UIRect inputRect = {};
::XCEngine::UI::UIRect bottomBarRect = {};
std::vector<::XCEngine::UI::UIRect> toolItemRects = {};
UIEditorStatusBarLayout statusBarLayout = {};
::XCEngine::UI::UISize requestedSurfaceSize = {};
bool hasTopBar = false;
bool hasBottomBar = false;
};
struct UIEditorViewportSlotHitTarget {
UIEditorViewportSlotHitTargetKind kind = UIEditorViewportSlotHitTargetKind::None;
std::size_t index = UIEditorViewportSlotInvalidIndex;
};
float ResolveUIEditorViewportSlotDesiredToolWidth(
const UIEditorViewportSlotToolItem& item,
const UIEditorViewportSlotMetrics& metrics = {});
UIEditorViewportSlotLayout BuildUIEditorViewportSlotLayout(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorViewportSlotChrome& chrome,
const UIEditorViewportSlotFrame& frame,
const std::vector<UIEditorViewportSlotToolItem>& toolItems,
const std::vector<UIEditorStatusBarSegment>& statusSegments,
const UIEditorViewportSlotMetrics& metrics = {});
UIEditorViewportSlotHitTarget HitTestUIEditorViewportSlot(
const UIEditorViewportSlotLayout& layout,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorViewportSlotBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorViewportSlotLayout& layout,
const std::vector<UIEditorViewportSlotToolItem>& toolItems,
const std::vector<UIEditorStatusBarSegment>& statusSegments,
const UIEditorViewportSlotState& state,
const UIEditorViewportSlotPalette& palette = {},
const UIEditorViewportSlotMetrics& metrics = {});
void AppendUIEditorViewportSlotForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorViewportSlotLayout& layout,
const UIEditorViewportSlotChrome& chrome,
const UIEditorViewportSlotFrame& frame,
const std::vector<UIEditorViewportSlotToolItem>& toolItems,
const std::vector<UIEditorStatusBarSegment>& statusSegments,
const UIEditorViewportSlotState& state,
const UIEditorViewportSlotPalette& palette = {},
const UIEditorViewportSlotMetrics& metrics = {});
void AppendUIEditorViewportSlot(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorViewportSlotChrome& chrome,
const UIEditorViewportSlotFrame& frame,
const std::vector<UIEditorViewportSlotToolItem>& toolItems,
const std::vector<UIEditorStatusBarSegment>& statusSegments,
const UIEditorViewportSlotState& state,
const UIEditorViewportSlotPalette& palette = {},
const UIEditorViewportSlotMetrics& metrics = {});
} // namespace XCEngine::UI::Editor::Widgets

View File

@@ -1,91 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorWindowWorkspaceModel.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorWindowWorkspaceOperationStatus : std::uint8_t {
Changed = 0,
NoOp,
Rejected
};
struct UIEditorWindowWorkspaceOperationResult {
UIEditorWindowWorkspaceOperationStatus status =
UIEditorWindowWorkspaceOperationStatus::Rejected;
std::string message = {};
std::string sourceWindowId = {};
std::string targetWindowId = {};
std::string panelId = {};
std::string activeWindowId = {};
std::vector<std::string> windowIds = {};
};
std::string_view GetUIEditorWindowWorkspaceOperationStatusName(
UIEditorWindowWorkspaceOperationStatus status);
class UIEditorWindowWorkspaceController {
public:
UIEditorWindowWorkspaceController() = default;
UIEditorWindowWorkspaceController(
UIEditorPanelRegistry panelRegistry,
UIEditorWindowWorkspaceSet windowSet);
const UIEditorPanelRegistry& GetPanelRegistry() const {
return m_panelRegistry;
}
const UIEditorWindowWorkspaceSet& GetWindowSet() const {
return m_windowSet;
}
UIEditorWindowWorkspaceValidationResult ValidateState() const;
UIEditorWindowWorkspaceOperationResult DetachPanelToNewWindow(
std::string_view sourceWindowId,
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view preferredNewWindowId = {});
UIEditorWindowWorkspaceOperationResult MovePanelToStack(
std::string_view sourceWindowId,
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetWindowId,
std::string_view targetNodeId,
std::size_t targetVisibleInsertionIndex);
UIEditorWindowWorkspaceOperationResult DockPanelRelative(
std::string_view sourceWindowId,
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetWindowId,
std::string_view targetNodeId,
UIEditorWorkspaceDockPlacement placement,
float splitRatio = 0.5f);
private:
UIEditorWindowWorkspaceOperationResult BuildOperationResult(
UIEditorWindowWorkspaceOperationStatus status,
std::string message,
std::string_view sourceWindowId,
std::string_view targetWindowId,
std::string_view panelId) const;
std::string MakeUniqueWindowId(std::string_view base) const;
UIEditorPanelRegistry m_panelRegistry = {};
UIEditorWindowWorkspaceSet m_windowSet = {};
};
UIEditorWindowWorkspaceController BuildDefaultUIEditorWindowWorkspaceController(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
std::string primaryWindowId = "main-window");
} // namespace XCEngine::UI::Editor

View File

@@ -1,62 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorWindowWorkspaceState {
std::string windowId = {};
UIEditorWorkspaceModel workspace = {};
UIEditorWorkspaceSession session = {};
};
struct UIEditorWindowWorkspaceSet {
std::string primaryWindowId = {};
std::string activeWindowId = {};
std::vector<UIEditorWindowWorkspaceState> windows = {};
};
enum class UIEditorWindowWorkspaceValidationCode : std::uint8_t {
None = 0,
InvalidPanelRegistry,
EmptyWindowId,
DuplicateWindowId,
MissingPrimaryWindow,
MissingActiveWindow,
InvalidWorkspace,
InvalidSession
};
struct UIEditorWindowWorkspaceValidationResult {
UIEditorWindowWorkspaceValidationCode code = UIEditorWindowWorkspaceValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorWindowWorkspaceValidationCode::None;
}
};
UIEditorWindowWorkspaceSet BuildDefaultUIEditorWindowWorkspaceSet(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
std::string primaryWindowId = "main-window");
const UIEditorWindowWorkspaceState* FindUIEditorWindowWorkspaceState(
const UIEditorWindowWorkspaceSet& windowSet,
std::string_view windowId);
UIEditorWindowWorkspaceState* FindMutableUIEditorWindowWorkspaceState(
UIEditorWindowWorkspaceSet& windowSet,
std::string_view windowId);
UIEditorWindowWorkspaceValidationResult ValidateUIEditorWindowWorkspaceSet(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWindowWorkspaceSet& windowSet);
} // namespace XCEngine::UI::Editor

View File

@@ -1,107 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelContentHost.h>
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorViewportShell.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <XCEditor/Shell/UIEditorDockHost.h>
#include <XCEngine/UI/DrawData.h>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspacePanelPresentationModel {
std::string panelId = {};
UIEditorPanelPresentationKind kind = UIEditorPanelPresentationKind::Placeholder;
UIEditorViewportShellModel viewportShellModel = {};
};
struct UIEditorWorkspacePanelPresentationState {
std::string panelId = {};
UIEditorViewportShellState viewportShellState = {};
};
struct UIEditorWorkspaceComposeState {
UIEditorPanelContentHostState contentHostState = {};
std::vector<UIEditorWorkspacePanelPresentationState> panelStates = {};
};
struct UIEditorWorkspaceViewportComposeRequest {
std::string panelId = {};
::XCEngine::UI::UIRect bounds = {};
UIEditorViewportShellRequest viewportShellRequest = {};
};
struct UIEditorWorkspaceComposeRequest {
Widgets::UIEditorDockHostLayout dockHostLayout = {};
UIEditorPanelContentHostRequest contentHostRequest = {};
std::vector<UIEditorWorkspaceViewportComposeRequest> viewportRequests = {};
};
struct UIEditorWorkspaceViewportComposeFrame {
std::string panelId = {};
::XCEngine::UI::UIRect bounds = {};
UIEditorViewportShellModel viewportShellModel = {};
UIEditorViewportShellFrame viewportShellFrame = {};
};
struct UIEditorWorkspaceComposeFrame {
Widgets::UIEditorDockHostLayout dockHostLayout = {};
UIEditorPanelContentHostFrame contentHostFrame = {};
std::vector<UIEditorWorkspaceViewportComposeFrame> viewportFrames = {};
};
const UIEditorWorkspacePanelPresentationModel* FindUIEditorWorkspacePanelPresentationModel(
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
std::string_view panelId);
const UIEditorWorkspacePanelPresentationState* FindUIEditorWorkspacePanelPresentationState(
const UIEditorWorkspaceComposeState& state,
std::string_view panelId);
const UIEditorWorkspaceViewportComposeRequest* FindUIEditorWorkspaceViewportPresentationRequest(
const UIEditorWorkspaceComposeRequest& request,
std::string_view panelId);
const UIEditorWorkspaceViewportComposeFrame* FindUIEditorWorkspaceViewportPresentationFrame(
const UIEditorWorkspaceComposeFrame& frame,
std::string_view panelId);
UIEditorWorkspaceComposeRequest ResolveUIEditorWorkspaceComposeRequest(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
const Widgets::UIEditorDockHostState& dockHostState = {},
const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {},
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {});
UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose(
UIEditorWorkspaceComposeState& state,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostState& dockHostState = {},
const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {},
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {});
std::vector<std::string> CollectUIEditorWorkspaceComposeExternalBodyPanelIds(
const UIEditorWorkspaceComposeFrame& frame);
void AppendUIEditorWorkspaceCompose(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorWorkspaceComposeFrame& frame,
const Widgets::UIEditorDockHostPalette& dockHostPalette = {},
const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {},
const Widgets::UIEditorViewportSlotPalette& viewportPalette = {},
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,156 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorWorkspaceLayoutPersistence.h>
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorWorkspaceCommandKind : std::uint8_t {
OpenPanel = 0,
ClosePanel,
ShowPanel,
HidePanel,
ActivatePanel,
ResetWorkspace
};
enum class UIEditorWorkspaceCommandStatus : std::uint8_t {
Changed = 0,
NoOp,
Rejected
};
struct UIEditorWorkspaceCommand {
UIEditorWorkspaceCommandKind kind = UIEditorWorkspaceCommandKind::ActivatePanel;
std::string panelId = {};
};
struct UIEditorWorkspaceCommandResult {
UIEditorWorkspaceCommandKind kind = UIEditorWorkspaceCommandKind::ActivatePanel;
UIEditorWorkspaceCommandStatus status = UIEditorWorkspaceCommandStatus::Rejected;
std::string panelId = {};
std::string message = {};
std::string activePanelId = {};
std::vector<std::string> visiblePanelIds = {};
};
enum class UIEditorWorkspaceControllerValidationCode : std::uint8_t {
None = 0,
InvalidPanelRegistry,
InvalidWorkspace,
InvalidWorkspaceSession
};
struct UIEditorWorkspaceControllerValidationResult {
UIEditorWorkspaceControllerValidationCode code =
UIEditorWorkspaceControllerValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorWorkspaceControllerValidationCode::None;
}
};
std::string_view GetUIEditorWorkspaceCommandKindName(UIEditorWorkspaceCommandKind kind);
std::string_view GetUIEditorWorkspaceCommandStatusName(UIEditorWorkspaceCommandStatus status);
enum class UIEditorWorkspaceLayoutOperationStatus : std::uint8_t {
Changed = 0,
NoOp,
Rejected
};
struct UIEditorWorkspaceLayoutOperationResult {
UIEditorWorkspaceLayoutOperationStatus status =
UIEditorWorkspaceLayoutOperationStatus::Rejected;
std::string message = {};
std::string activePanelId = {};
std::vector<std::string> visiblePanelIds = {};
};
std::string_view GetUIEditorWorkspaceLayoutOperationStatusName(
UIEditorWorkspaceLayoutOperationStatus status);
class UIEditorWorkspaceController {
public:
UIEditorWorkspaceController() = default;
UIEditorWorkspaceController(
UIEditorPanelRegistry panelRegistry,
UIEditorWorkspaceModel workspace,
UIEditorWorkspaceSession session);
const UIEditorPanelRegistry& GetPanelRegistry() const {
return m_panelRegistry;
}
const UIEditorWorkspaceModel& GetWorkspace() const {
return m_workspace;
}
const UIEditorWorkspaceSession& GetSession() const {
return m_session;
}
UIEditorWorkspaceControllerValidationResult ValidateState() const;
UIEditorWorkspaceLayoutSnapshot CaptureLayoutSnapshot() const;
UIEditorWorkspaceLayoutOperationResult RestoreLayoutSnapshot(
const UIEditorWorkspaceLayoutSnapshot& snapshot);
UIEditorWorkspaceLayoutOperationResult RestoreSerializedLayout(
std::string_view serializedLayout);
UIEditorWorkspaceLayoutOperationResult SetSplitRatio(
std::string_view nodeId,
float splitRatio);
UIEditorWorkspaceLayoutOperationResult ReorderTab(
std::string_view nodeId,
std::string_view panelId,
std::size_t targetVisibleInsertionIndex);
UIEditorWorkspaceLayoutOperationResult MoveTabToStack(
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetNodeId,
std::size_t targetVisibleInsertionIndex);
UIEditorWorkspaceLayoutOperationResult DockTabRelative(
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetNodeId,
UIEditorWorkspaceDockPlacement placement,
float splitRatio = 0.5f);
UIEditorWorkspaceCommandResult Dispatch(const UIEditorWorkspaceCommand& command);
private:
UIEditorWorkspaceCommandResult BuildResult(
const UIEditorWorkspaceCommand& command,
UIEditorWorkspaceCommandStatus status,
std::string message) const;
UIEditorWorkspaceCommandResult FinalizeMutation(
const UIEditorWorkspaceCommand& command,
bool changed,
std::string changedMessage,
std::string unexpectedFailureMessage,
const UIEditorWorkspaceModel& previousWorkspace,
const UIEditorWorkspaceSession& previousSession);
UIEditorWorkspaceLayoutOperationResult BuildLayoutOperationResult(
UIEditorWorkspaceLayoutOperationStatus status,
std::string message) const;
const UIEditorPanelDescriptor* FindPanelDescriptor(std::string_view panelId) const;
UIEditorPanelRegistry m_panelRegistry = {};
UIEditorWorkspaceModel m_baselineWorkspace = {};
UIEditorWorkspaceSession m_baselineSession = {};
UIEditorWorkspaceModel m_workspace = {};
UIEditorWorkspaceSession m_session = {};
};
UIEditorWorkspaceController BuildDefaultUIEditorWorkspaceController(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace);
} // namespace XCEngine::UI::Editor

View File

@@ -1,47 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorDockHostInteraction.h>
#include <XCEditor/Shell/UIEditorWorkspaceCompose.h>
#include <XCEngine/UI/Types.h>
#include <string>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspaceInteractionModel {
std::vector<UIEditorWorkspacePanelPresentationModel> workspacePresentations = {};
};
struct UIEditorWorkspaceInteractionState {
UIEditorDockHostInteractionState dockHostInteractionState = {};
UIEditorWorkspaceComposeState composeState = {};
};
struct UIEditorWorkspaceInteractionResult {
bool consumed = false;
bool requestPointerCapture = false;
bool releasePointerCapture = false;
bool viewportInteractionChanged = false;
std::string viewportPanelId = {};
UIEditorViewportInputBridgeFrame viewportInputFrame = {};
UIEditorDockHostInteractionResult dockHostResult = {};
};
struct UIEditorWorkspaceInteractionFrame {
UIEditorDockHostInteractionFrame dockHostFrame = {};
UIEditorWorkspaceComposeFrame composeFrame = {};
UIEditorWorkspaceInteractionResult result = {};
};
UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
UIEditorWorkspaceInteractionState& state,
UIEditorWorkspaceController& controller,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorWorkspaceInteractionModel& model,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {},
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics = {});
} // namespace XCEngine::UI::Editor

View File

@@ -1,55 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
#include <cstdint>
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspaceLayoutSnapshot {
UIEditorWorkspaceModel workspace = {};
UIEditorWorkspaceSession session = {};
};
enum class UIEditorWorkspaceLayoutLoadCode : std::uint8_t {
None = 0,
InvalidPanelRegistry,
EmptyInput,
InvalidHeader,
UnsupportedVersion,
MissingActiveRecord,
UnexpectedEndOfInput,
InvalidNodeRecord,
InvalidSessionRecord,
InvalidWorkspace,
InvalidWorkspaceSession
};
struct UIEditorWorkspaceLayoutLoadResult {
UIEditorWorkspaceLayoutLoadCode code = UIEditorWorkspaceLayoutLoadCode::None;
std::string message = {};
UIEditorWorkspaceLayoutSnapshot snapshot = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorWorkspaceLayoutLoadCode::None;
}
};
UIEditorWorkspaceLayoutSnapshot BuildUIEditorWorkspaceLayoutSnapshot(
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session);
bool AreUIEditorWorkspaceLayoutSnapshotsEquivalent(
const UIEditorWorkspaceLayoutSnapshot& lhs,
const UIEditorWorkspaceLayoutSnapshot& rhs);
std::string SerializeUIEditorWorkspaceLayoutSnapshot(
const UIEditorWorkspaceLayoutSnapshot& snapshot);
UIEditorWorkspaceLayoutLoadResult DeserializeUIEditorWorkspaceLayoutSnapshot(
const UIEditorPanelRegistry& panelRegistry,
std::string_view serializedLayout);
} // namespace XCEngine::UI::Editor

View File

@@ -1,192 +0,0 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspaceSession;
enum class UIEditorWorkspaceNodeKind : std::uint8_t {
Panel = 0,
TabStack,
Split
};
enum class UIEditorWorkspaceSplitAxis : std::uint8_t {
Horizontal = 0,
Vertical
};
enum class UIEditorWorkspaceDockPlacement : std::uint8_t {
Center = 0,
Left,
Right,
Top,
Bottom
};
struct UIEditorWorkspacePanelState {
std::string panelId = {};
std::string title = {};
bool placeholder = false;
};
struct UIEditorWorkspaceNode {
UIEditorWorkspaceNodeKind kind = UIEditorWorkspaceNodeKind::Panel;
std::string nodeId = {};
UIEditorWorkspaceSplitAxis splitAxis = UIEditorWorkspaceSplitAxis::Horizontal;
float splitRatio = 0.5f;
std::size_t selectedTabIndex = 0u;
UIEditorWorkspacePanelState panel = {};
std::vector<UIEditorWorkspaceNode> children = {};
};
struct UIEditorWorkspaceModel {
UIEditorWorkspaceNode root = {};
std::string activePanelId = {};
};
enum class UIEditorWorkspaceValidationCode : std::uint8_t {
None = 0,
EmptyNodeId,
InvalidSplitChildCount,
InvalidSplitRatio,
EmptyTabStack,
InvalidSelectedTabIndex,
NonPanelTabChild,
EmptyPanelId,
EmptyPanelTitle,
DuplicatePanelId,
InvalidActivePanelId
};
struct UIEditorWorkspaceValidationResult {
UIEditorWorkspaceValidationCode code = UIEditorWorkspaceValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorWorkspaceValidationCode::None;
}
};
struct UIEditorWorkspaceVisiblePanel {
std::string panelId = {};
std::string title = {};
bool active = false;
bool placeholder = false;
};
UIEditorWorkspaceModel BuildDefaultEditorShellWorkspaceModel();
UIEditorWorkspaceNode BuildUIEditorWorkspacePanel(
std::string nodeId,
std::string panelId,
std::string title,
bool placeholder = false);
UIEditorWorkspaceNode BuildUIEditorWorkspaceSingleTabStack(
std::string nodeId,
std::string panelId,
std::string title,
bool placeholder = false);
UIEditorWorkspaceNode BuildUIEditorWorkspaceTabStack(
std::string nodeId,
std::vector<UIEditorWorkspaceNode> panels,
std::size_t selectedTabIndex = 0u);
UIEditorWorkspaceNode BuildUIEditorWorkspaceSplit(
std::string nodeId,
UIEditorWorkspaceSplitAxis axis,
float splitRatio,
UIEditorWorkspaceNode primary,
UIEditorWorkspaceNode secondary);
UIEditorWorkspaceValidationResult ValidateUIEditorWorkspace(
const UIEditorWorkspaceModel& workspace);
UIEditorWorkspaceModel CanonicalizeUIEditorWorkspaceModel(
UIEditorWorkspaceModel workspace);
std::vector<UIEditorWorkspaceVisiblePanel> CollectUIEditorWorkspaceVisiblePanels(
const UIEditorWorkspaceModel& workspace);
bool ContainsUIEditorWorkspacePanel(
const UIEditorWorkspaceModel& workspace,
std::string_view panelId);
const UIEditorWorkspaceNode* FindUIEditorWorkspaceNode(
const UIEditorWorkspaceModel& workspace,
std::string_view nodeId);
bool AreUIEditorWorkspaceNodesEquivalent(
const UIEditorWorkspaceNode& lhs,
const UIEditorWorkspaceNode& rhs);
bool AreUIEditorWorkspaceModelsEquivalent(
const UIEditorWorkspaceModel& lhs,
const UIEditorWorkspaceModel& rhs);
const UIEditorWorkspacePanelState* FindUIEditorWorkspaceActivePanel(
const UIEditorWorkspaceModel& workspace);
bool TryActivateUIEditorWorkspacePanel(
UIEditorWorkspaceModel& workspace,
std::string_view panelId);
bool TrySetUIEditorWorkspaceSplitRatio(
UIEditorWorkspaceModel& workspace,
std::string_view nodeId,
float splitRatio);
bool TryReorderUIEditorWorkspaceTab(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
std::string_view nodeId,
std::string_view panelId,
std::size_t targetVisibleInsertionIndex);
bool TryExtractUIEditorWorkspaceVisiblePanelNode(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
std::string_view sourceNodeId,
std::string_view panelId,
UIEditorWorkspaceNode& extractedPanel);
bool TryInsertUIEditorWorkspacePanelNodeToStack(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
UIEditorWorkspaceNode panelNode,
std::string_view targetNodeId,
std::size_t targetVisibleInsertionIndex);
bool TryDockUIEditorWorkspacePanelNodeRelative(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
UIEditorWorkspaceNode panelNode,
std::string_view targetNodeId,
UIEditorWorkspaceDockPlacement placement,
float splitRatio = 0.5f);
bool TryMoveUIEditorWorkspaceTabToStack(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetNodeId,
std::size_t targetVisibleInsertionIndex);
bool TryDockUIEditorWorkspaceTabRelative(
UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
std::string_view sourceNodeId,
std::string_view panelId,
std::string_view targetNodeId,
UIEditorWorkspaceDockPlacement placement,
float splitRatio = 0.5f);
} // namespace XCEngine::UI::Editor

View File

@@ -1,98 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorPanelRegistry.h>
#include <XCEditor/Shell/UIEditorWorkspaceModel.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorPanelSessionState {
std::string panelId = {};
bool open = true;
bool visible = true;
};
struct UIEditorWorkspaceSession {
std::vector<UIEditorPanelSessionState> panelStates = {};
};
enum class UIEditorWorkspaceSessionValidationCode : std::uint8_t {
None = 0,
MissingPanelState,
UnknownPanelId,
DuplicatePanelId,
ClosedPanelVisible,
NonHideablePanelHidden,
NonCloseablePanelClosed,
InvalidActivePanelId
};
struct UIEditorWorkspaceSessionValidationResult {
UIEditorWorkspaceSessionValidationCode code = UIEditorWorkspaceSessionValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorWorkspaceSessionValidationCode::None;
}
};
UIEditorWorkspaceSession BuildDefaultUIEditorWorkspaceSession(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace);
const UIEditorPanelSessionState* FindUIEditorPanelSessionState(
const UIEditorWorkspaceSession& session,
std::string_view panelId);
UIEditorWorkspaceSessionValidationResult ValidateUIEditorWorkspaceSession(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session);
bool AreUIEditorWorkspaceSessionsEquivalent(
const UIEditorWorkspaceSession& lhs,
const UIEditorWorkspaceSession& rhs);
std::vector<UIEditorWorkspaceVisiblePanel> CollectUIEditorWorkspaceVisiblePanels(
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session);
const UIEditorWorkspacePanelState* FindUIEditorWorkspaceActivePanel(
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session);
bool TryOpenUIEditorWorkspacePanel(
const UIEditorPanelRegistry& panelRegistry,
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view panelId);
bool TryCloseUIEditorWorkspacePanel(
const UIEditorPanelRegistry& panelRegistry,
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view panelId);
bool TryShowUIEditorWorkspacePanel(
const UIEditorPanelRegistry& panelRegistry,
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view panelId);
bool TryHideUIEditorWorkspacePanel(
const UIEditorPanelRegistry& panelRegistry,
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view panelId);
bool TryActivateUIEditorWorkspacePanel(
const UIEditorPanelRegistry& panelRegistry,
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view panelId);
} // namespace XCEngine::UI::Editor

View File

@@ -1,41 +0,0 @@
#pragma once
#include <XCEditor/Shell/UIEditorWorkspaceSession.h>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspaceExtractedPanel {
UIEditorWorkspaceNode panelNode = {};
UIEditorPanelSessionState sessionState = {};
};
bool TryExtractUIEditorWorkspaceVisiblePanel(
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
std::string_view sourceNodeId,
std::string_view panelId,
UIEditorWorkspaceExtractedPanel& extractedPanel);
UIEditorWorkspaceModel BuildUIEditorDetachedWorkspaceFromExtractedPanel(
std::string rootNodeId,
UIEditorWorkspaceExtractedPanel extractedPanel);
UIEditorWorkspaceSession BuildUIEditorDetachedWorkspaceSessionFromExtractedPanel(
UIEditorWorkspaceExtractedPanel extractedPanel);
bool TryInsertExtractedUIEditorWorkspacePanelToStack(
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
UIEditorWorkspaceExtractedPanel extractedPanel,
std::string_view targetNodeId,
std::size_t targetVisibleInsertionIndex);
bool TryDockExtractedUIEditorWorkspacePanelRelative(
UIEditorWorkspaceModel& workspace,
UIEditorWorkspaceSession& session,
UIEditorWorkspaceExtractedPanel extractedPanel,
std::string_view targetNodeId,
UIEditorWorkspaceDockPlacement placement,
float splitRatio = 0.5f);
} // namespace XCEngine::UI::Editor