Refine XCEditor docking and DPI rendering
This commit is contained in:
@@ -22,11 +22,21 @@ struct UIEditorTabStripItem {
|
||||
float desiredHeaderLabelWidth = 0.0f;
|
||||
};
|
||||
|
||||
struct UIEditorTabStripReorderState {
|
||||
::XCEngine::UI::UIPoint pressPosition = {};
|
||||
std::size_t pressedIndex = UIEditorTabStripInvalidIndex;
|
||||
std::size_t sourceIndex = UIEditorTabStripInvalidIndex;
|
||||
std::size_t previewInsertionIndex = UIEditorTabStripInvalidIndex;
|
||||
bool armed = false;
|
||||
bool dragging = false;
|
||||
};
|
||||
|
||||
struct UIEditorTabStripState {
|
||||
std::size_t selectedIndex = UIEditorTabStripInvalidIndex;
|
||||
std::size_t hoveredIndex = UIEditorTabStripInvalidIndex;
|
||||
std::size_t closeHoveredIndex = UIEditorTabStripInvalidIndex;
|
||||
bool focused = false;
|
||||
UIEditorTabStripReorderState reorder = {};
|
||||
};
|
||||
|
||||
struct UIEditorTabStripMetrics {
|
||||
@@ -38,21 +48,26 @@ struct UIEditorTabStripMetrics {
|
||||
float closeInsetRight = 6.0f;
|
||||
float closeInsetY = 0.0f;
|
||||
float labelInsetX = 8.0f;
|
||||
float labelInsetY = -2.5f;
|
||||
float labelInsetY = -0.5f;
|
||||
float baseBorderThickness = 1.0f;
|
||||
float selectedBorderThickness = 1.0f;
|
||||
float focusedBorderThickness = 1.0f;
|
||||
float reorderDragThreshold = 6.0f;
|
||||
float reorderPreviewThickness = 2.0f;
|
||||
float reorderPreviewInsetY = 3.0f;
|
||||
};
|
||||
|
||||
struct UIEditorTabStripPalette {
|
||||
::XCEngine::UI::UIColor stripBackgroundColor =
|
||||
::XCEngine::UI::UIColor(0.16f, 0.16f, 0.16f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
|
||||
::XCEngine::UI::UIColor headerBackgroundColor =
|
||||
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
|
||||
::XCEngine::UI::UIColor contentBackgroundColor =
|
||||
::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
|
||||
::XCEngine::UI::UIColor stripBorderColor =
|
||||
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
|
||||
::XCEngine::UI::UIColor headerContentSeparatorColor =
|
||||
::XCEngine::UI::UIColor(0.27f, 0.27f, 0.27f, 1.0f);
|
||||
::XCEngine::UI::UIColor focusedBorderColor =
|
||||
::XCEngine::UI::UIColor(0.36f, 0.36f, 0.36f, 1.0f);
|
||||
::XCEngine::UI::UIColor tabColor =
|
||||
@@ -60,7 +75,7 @@ struct UIEditorTabStripPalette {
|
||||
::XCEngine::UI::UIColor tabHoveredColor =
|
||||
::XCEngine::UI::UIColor(0.23f, 0.23f, 0.23f, 1.0f);
|
||||
::XCEngine::UI::UIColor tabSelectedColor =
|
||||
::XCEngine::UI::UIColor(0.22f, 0.22f, 0.22f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
|
||||
::XCEngine::UI::UIColor tabBorderColor =
|
||||
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
|
||||
::XCEngine::UI::UIColor tabHoveredBorderColor =
|
||||
@@ -81,6 +96,14 @@ struct UIEditorTabStripPalette {
|
||||
::XCEngine::UI::UIColor(0.30f, 0.30f, 0.30f, 1.0f);
|
||||
::XCEngine::UI::UIColor closeGlyphColor =
|
||||
::XCEngine::UI::UIColor(0.83f, 0.83f, 0.83f, 1.0f);
|
||||
::XCEngine::UI::UIColor reorderPreviewColor =
|
||||
::XCEngine::UI::UIColor(0.82f, 0.82f, 0.82f, 1.0f);
|
||||
};
|
||||
|
||||
struct UIEditorTabStripInsertionPreview {
|
||||
bool visible = false;
|
||||
std::size_t insertionIndex = UIEditorTabStripInvalidIndex;
|
||||
::XCEngine::UI::UIRect indicatorRect = {};
|
||||
};
|
||||
|
||||
struct UIEditorTabStripLayout {
|
||||
@@ -91,6 +114,7 @@ struct UIEditorTabStripLayout {
|
||||
std::vector<::XCEngine::UI::UIRect> closeButtonRects = {};
|
||||
std::vector<bool> showCloseButtons = {};
|
||||
std::size_t selectedIndex = UIEditorTabStripInvalidIndex;
|
||||
UIEditorTabStripInsertionPreview insertionPreview = {};
|
||||
};
|
||||
|
||||
enum class UIEditorTabStripHitTargetKind : std::uint8_t {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <XCEditor/Collections/UIEditorTabStrip.h>
|
||||
|
||||
#include <XCEngine/UI/DrawData.h>
|
||||
#include <XCEngine/UI/Widgets/UIDragDropInteraction.h>
|
||||
#include <XCEngine/UI/Widgets/UITabStripModel.h>
|
||||
|
||||
#include <string>
|
||||
@@ -13,9 +14,13 @@ namespace XCEngine::UI::Editor {
|
||||
struct UIEditorTabStripInteractionState {
|
||||
Widgets::UIEditorTabStripState tabStripState = {};
|
||||
::XCEngine::UI::Widgets::UITabStripModel navigationModel = {};
|
||||
::XCEngine::UI::Widgets::UIDragDropState reorderDragState = {};
|
||||
Widgets::UIEditorTabStripHitTarget pressedTarget = {};
|
||||
::XCEngine::UI::UIPoint pointerPosition = {};
|
||||
std::size_t reorderSourceIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::size_t reorderPreviewIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
bool hasPointerPosition = false;
|
||||
bool reorderCaptureActive = false;
|
||||
};
|
||||
|
||||
struct UIEditorTabStripInteractionResult {
|
||||
@@ -23,11 +28,23 @@ struct UIEditorTabStripInteractionResult {
|
||||
bool selectionChanged = false;
|
||||
bool closeRequested = false;
|
||||
bool keyboardNavigated = false;
|
||||
bool requestPointerCapture = false;
|
||||
bool releasePointerCapture = false;
|
||||
bool dragStarted = false;
|
||||
bool dragEnded = false;
|
||||
bool dragCanceled = false;
|
||||
bool reorderRequested = false;
|
||||
bool reorderPreviewActive = false;
|
||||
Widgets::UIEditorTabStripHitTarget hitTarget = {};
|
||||
std::string selectedTabId = {};
|
||||
std::size_t selectedIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::string closedTabId = {};
|
||||
std::size_t closedIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::string draggedTabId = {};
|
||||
std::size_t dragSourceIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::size_t dropInsertionIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::size_t reorderToIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
std::size_t reorderPreviewIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
};
|
||||
|
||||
struct UIEditorTabStripInteractionFrame {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
void InitializeUIEditorRuntimeTrace(const std::filesystem::path& logRoot);
|
||||
void ShutdownUIEditorRuntimeTrace();
|
||||
|
||||
void AppendUIEditorRuntimeTrace(
|
||||
std::string_view channel,
|
||||
std::string_view message);
|
||||
|
||||
void AppendUIEditorCrashTrace(
|
||||
std::uint32_t exceptionCode,
|
||||
const void* exceptionAddress);
|
||||
|
||||
std::filesystem::path GetUIEditorRuntimeTracePath();
|
||||
std::filesystem::path GetUIEditorCrashTracePath();
|
||||
|
||||
} // namespace XCEngine::UI::Editor
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
struct UIEditorTextMeasureRequest {
|
||||
std::string_view text = {};
|
||||
float fontSize = 0.0f;
|
||||
};
|
||||
|
||||
class UIEditorTextMeasurer {
|
||||
public:
|
||||
virtual ~UIEditorTextMeasurer() = default;
|
||||
|
||||
virtual float MeasureTextWidth(const UIEditorTextMeasureRequest& request) const = 0;
|
||||
};
|
||||
|
||||
} // namespace XCEngine::UI::Editor
|
||||
@@ -40,16 +40,27 @@ struct UIEditorDockHostTabStripVisualState {
|
||||
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{ 4.0f, 12.0f };
|
||||
::XCEngine::UI::Layout::UISplitterMetrics{ 1.0f, 10.0f };
|
||||
UIEditorTabStripMetrics tabStripMetrics = {};
|
||||
UIEditorPanelFrameMetrics panelFrameMetrics = {};
|
||||
::XCEngine::UI::UISize minimumStandalonePanelBodySize =
|
||||
@@ -75,6 +86,10 @@ struct UIEditorDockHostPalette {
|
||||
::XCEngine::UI::UIColor(0.70f, 0.72f, 0.74f, 1.0f);
|
||||
::XCEngine::UI::UIColor placeholderMutedColor =
|
||||
::XCEngine::UI::UIColor(0.58f, 0.59f, 0.62f, 1.0f);
|
||||
::XCEngine::UI::UIColor dropPreviewFillColor =
|
||||
::XCEngine::UI::UIColor(0.88f, 0.88f, 0.88f, 0.14f);
|
||||
::XCEngine::UI::UIColor dropPreviewBorderColor =
|
||||
::XCEngine::UI::UIColor(0.94f, 0.94f, 0.94f, 0.78f);
|
||||
};
|
||||
|
||||
struct UIEditorDockHostTabItemLayout {
|
||||
@@ -107,10 +122,20 @@ struct UIEditorDockHostTabStackLayout {
|
||||
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 = {};
|
||||
};
|
||||
|
||||
// Allows higher-level compose to own panel body presentation while DockHost
|
||||
|
||||
@@ -21,6 +21,8 @@ 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;
|
||||
};
|
||||
|
||||
@@ -29,12 +29,13 @@ struct UIEditorMenuBarMetrics {
|
||||
float barHeight = 24.0f;
|
||||
float horizontalInset = 0.0f;
|
||||
float verticalInset = 2.0f;
|
||||
float buttonGap = 2.0f;
|
||||
float buttonPaddingX = 10.0f;
|
||||
float buttonGap = 1.0f;
|
||||
float buttonPaddingX = 4.0f;
|
||||
float labelFontSize = 13.0f;
|
||||
float estimatedGlyphWidth = 6.5f;
|
||||
float labelInsetY = -1.5f;
|
||||
float barCornerRounding = 0.0f;
|
||||
float buttonCornerRounding = 0.0f;
|
||||
float buttonCornerRounding = 0.75f;
|
||||
float baseBorderThickness = 1.0f;
|
||||
float focusedBorderThickness = 1.0f;
|
||||
float openBorderThickness = 1.0f;
|
||||
@@ -42,23 +43,23 @@ struct UIEditorMenuBarMetrics {
|
||||
|
||||
struct UIEditorMenuBarPalette {
|
||||
::XCEngine::UI::UIColor barColor =
|
||||
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
|
||||
::XCEngine::UI::UIColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
::XCEngine::UI::UIColor buttonColor =
|
||||
::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
::XCEngine::UI::UIColor buttonHoveredColor =
|
||||
::XCEngine::UI::UIColor(0.23f, 0.23f, 0.23f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.88f, 0.88f, 0.88f, 1.0f);
|
||||
::XCEngine::UI::UIColor buttonOpenColor =
|
||||
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
|
||||
::XCEngine::UI::UIColor borderColor =
|
||||
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
::XCEngine::UI::UIColor focusedBorderColor =
|
||||
::XCEngine::UI::UIColor(0.38f, 0.38f, 0.38f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
::XCEngine::UI::UIColor openBorderColor =
|
||||
::XCEngine::UI::UIColor(0.34f, 0.34f, 0.34f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
::XCEngine::UI::UIColor textPrimary =
|
||||
::XCEngine::UI::UIColor(0.85f, 0.85f, 0.85f, 1.0f);
|
||||
::XCEngine::UI::UIColor(0.08f, 0.08f, 0.08f, 1.0f);
|
||||
::XCEngine::UI::UIColor textMuted =
|
||||
::XCEngine::UI::UIColor(0.67f, 0.67f, 0.67f, 1.0f);
|
||||
::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);
|
||||
};
|
||||
|
||||
@@ -34,19 +34,19 @@ struct UIEditorMenuPopupState {
|
||||
};
|
||||
|
||||
struct UIEditorMenuPopupMetrics {
|
||||
float contentPaddingX = 6.0f;
|
||||
float contentPaddingX = 2.0f;
|
||||
float contentPaddingY = 6.0f;
|
||||
float itemHeight = 28.0f;
|
||||
float separatorHeight = 9.0f;
|
||||
float checkColumnWidth = 18.0f;
|
||||
float shortcutGap = 20.0f;
|
||||
float submenuIndicatorWidth = 14.0f;
|
||||
float rowCornerRounding = 5.0f;
|
||||
float popupCornerRounding = 8.0f;
|
||||
float labelInsetX = 14.0f;
|
||||
float checkColumnWidth = 12.0f;
|
||||
float shortcutGap = 14.0f;
|
||||
float submenuIndicatorWidth = 10.0f;
|
||||
float rowCornerRounding = 2.5f;
|
||||
float popupCornerRounding = 4.0f;
|
||||
float labelInsetX = 4.0f;
|
||||
float labelInsetY = -1.0f;
|
||||
float labelFontSize = 13.0f;
|
||||
float shortcutInsetRight = 24.0f;
|
||||
float shortcutInsetRight = 8.0f;
|
||||
float estimatedGlyphWidth = 7.0f;
|
||||
float glyphFontSize = 12.0f;
|
||||
float separatorThickness = 1.0f;
|
||||
|
||||
@@ -110,6 +110,12 @@ struct UIEditorShellComposeFrame {
|
||||
UIEditorWorkspaceComposeFrame workspaceFrame = {};
|
||||
};
|
||||
|
||||
UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
const ::XCEngine::UI::UIRect& bounds,
|
||||
const std::vector<Widgets::UIEditorMenuBarItem>& menuBarItems,
|
||||
const std::vector<Widgets::UIEditorStatusBarSegment>& statusSegments,
|
||||
const UIEditorShellComposeMetrics& metrics = {});
|
||||
|
||||
UIEditorShellComposeLayout BuildUIEditorShellComposeLayout(
|
||||
const ::XCEngine::UI::UIRect& bounds,
|
||||
const std::vector<Widgets::UIEditorMenuBarItem>& menuBarItems,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
|
||||
#include <XCEditor/Shell/UIEditorMenuModel.h>
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
#include <XCEditor/Shell/UIEditorShellCompose.h>
|
||||
@@ -50,6 +51,7 @@ struct UIEditorShellInteractionPalette {
|
||||
struct UIEditorShellInteractionServices {
|
||||
const UIEditorCommandDispatcher* commandDispatcher = nullptr;
|
||||
const UIEditorShortcutManager* shortcutManager = nullptr;
|
||||
const UIEditorTextMeasurer* textMeasurer = nullptr;
|
||||
};
|
||||
|
||||
struct UIEditorShellInteractionMenuButtonRequest {
|
||||
|
||||
@@ -105,6 +105,21 @@ public:
|
||||
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:
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
struct UIEditorWorkspaceSession;
|
||||
|
||||
enum class UIEditorWorkspaceNodeKind : std::uint8_t {
|
||||
Panel = 0,
|
||||
TabStack,
|
||||
@@ -19,6 +21,14 @@ enum class UIEditorWorkspaceSplitAxis : std::uint8_t {
|
||||
Vertical
|
||||
};
|
||||
|
||||
enum class UIEditorWorkspaceDockPlacement : std::uint8_t {
|
||||
Center = 0,
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom
|
||||
};
|
||||
|
||||
struct UIEditorWorkspacePanelState {
|
||||
std::string panelId = {};
|
||||
std::string title = {};
|
||||
@@ -133,4 +143,28 @@ bool TrySetUIEditorWorkspaceSplitRatio(
|
||||
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 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
|
||||
|
||||
Reference in New Issue
Block a user