Files
XCEngine/new_editor/app/Features/Hierarchy/HierarchyPanelSupport.h

134 lines
4.3 KiB
C++

#pragma once
#include "HierarchyPanel.h"
#include "Rendering/Assets/BuiltInIcons.h"
#include "UI/Styles/EditorTreeViewStyle.h"
#include <XCEditor/Collections/UIEditorTreeView.h>
#include <algorithm>
#include <cmath>
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor::App::HierarchyPanelSupport {
using ::XCEngine::UI::UIColor;
using ::XCEngine::UI::UIDrawList;
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
using ::XCEngine::UI::UIPoint;
using ::XCEngine::UI::UIPointerButton;
using ::XCEngine::UI::UIRect;
using Widgets::AppendUIEditorTreeViewBackground;
using Widgets::AppendUIEditorTreeViewForeground;
using Widgets::DoesUIEditorTreeViewItemHaveChildren;
using Widgets::HitTestUIEditorTreeView;
using Widgets::IsUIEditorTreeViewPointInside;
using Widgets::UIEditorTreeViewHitTarget;
using Widgets::UIEditorTreeViewHitTargetKind;
using Widgets::UIEditorTreeViewInvalidIndex;
inline constexpr std::string_view kHierarchyPanelId = "hierarchy";
inline constexpr float kDragThreshold = 4.0f;
inline constexpr UIColor kDragPreviewColor(0.92f, 0.92f, 0.92f, 0.42f);
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 ComputeSquaredDistance(const UIPoint& lhs, const UIPoint& rhs) {
const float dx = lhs.x - rhs.x;
const float dy = lhs.y - rhs.y;
return dx * dx + dy * dy;
}
inline ::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::GameObject)
: ::XCEngine::UI::UITextureHandle {};
}
inline std::vector<UIInputEvent> FilterHierarchyInputEvents(
const UIRect& bounds,
const std::vector<UIInputEvent>& inputEvents,
bool allowInteraction,
bool panelActive,
bool captureActive) {
if (!allowInteraction && !captureActive) {
return {};
}
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 (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 const Widgets::UIEditorTreeViewItem* ResolveHitItem(
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
const UIPoint& point,
UIEditorTreeViewHitTarget* hitTargetOutput = nullptr) {
const UIEditorTreeViewHitTarget hitTarget = HitTestUIEditorTreeView(layout, point);
if (hitTargetOutput != nullptr) {
*hitTargetOutput = hitTarget;
}
if (hitTarget.itemIndex >= items.size()) {
return nullptr;
}
return &items[hitTarget.itemIndex];
}
inline std::size_t FindVisibleIndexForItemId(
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::string_view itemId) {
for (std::size_t visibleIndex = 0u; visibleIndex < layout.visibleItemIndices.size(); ++visibleIndex) {
const std::size_t itemIndex = layout.visibleItemIndices[visibleIndex];
if (itemIndex < items.size() && items[itemIndex].itemId == itemId) {
return visibleIndex;
}
}
return UIEditorTreeViewInvalidIndex;
}
} // namespace XCEngine::UI::Editor::App::HierarchyPanelSupport