feat(xcui): add editor command and menu foundations
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCNewEditor/Editor/UIEditorCommandRegistry.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine::NewEditor {
|
||||
|
||||
enum class UIEditorCommandEvaluationCode : std::uint8_t {
|
||||
None = 0,
|
||||
InvalidCommandRegistry,
|
||||
UnknownCommandId,
|
||||
MissingActivePanel
|
||||
};
|
||||
|
||||
struct UIEditorCommandEvaluationResult {
|
||||
UIEditorCommandEvaluationCode code = UIEditorCommandEvaluationCode::None;
|
||||
bool executable = false;
|
||||
std::string commandId = {};
|
||||
std::string displayName = {};
|
||||
UIEditorWorkspaceCommand workspaceCommand = {};
|
||||
UIEditorWorkspaceCommandResult previewResult = {};
|
||||
std::string message = {};
|
||||
|
||||
[[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 = {};
|
||||
};
|
||||
|
||||
std::string_view GetUIEditorCommandDispatchStatusName(
|
||||
UIEditorCommandDispatchStatus status);
|
||||
|
||||
class UIEditorCommandDispatcher {
|
||||
public:
|
||||
UIEditorCommandDispatcher() = default;
|
||||
explicit UIEditorCommandDispatcher(UIEditorCommandRegistry commandRegistry);
|
||||
|
||||
const UIEditorCommandRegistry& GetCommandRegistry() const {
|
||||
return m_commandRegistry;
|
||||
}
|
||||
|
||||
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 = {};
|
||||
};
|
||||
|
||||
} // namespace XCEngine::NewEditor
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCNewEditor/Editor/UIEditorWorkspaceController.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine::NewEditor {
|
||||
|
||||
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 = {};
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
const UIEditorCommandDescriptor* FindUIEditorCommandDescriptor(
|
||||
const UIEditorCommandRegistry& registry,
|
||||
std::string_view commandId);
|
||||
|
||||
UIEditorCommandRegistryValidationResult ValidateUIEditorCommandRegistry(
|
||||
const UIEditorCommandRegistry& registry);
|
||||
|
||||
} // namespace XCEngine::NewEditor
|
||||
116
new_editor/include/XCNewEditor/Editor/UIEditorMenuModel.h
Normal file
116
new_editor/include/XCNewEditor/Editor/UIEditorMenuModel.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCNewEditor/Editor/UIEditorCommandDispatcher.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine::NewEditor {
|
||||
|
||||
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::NewEditor
|
||||
100
new_editor/include/XCNewEditor/Editor/UIEditorShortcutManager.h
Normal file
100
new_editor/include/XCNewEditor/Editor/UIEditorShortcutManager.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCNewEditor/Editor/UIEditorCommandDispatcher.h>
|
||||
|
||||
#include <XCEngine/UI/Input/UIShortcutRegistry.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine::NewEditor {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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::NewEditor
|
||||
Reference in New Issue
Block a user