#include "ProjectPanelInternal.h" namespace XCEngine::UI::Editor::App::ProjectPanelInternal { using ::XCEngine::UI::UIInputEventType; 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; } float ClampNonNegative(float value) { return (std::max)(value, 0.0f); } float ResolveTextTop(float rectY, float rectHeight, float fontSize) { const float lineHeight = fontSize * 1.6f; return rectY + std::floor((rectHeight - lineHeight) * 0.5f); } 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; } 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; } 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; } ::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons) { return icons != nullptr ? icons->Resolve(BuiltInIconKind::Folder) : ::XCEngine::UI::UITextureHandle {}; } float ClampNavigationWidth(float value, float totalWidth) { const float maxWidth = (std::max)( kNavigationMinWidth, totalWidth - kBrowserMinWidth - ResolveUIEditorDockHostMetrics().splitterMetrics.thickness); return std::clamp(value, kNavigationMinWidth, maxWidth); } 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::ProjectPanelInternal