Unify new editor tree filter host

This commit is contained in:
2026-04-23 01:12:36 +08:00
parent 03e0b362f7
commit d52eefe2ff
7 changed files with 856 additions and 53 deletions

View File

@@ -341,6 +341,15 @@ const std::vector<Widgets::UIEditorTreeViewItem>& ProjectPanel::GetWindowTreeIte
return m_windowTreeItems;
}
const std::vector<Widgets::UIEditorTreeViewItem>& ProjectPanel::GetPresentedWindowTreeItems() const {
return ResolveUIEditorFilterableTreeHostItems(m_treeFilterHostFrame);
}
const ::XCEngine::UI::Widgets::UIExpansionModel&
ProjectPanel::GetPresentedWindowTreeExpansionModel() const {
return ResolveUIEditorFilterableTreeHostExpansionModel(m_treeFilterHostFrame);
}
void ProjectPanel::Initialize(const std::filesystem::path& repoRoot) {
m_ownedProjectRuntime = std::make_unique<EditorProjectRuntime>();
m_ownedProjectRuntime->Initialize(repoRoot);
@@ -378,6 +387,8 @@ void ProjectPanel::SetTextMeasurer(const UIEditorTextMeasurer* textMeasurer) {
void ProjectPanel::ResetInteractionState() {
m_assetDragState = {};
m_treeDragState = {};
m_treeFilterHostState = {};
m_treeFilterHostFrame = {};
m_browserScrollInteractionState = {};
m_browserScrollFrame = {};
m_browserVerticalOffset = 0.0f;
@@ -505,7 +516,7 @@ UIRect ProjectPanel::BuildRenameBounds(
if (surface == RenameSurface::Tree) {
return BuildUIEditorTreeViewInlineRenameBounds(
m_treeFrame.layout,
GetWindowTreeItems(),
GetPresentedWindowTreeItems(),
itemId,
hostedMetrics);
}
@@ -690,13 +701,43 @@ void ProjectPanel::SyncAssetSelectionFromRuntime() {
m_assetSelection.ClearSelection();
}
Widgets::UIEditorTreeViewMetrics ProjectPanel::RebuildPanelLayout(const UIRect& bounds) {
void ProjectPanel::ApplyBrowserLayout(
const UIRect& bounds,
const UIRect& browserContentRect,
float browserVerticalOffset) {
m_layout = BuildLayout(bounds, browserContentRect, browserVerticalOffset);
if (HasValidBounds(m_treeFilterHostFrame.layout.bounds)) {
m_layout.treeRect = m_treeFilterHostFrame.layout.treeRect;
}
}
Widgets::UIEditorTreeViewMetrics ProjectPanel::RebuildPanelLayout(
const UIRect& bounds,
const std::vector<UIInputEvent>& treeHostInputEvents) {
const Widgets::UIEditorTreeViewMetrics treeMetrics = ResolveUIEditorTreeViewMetrics();
m_layout = BuildLayout(bounds, {}, 0.0f);
m_treeFilterHostFrame = UpdateUIEditorFilterableTreeHost(
m_treeFilterHostState,
m_layout.treeRect,
"Project.TreeFilter",
treeHostInputEvents,
m_windowTreeItems,
m_folderExpansion);
if (m_treeFilterHostFrame.result.queryChanged) {
m_treeInteractionState.verticalOffset = 0.0f;
}
if (IsUIEditorFilterableTreeHostSearchFocused(m_treeFilterHostState)) {
m_treeInteractionState.treeViewState.focused = false;
}
m_layout.treeRect = m_treeFilterHostFrame.layout.treeRect;
::XCEngine::UI::Widgets::UIExpansionModel* activeExpansionModel =
m_treeFilterHostFrame.result.filteringActive
? &m_treeFilterHostFrame.filteredExpansionModel
: &m_folderExpansion;
m_treeFrame.layout = Widgets::BuildUIEditorTreeViewLayout(
m_layout.treeRect,
GetWindowTreeItems(),
m_folderExpansion,
GetPresentedWindowTreeItems(),
*activeExpansionModel,
treeMetrics,
m_treeInteractionState.verticalOffset);
return treeMetrics;
@@ -797,7 +838,7 @@ bool ProjectPanel::OpenProjectItem(std::string_view itemId, EventSource source)
SyncSelectionsFromRuntime();
RebuildPanelLayout(m_layout.bounds);
RebuildBrowserScrollLayout();
m_layout = BuildLayout(
ApplyBrowserLayout(
m_layout.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
@@ -1146,13 +1187,17 @@ std::vector<UIInputEvent> ProjectPanel::BuildTreeInteractionInputEvents(
const std::vector<UIInputEvent>& inputEvents,
const UIRect& bounds,
const UIEditorHostedPanelDispatchEntry& dispatchEntry) const {
const std::vector<Widgets::UIEditorTreeViewItem>& presentedItems =
GetPresentedWindowTreeItems();
const std::vector<UIInputEvent> rawEvents =
BuildUIEditorHostedTreeViewInputEvents(
bounds,
inputEvents,
UIEditorHostedTreeViewInputOptions{
.allowInteraction = dispatchEntry.allowInteraction,
.hasInputFocus = dispatchEntry.focused,
.hasInputFocus =
dispatchEntry.focused &&
!IsUIEditorFilterableTreeHostSearchFocused(m_treeFilterHostState),
.captureActive = HasActivePointerCapture()
},
dispatchEntry.focusGained,
@@ -1162,15 +1207,15 @@ std::vector<UIInputEvent> ProjectPanel::BuildTreeInteractionInputEvents(
m_treeFrame.layout.bounds.width > 0.0f
? m_treeFrame.layout
: Widgets::BuildUIEditorTreeViewLayout(
m_layout.treeRect,
GetWindowTreeItems(),
m_folderExpansion,
bounds,
presentedItems,
GetPresentedWindowTreeExpansionModel(),
ResolveUIEditorTreeViewMetrics(),
m_treeInteractionState.verticalOffset);
return TreeDrag::BuildInteractionInputEvents(
m_treeDragState,
layout,
GetWindowTreeItems(),
presentedItems,
rawEvents,
TreeDrag::kDefaultDragThreshold,
m_splitterDragging || m_assetDragState.dragging);
@@ -1296,7 +1341,7 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchAssetCommand(
if (HasValidBounds(m_layout.bounds)) {
RebuildPanelLayout(m_layout.bounds);
RebuildBrowserScrollLayout();
m_layout = BuildLayout(
ApplyBrowserLayout(
m_layout.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
@@ -1333,7 +1378,7 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchAssetCommand(
if (HasValidBounds(m_layout.bounds)) {
RebuildPanelLayout(m_layout.bounds);
RebuildBrowserScrollLayout();
m_layout = BuildLayout(
ApplyBrowserLayout(
m_layout.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
@@ -1591,10 +1636,10 @@ void ProjectPanel::Update(
m_navigationWidth = ClampNavigationWidth(m_navigationWidth, dispatchEntry.bounds.width);
const Widgets::UIEditorTreeViewMetrics treeMetrics =
RebuildPanelLayout(dispatchEntry.bounds);
RebuildPanelLayout(dispatchEntry.bounds, filteredEvents);
const auto refreshBrowserLayout = [&]() {
RebuildBrowserScrollLayout();
m_layout = BuildLayout(
ApplyBrowserLayout(
dispatchEntry.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
@@ -1614,7 +1659,7 @@ void ProjectPanel::Update(
m_browserVerticalOffset = 0.0f;
}
m_layout = BuildLayout(
ApplyBrowserLayout(
dispatchEntry.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
@@ -1640,14 +1685,18 @@ void ProjectPanel::Update(
const std::vector<UIInputEvent> treeEvents =
BuildTreeInteractionInputEvents(
inputEvents,
dispatchEntry.bounds,
m_layout.treeRect,
dispatchEntry);
::XCEngine::UI::Widgets::UIExpansionModel* activeExpansionModel =
m_treeFilterHostFrame.result.filteringActive
? &m_treeFilterHostFrame.filteredExpansionModel
: &m_folderExpansion;
m_treeFrame = UpdateUIEditorTreeViewInteraction(
m_treeInteractionState,
m_folderSelection,
m_folderExpansion,
*activeExpansionModel,
m_layout.treeRect,
GetWindowTreeItems(),
GetPresentedWindowTreeItems(),
treeEvents,
treeMetrics);
@@ -1726,7 +1775,7 @@ void ProjectPanel::Update(
TreeDrag::ProcessInputEvents(
m_treeDragState,
m_treeFrame.layout,
GetWindowTreeItems(),
GetPresentedWindowTreeItems(),
filteredEvents,
m_layout.treeRect,
treeDragCallbacks,
@@ -2212,15 +2261,17 @@ std::string ProjectPanel::ResolveAssetDropTargetItemId(
}
if (ContainsPoint(m_treeFrame.layout.bounds, point)) {
const std::vector<Widgets::UIEditorTreeViewItem>& presentedItems =
GetPresentedWindowTreeItems();
Widgets::UIEditorTreeViewHitTarget hitTarget =
Widgets::HitTestUIEditorTreeView(m_treeFrame.layout, point);
if (hitTarget.itemIndex < GetWindowTreeItems().size() &&
if (hitTarget.itemIndex < presentedItems.size() &&
(hitTarget.kind == Widgets::UIEditorTreeViewHitTargetKind::Row ||
hitTarget.kind == Widgets::UIEditorTreeViewHitTargetKind::Disclosure)) {
if (surface != nullptr) {
*surface = DropTargetSurface::Tree;
}
return GetWindowTreeItems()[hitTarget.itemIndex].itemId;
return presentedItems[hitTarget.itemIndex].itemId;
}
}
@@ -2249,6 +2300,8 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
const BrowserModel& browserModel = GetBrowserModel();
const auto& assetEntries = browserModel.GetAssetEntries();
const std::filesystem::path projectRootPath = browserModel.GetProjectRootPath();
const std::vector<Widgets::UIEditorTreeViewItem>& presentedItems =
GetPresentedWindowTreeItems();
drawList.AddFilledRect(m_layout.bounds, kSurfaceColor);
drawList.AddFilledRect(m_layout.leftPaneRect, kPaneColor);
@@ -2268,10 +2321,14 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
const Widgets::UIEditorTreeViewPalette treePalette = ResolveUIEditorTreeViewPalette();
const Widgets::UIEditorTreeViewMetrics treeMetrics = ResolveUIEditorTreeViewMetrics();
AppendUIEditorFilterableTreeHostSearchField(
drawList,
m_treeFilterHostFrame,
m_treeFilterHostState);
AppendUIEditorTreeViewBackground(
drawList,
m_treeFrame.layout,
GetWindowTreeItems(),
presentedItems,
m_folderSelection,
m_treeInteractionState.treeViewState,
treePalette,
@@ -2279,14 +2336,14 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
AppendUIEditorTreeViewForeground(
drawList,
m_treeFrame.layout,
GetWindowTreeItems(),
presentedItems,
treePalette,
treeMetrics);
AppendUIEditorTreeViewDropPreview(
drawList,
m_treeFrame.layout,
GetWindowTreeItems(),
presentedItems,
m_treeDragState.dragging && m_treeDragState.validDropTarget,
m_treeDragState.dropToRoot,
m_treeDragState.dropTargetItemId,
@@ -2297,7 +2354,7 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
AppendUIEditorTreeViewDropPreview(
drawList,
m_treeFrame.layout,
GetWindowTreeItems(),
presentedItems,
m_assetDragState.dragging &&
m_assetDragState.validDropTarget &&
m_assetDropTargetSurface == DropTargetSurface::Tree,