关键节点

This commit is contained in:
2026-04-25 16:46:01 +08:00
parent 6002d86a7e
commit ef41c44464
516 changed files with 6175 additions and 12401 deletions

View File

@@ -0,0 +1,107 @@
#pragma once
#include <XCEditor/Foundation/UIEditorCommandRegistry.h>
#include <cstdint>
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor {
struct UIEditorHostCommandEvaluationResult {
bool executable = false;
std::string message = {};
};
struct UIEditorHostCommandDispatchResult {
bool commandExecuted = false;
std::string message = {};
};
class UIEditorHostCommandHandler {
public:
virtual ~UIEditorHostCommandHandler() = default;
virtual UIEditorHostCommandEvaluationResult EvaluateHostCommand(
std::string_view commandId) const = 0;
virtual UIEditorHostCommandDispatchResult DispatchHostCommand(
std::string_view commandId) = 0;
};
enum class UIEditorCommandEvaluationCode : std::uint8_t {
None = 0,
InvalidCommandRegistry,
UnknownCommandId,
MissingActivePanel,
MissingHostCommandHandler,
HostCommandDisabled
};
struct UIEditorCommandEvaluationResult {
UIEditorCommandEvaluationCode code = UIEditorCommandEvaluationCode::None;
bool executable = false;
std::string commandId = {};
std::string displayName = {};
UIEditorWorkspaceCommand workspaceCommand = {};
UIEditorWorkspaceCommandResult previewResult = {};
std::string message = {};
UIEditorCommandKind kind = UIEditorCommandKind::Workspace;
[[nodiscard]] bool IsExecutable() const {
return executable;
}
};
enum class UIEditorCommandDispatchStatus : std::uint8_t {
Dispatched = 0,
Rejected
};
struct UIEditorCommandDispatchResult {
UIEditorCommandDispatchStatus status = UIEditorCommandDispatchStatus::Rejected;
bool commandExecuted = false;
std::string commandId = {};
std::string displayName = {};
UIEditorWorkspaceCommand workspaceCommand = {};
UIEditorWorkspaceCommandResult commandResult = {};
std::string message = {};
UIEditorCommandKind kind = UIEditorCommandKind::Workspace;
};
std::string_view GetUIEditorCommandDispatchStatusName(
UIEditorCommandDispatchStatus status);
class UIEditorCommandDispatcher {
public:
UIEditorCommandDispatcher() = default;
explicit UIEditorCommandDispatcher(UIEditorCommandRegistry commandRegistry);
const UIEditorCommandRegistry& GetCommandRegistry() const {
return m_commandRegistry;
}
void SetHostCommandHandler(UIEditorHostCommandHandler* handler) {
m_hostCommandHandler = handler;
}
UIEditorHostCommandHandler* GetHostCommandHandler() const {
return m_hostCommandHandler;
}
UIEditorCommandRegistryValidationResult ValidateConfiguration() const;
UIEditorCommandEvaluationResult Evaluate(
std::string_view commandId,
const UIEditorWorkspaceController& controller) const;
UIEditorCommandDispatchResult Dispatch(
std::string_view commandId,
UIEditorWorkspaceController& controller) const;
private:
UIEditorCommandRegistry m_commandRegistry = {};
UIEditorHostCommandHandler* m_hostCommandHandler = nullptr;
};
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,70 @@
#pragma once
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor {
enum class UIEditorCommandKind : std::uint8_t {
Workspace = 0,
Host
};
enum class UIEditorCommandPanelSource : std::uint8_t {
None = 0,
FixedPanelId,
ActivePanel
};
struct UIEditorWorkspaceCommandDescriptor {
UIEditorWorkspaceCommandKind kind = UIEditorWorkspaceCommandKind::ActivatePanel;
UIEditorCommandPanelSource panelSource = UIEditorCommandPanelSource::FixedPanelId;
std::string panelId = {};
};
struct UIEditorCommandDescriptor {
std::string commandId = {};
std::string displayName = {};
UIEditorWorkspaceCommandDescriptor workspaceCommand = {};
UIEditorCommandKind kind = UIEditorCommandKind::Workspace;
};
struct UIEditorCommandRegistry {
std::vector<UIEditorCommandDescriptor> commands = {};
};
enum class UIEditorCommandRegistryValidationCode : std::uint8_t {
None = 0,
EmptyCommandId,
EmptyDisplayName,
DuplicateCommandId,
MissingPanelSource,
MissingFixedPanelId,
UnexpectedPanelSource
};
struct UIEditorCommandRegistryValidationResult {
UIEditorCommandRegistryValidationCode code =
UIEditorCommandRegistryValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorCommandRegistryValidationCode::None;
}
};
std::string_view GetUIEditorCommandPanelSourceName(UIEditorCommandPanelSource source);
std::string_view GetUIEditorCommandKindName(UIEditorCommandKind kind);
const UIEditorCommandDescriptor* FindUIEditorCommandDescriptor(
const UIEditorCommandRegistry& registry,
std::string_view commandId);
UIEditorCommandRegistryValidationResult ValidateUIEditorCommandRegistry(
const UIEditorCommandRegistry& registry);
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,121 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorPanelInputFilterOptions {
bool allowPointerInBounds = false;
bool allowPointerWhileCaptured = false;
bool allowKeyboardInput = false;
bool allowFocusEvents = false;
bool includePointerLeave = false;
};
inline ::XCEngine::UI::UIInputEvent BuildUIEditorPanelFocusEvent(
::XCEngine::UI::UIInputEventType type) {
::XCEngine::UI::UIInputEvent event = {};
event.type = type;
return event;
}
inline std::vector<::XCEngine::UI::UIInputEvent> FilterUIEditorPanelInputEvents(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const UIEditorPanelInputFilterOptions& options) {
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
if (!options.allowPointerInBounds &&
!options.allowPointerWhileCaptured &&
!options.allowKeyboardInput &&
!options.allowFocusEvents &&
!options.includePointerLeave) {
return {};
}
auto containsPoint = [&bounds](const ::XCEngine::UI::UIPoint& point) {
return point.x >= bounds.x &&
point.x <= bounds.x + bounds.width &&
point.y >= bounds.y &&
point.y <= bounds.y + bounds.height;
};
std::vector<UIInputEvent> filteredEvents = {};
filteredEvents.reserve(inputEvents.size());
for (const UIInputEvent& event : inputEvents) {
switch (event.type) {
case UIInputEventType::PointerMove:
case UIInputEventType::PointerButtonDown:
case UIInputEventType::PointerButtonUp:
case UIInputEventType::PointerWheel:
if (options.allowPointerWhileCaptured ||
(options.allowPointerInBounds && containsPoint(event.position))) {
filteredEvents.push_back(event);
}
break;
case UIInputEventType::PointerLeave:
if (options.includePointerLeave) {
filteredEvents.push_back(event);
}
break;
case UIInputEventType::FocusGained:
case UIInputEventType::FocusLost:
if (options.allowFocusEvents) {
filteredEvents.push_back(event);
}
break;
case UIInputEventType::KeyDown:
case UIInputEventType::KeyUp:
case UIInputEventType::Character:
if (options.allowKeyboardInput) {
filteredEvents.push_back(event);
}
break;
default:
break;
}
}
return filteredEvents;
}
inline std::vector<::XCEngine::UI::UIInputEvent> BuildUIEditorPanelInputEvents(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const UIEditorPanelInputFilterOptions& options,
bool synthesizeFocusGained = false,
bool synthesizeFocusLost = false) {
std::vector<::XCEngine::UI::UIInputEvent> filteredEvents =
FilterUIEditorPanelInputEvents(bounds, inputEvents, options);
if (!synthesizeFocusGained && !synthesizeFocusLost) {
return filteredEvents;
}
std::vector<::XCEngine::UI::UIInputEvent> routedEvents = {};
routedEvents.reserve(
filteredEvents.size() +
static_cast<std::size_t>(synthesizeFocusGained) +
static_cast<std::size_t>(synthesizeFocusLost));
if (synthesizeFocusLost) {
routedEvents.push_back(
BuildUIEditorPanelFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost));
}
if (synthesizeFocusGained) {
routedEvents.push_back(
BuildUIEditorPanelFocusEvent(::XCEngine::UI::UIInputEventType::FocusGained));
}
routedEvents.insert(
routedEvents.end(),
filteredEvents.begin(),
filteredEvents.end());
return routedEvents;
}
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,28 @@
#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);
void AppendUIEditorCrashTrace(
std::uint32_t exceptionCode,
const void* exceptionAddress,
const struct _EXCEPTION_POINTERS* exceptionPointers);
std::filesystem::path GetUIEditorRuntimeTracePath();
std::filesystem::path GetUIEditorCrashTracePath();
bool IsUIEditorRuntimeTraceInitialized();
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,108 @@
#pragma once
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
#include <XCEngine/UI/Input/UIShortcutRegistry.h>
#include <cstdint>
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor {
enum class UIEditorShortcutManagerValidationCode : std::uint8_t {
None = 0,
InvalidCommandRegistry,
EmptyBindingCommandId,
UnknownCommandId,
MissingScopedOwnerId,
EmptyShortcutKey,
ConflictingBinding
};
struct UIEditorShortcutManagerValidationResult {
UIEditorShortcutManagerValidationCode code =
UIEditorShortcutManagerValidationCode::None;
std::string message = {};
[[nodiscard]] bool IsValid() const {
return code == UIEditorShortcutManagerValidationCode::None;
}
};
enum class UIEditorShortcutDispatchStatus : std::uint8_t {
NoMatch = 0,
Suppressed,
Dispatched,
Rejected
};
struct UIEditorShortcutDispatchResult {
UIEditorShortcutDispatchStatus status = UIEditorShortcutDispatchStatus::NoMatch;
bool matched = false;
bool commandExecuted = false;
std::string commandId = {};
std::string commandDisplayName = {};
std::string message = {};
XCEngine::UI::UIShortcutScope shortcutScope =
XCEngine::UI::UIShortcutScope::Global;
XCEngine::UI::UIElementId shortcutOwnerId = 0;
UIEditorWorkspaceCommandResult commandResult = {};
};
std::string_view GetUIEditorShortcutDispatchStatusName(
UIEditorShortcutDispatchStatus status);
class UIEditorShortcutManager {
public:
UIEditorShortcutManager() = default;
explicit UIEditorShortcutManager(UIEditorCommandRegistry commandRegistry);
const UIEditorCommandDispatcher& GetCommandDispatcher() const {
return m_commandDispatcher;
}
void SetHostCommandHandler(UIEditorHostCommandHandler* handler) {
m_commandDispatcher.SetHostCommandHandler(handler);
}
UIEditorHostCommandHandler* GetHostCommandHandler() const {
return m_commandDispatcher.GetHostCommandHandler();
}
const UIEditorCommandRegistry& GetCommandRegistry() const {
return m_commandDispatcher.GetCommandRegistry();
}
const XCEngine::UI::UIShortcutRegistry& GetShortcutRegistry() const {
return m_shortcutRegistry;
}
std::uint64_t RegisterBinding(const XCEngine::UI::UIShortcutBinding& binding);
bool UnregisterBinding(std::uint64_t bindingId);
void ClearBindings();
UIEditorShortcutManagerValidationResult ValidateConfiguration() const;
std::string GetPreferredShortcutText(std::string_view commandId) const;
UIEditorShortcutDispatchResult Dispatch(
const XCEngine::UI::UIInputEvent& event,
const XCEngine::UI::UIShortcutContext& shortcutContext,
UIEditorWorkspaceController& controller) const;
private:
UIEditorShortcutDispatchResult BuildDispatchResult(
UIEditorShortcutDispatchStatus status,
std::string commandId,
std::string commandDisplayName,
std::string message,
const XCEngine::UI::UIShortcutMatch* match = nullptr) const;
const XCEngine::UI::UIShortcutBinding* FindPreferredBinding(
std::string_view commandId) const;
UIEditorCommandDispatcher m_commandDispatcher = {};
XCEngine::UI::UIShortcutRegistry m_shortcutRegistry = {};
};
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,39 @@
#pragma once
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
#include <algorithm>
#include <string_view>
namespace XCEngine::UI::Editor {
inline float ClampUIEditorNonNegative(float value) {
return (std::max)(value, 0.0f);
}
inline float EstimateUIEditorSimpleTextWidth(
std::string_view text,
float estimatedGlyphWidth) {
return static_cast<float>(text.size()) * ClampUIEditorNonNegative(estimatedGlyphWidth);
}
inline float ResolveUIEditorMeasuredTextWidth(
std::string_view text,
float measuredWidth,
float fontSize,
float estimatedGlyphWidth,
const UIEditorTextMeasurer* textMeasurer = nullptr) {
if (measuredWidth > 0.0f) {
return measuredWidth;
}
if (textMeasurer != nullptr &&
!text.empty() &&
fontSize > 0.0f) {
return textMeasurer->MeasureTextWidth(UIEditorTextMeasureRequest { text, fontSize });
}
return EstimateUIEditorSimpleTextWidth(text, estimatedGlyphWidth);
}
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,23 @@
#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;
virtual float MeasureTextAdvance(const UIEditorTextMeasureRequest& request) const {
return MeasureTextWidth(request);
}
};
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,76 @@
#pragma once
#include <XCEditor/Collections/UIEditorListView.h>
#include <XCEditor/Collections/UIEditorScrollView.h>
#include <XCEditor/Collections/UIEditorTabStrip.h>
#include <XCEditor/Collections/UIEditorTreeView.h>
#include <XCEditor/Fields/UIEditorAssetField.h>
#include <XCEditor/Fields/UIEditorBoolField.h>
#include <XCEditor/Fields/UIEditorColorField.h>
#include <XCEditor/Fields/UIEditorEnumField.h>
#include <XCEditor/Fields/UIEditorNumberField.h>
#include <XCEditor/Fields/UIEditorObjectField.h>
#include <XCEditor/Fields/UIEditorPropertyGrid.h>
#include <XCEditor/Fields/UIEditorTextField.h>
#include <XCEditor/Fields/UIEditorVector2Field.h>
#include <XCEditor/Fields/UIEditorVector3Field.h>
#include <XCEditor/Fields/UIEditorVector4Field.h>
#include <XCEditor/Docking/UIEditorDockHost.h>
#include <XCEditor/Menu/UIEditorMenuBar.h>
#include <XCEditor/Menu/UIEditorMenuPopup.h>
#include <XCEditor/Panels/UIEditorPanelFrame.h>
#include <XCEditor/Shell/UIEditorShellCompose.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Shell/UIEditorStatusBar.h>
#include <XCEditor/Viewport/UIEditorViewportSlot.h>
namespace XCEngine::UI::Editor {
const Widgets::UIEditorBoolFieldMetrics& ResolveUIEditorBoolFieldMetrics();
const Widgets::UIEditorBoolFieldPalette& ResolveUIEditorBoolFieldPalette();
const Widgets::UIEditorNumberFieldMetrics& ResolveUIEditorNumberFieldMetrics();
const Widgets::UIEditorNumberFieldPalette& ResolveUIEditorNumberFieldPalette();
const Widgets::UIEditorTextFieldMetrics& ResolveUIEditorTextFieldMetrics();
const Widgets::UIEditorTextFieldPalette& ResolveUIEditorTextFieldPalette();
const Widgets::UIEditorVector2FieldMetrics& ResolveUIEditorVector2FieldMetrics();
const Widgets::UIEditorVector2FieldPalette& ResolveUIEditorVector2FieldPalette();
const Widgets::UIEditorVector3FieldMetrics& ResolveUIEditorVector3FieldMetrics();
const Widgets::UIEditorVector3FieldPalette& ResolveUIEditorVector3FieldPalette();
const Widgets::UIEditorVector4FieldMetrics& ResolveUIEditorVector4FieldMetrics();
const Widgets::UIEditorVector4FieldPalette& ResolveUIEditorVector4FieldPalette();
const Widgets::UIEditorEnumFieldMetrics& ResolveUIEditorEnumFieldMetrics();
const Widgets::UIEditorEnumFieldPalette& ResolveUIEditorEnumFieldPalette();
const Widgets::UIEditorColorFieldMetrics& ResolveUIEditorColorFieldMetrics();
const Widgets::UIEditorColorFieldPalette& ResolveUIEditorColorFieldPalette();
const Widgets::UIEditorObjectFieldMetrics& ResolveUIEditorObjectFieldMetrics();
const Widgets::UIEditorObjectFieldPalette& ResolveUIEditorObjectFieldPalette();
const Widgets::UIEditorAssetFieldMetrics& ResolveUIEditorAssetFieldMetrics();
const Widgets::UIEditorAssetFieldPalette& ResolveUIEditorAssetFieldPalette();
const Widgets::UIEditorMenuPopupMetrics& ResolveUIEditorMenuPopupMetrics();
const Widgets::UIEditorMenuPopupPalette& ResolveUIEditorMenuPopupPalette();
const Widgets::UIEditorListViewMetrics& ResolveUIEditorListViewMetrics();
const Widgets::UIEditorListViewPalette& ResolveUIEditorListViewPalette();
const Widgets::UIEditorTreeViewMetrics& ResolveUIEditorTreeViewMetrics();
const Widgets::UIEditorTreeViewPalette& ResolveUIEditorTreeViewPalette();
const Widgets::UIEditorScrollViewMetrics& ResolveUIEditorScrollViewMetrics();
const Widgets::UIEditorScrollViewPalette& ResolveUIEditorScrollViewPalette();
const Widgets::UIEditorTabStripMetrics& ResolveUIEditorTabStripMetrics();
const Widgets::UIEditorTabStripPalette& ResolveUIEditorTabStripPalette();
const Widgets::UIEditorMenuBarMetrics& ResolveUIEditorMenuBarMetrics();
const Widgets::UIEditorMenuBarPalette& ResolveUIEditorMenuBarPalette();
const Widgets::UIEditorStatusBarMetrics& ResolveUIEditorStatusBarMetrics();
const Widgets::UIEditorStatusBarPalette& ResolveUIEditorStatusBarPalette();
const Widgets::UIEditorPanelFrameMetrics& ResolveUIEditorPanelFrameMetrics();
const Widgets::UIEditorPanelFramePalette& ResolveUIEditorPanelFramePalette();
const Widgets::UIEditorDockHostMetrics& ResolveUIEditorDockHostMetrics();
const Widgets::UIEditorDockHostPalette& ResolveUIEditorDockHostPalette();
const Widgets::UIEditorViewportSlotMetrics& ResolveUIEditorViewportSlotMetrics();
const Widgets::UIEditorViewportSlotPalette& ResolveUIEditorViewportSlotPalette();
const UIEditorShellComposeMetrics& ResolveUIEditorShellComposeMetrics();
const UIEditorShellComposePalette& ResolveUIEditorShellComposePalette();
const UIEditorShellInteractionMetrics& ResolveUIEditorShellInteractionMetrics();
const UIEditorShellInteractionPalette& ResolveUIEditorShellInteractionPalette();
const Widgets::UIEditorPropertyGridMetrics& ResolveUIEditorPropertyGridMetrics();
const Widgets::UIEditorPropertyGridPalette& ResolveUIEditorPropertyGridPalette();
} // namespace XCEngine::UI::Editor