#pragma once #include "ProjectPanel.h" #include "Rendering/Assets/BuiltInIcons.h" #include "UI/Styles/EditorTreeViewStyle.h" #include #include #include #include #include namespace XCEngine::UI::Editor::App::ProjectPanelSupport { using ::XCEngine::UI::Editor::UIEditorTextMeasureRequest; using ::XCEngine::UI::Editor::UIEditorTextMeasurer; using ::XCEngine::UI::UIColor; using ::XCEngine::UI::UIDrawList; using ::XCEngine::UI::UIInputEvent; using ::XCEngine::UI::UIInputEventType; using ::XCEngine::UI::UIPoint; using ::XCEngine::UI::UIRect; using Widgets::AppendUIEditorTreeViewBackground; using Widgets::AppendUIEditorTreeViewForeground; inline constexpr std::string_view kProjectPanelId = "project"; inline constexpr std::size_t kInvalidLayoutIndex = static_cast(-1); inline constexpr float kBrowserHeaderHeight = 24.0f; inline constexpr float kNavigationMinWidth = 180.0f; inline constexpr float kBrowserMinWidth = 260.0f; inline constexpr float kHeaderHorizontalPadding = 10.0f; inline constexpr float kHeaderBottomBorderThickness = 1.0f; inline constexpr float kBreadcrumbItemPaddingX = 4.0f; inline constexpr float kBreadcrumbItemPaddingY = 1.0f; inline constexpr float kBreadcrumbSpacing = 3.0f; inline constexpr float kTreeTopPadding = 0.0f; inline constexpr float kGridInsetX = 16.0f; inline constexpr float kGridInsetY = 12.0f; inline constexpr float kGridTileWidth = 92.0f; inline constexpr float kGridTileHeight = 92.0f; inline constexpr float kGridTileGapX = 12.0f; inline constexpr float kGridTileGapY = 12.0f; inline constexpr float kGridPreviewWidth = 68.0f; inline constexpr float kGridPreviewHeight = 54.0f; inline constexpr float kHeaderFontSize = 12.0f; inline constexpr float kTileLabelFontSize = 11.0f; inline constexpr UIColor kSurfaceColor(0.10f, 0.10f, 0.10f, 1.0f); inline constexpr UIColor kPaneColor(0.10f, 0.10f, 0.10f, 1.0f); inline constexpr UIColor kHeaderColor(0.11f, 0.11f, 0.11f, 1.0f); inline constexpr UIColor kTextPrimary(0.880f, 0.880f, 0.880f, 1.0f); inline constexpr UIColor kTextStrong(0.930f, 0.930f, 0.930f, 1.0f); inline constexpr UIColor kTextMuted(0.640f, 0.640f, 0.640f, 1.0f); inline constexpr UIColor kTileHoverColor(0.14f, 0.14f, 0.14f, 1.0f); inline constexpr UIColor kTileSelectedColor(0.18f, 0.18f, 0.18f, 1.0f); inline constexpr UIColor kTilePreviewFillColor(0.15f, 0.15f, 0.15f, 1.0f); inline constexpr UIColor kTilePreviewShadeColor(0.12f, 0.12f, 0.12f, 1.0f); inline constexpr UIColor kTilePreviewOutlineColor(0.920f, 0.920f, 0.920f, 0.20f); inline bool ContainsPoint(const UIRect& rect, const UIPoint& point) { return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height; } inline float ClampNonNegative(float value) { return (std::max)(value, 0.0f); } inline float ResolveTextTop(float rectY, float rectHeight, float fontSize) { const float lineHeight = fontSize * 1.6f; return rectY + std::floor((rectHeight - lineHeight) * 0.5f); } inline float MeasureTextWidth( const UIEditorTextMeasurer* textMeasurer, std::string_view text, float fontSize) { if (text.empty()) { return 0.0f; } if (textMeasurer != nullptr) { const float measuredWidth = textMeasurer->MeasureTextWidth(UIEditorTextMeasureRequest{ text, fontSize }); if (measuredWidth > 0.0f) { return measuredWidth; } } return static_cast(text.size()) * fontSize * 0.56f; } inline std::vector FilterProjectPanelInputEvents( const UIRect& bounds, const std::vector& inputEvents, bool allowInteraction, bool panelActive, bool captureActive) { if (!allowInteraction && !captureActive) { return {}; } std::vector 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 (captureActive || ContainsPoint(bounds, event.position)) { filteredEvents.push_back(event); } break; case UIInputEventType::PointerLeave: filteredEvents.push_back(event); break; case UIInputEventType::FocusGained: case UIInputEventType::FocusLost: if (panelActive || captureActive) { filteredEvents.push_back(event); } break; case UIInputEventType::KeyDown: case UIInputEventType::KeyUp: case UIInputEventType::Character: if (panelActive) { filteredEvents.push_back(event); } break; default: break; } } return filteredEvents; } inline std::vector FilterTreeInputEvents( const std::vector& inputEvents, bool suppressPointerInput) { if (!suppressPointerInput) { return inputEvents; } std::vector 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: case UIInputEventType::PointerEnter: break; default: filteredEvents.push_back(event); break; } } return filteredEvents; } inline ::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons) { return icons != nullptr ? icons->Resolve(BuiltInIconKind::Folder) : ::XCEngine::UI::UITextureHandle {}; } inline float ClampNavigationWidth(float value, float totalWidth) { const float maxWidth = (std::max)( kNavigationMinWidth, totalWidth - kBrowserMinWidth - ResolveUIEditorDockHostMetrics().splitterMetrics.thickness); return std::clamp(value, kNavigationMinWidth, maxWidth); } inline void AppendTilePreview( UIDrawList& drawList, const UIRect& previewRect, bool directory) { if (directory) { const UIRect tabRect( previewRect.x + 8.0f, previewRect.y + 7.0f, 22.0f, 7.0f); const UIRect bodyRect( previewRect.x + 4.0f, previewRect.y + 13.0f, previewRect.width - 8.0f, previewRect.height - 18.0f); drawList.AddFilledRect(tabRect, kTilePreviewShadeColor, 1.0f); drawList.AddFilledRect(bodyRect, kTilePreviewFillColor, 1.0f); drawList.AddRectOutline(bodyRect, kTilePreviewOutlineColor, 1.0f, 1.0f); return; } const UIRect sheetRect( previewRect.x + 10.0f, previewRect.y + 4.0f, previewRect.width - 20.0f, previewRect.height - 8.0f); const UIRect accentRect( sheetRect.x, sheetRect.y, sheetRect.width, 7.0f); drawList.AddFilledRect(sheetRect, kTilePreviewFillColor, 1.0f); drawList.AddFilledRect(accentRect, kTilePreviewShadeColor, 1.0f); drawList.AddRectOutline(sheetRect, kTilePreviewOutlineColor, 1.0f, 1.0f); } } // namespace XCEngine::UI::Editor::App::ProjectPanelSupport