2026-04-07 03:51:26 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
2026-04-10 00:41:28 +08:00
|
|
|
#include <XCEditor/Shell/UIEditorMenuModel.h>
|
2026-04-07 03:51:26 +08:00
|
|
|
#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 = 6.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 labelInsetY = -1.0f;
|
2026-04-08 02:52:28 +08:00
|
|
|
float labelFontSize = 13.0f;
|
2026-04-07 03:51:26 +08:00
|
|
|
float shortcutInsetRight = 24.0f;
|
|
|
|
|
float estimatedGlyphWidth = 7.0f;
|
2026-04-08 02:52:28 +08:00
|
|
|
float glyphFontSize = 12.0f;
|
2026-04-07 03:51:26 +08:00
|
|
|
float separatorThickness = 1.0f;
|
|
|
|
|
float borderThickness = 1.0f;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct UIEditorMenuPopupPalette {
|
|
|
|
|
::XCEngine::UI::UIColor popupColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor borderColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.31f, 0.31f, 0.31f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor itemHoverColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.28f, 0.28f, 0.28f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor itemOpenColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.34f, 0.34f, 0.34f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor separatorColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.32f, 0.32f, 0.32f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor textPrimary =
|
|
|
|
|
::XCEngine::UI::UIColor(0.94f, 0.94f, 0.94f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor textMuted =
|
|
|
|
|
::XCEngine::UI::UIColor(0.76f, 0.76f, 0.76f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor textDisabled =
|
|
|
|
|
::XCEngine::UI::UIColor(0.50f, 0.50f, 0.50f, 1.0f);
|
|
|
|
|
::XCEngine::UI::UIColor glyphColor =
|
|
|
|
|
::XCEngine::UI::UIColor(0.90f, 0.90f, 0.90f, 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
|