Add native scrolling to new editor tree views

This commit is contained in:
2026-04-21 01:38:55 +08:00
parent 383d1e9c73
commit 33c88f8234
7 changed files with 236 additions and 38 deletions

View File

@@ -569,7 +569,8 @@ void HierarchyPanel::ProcessDragAndFrameEvents(
bounds,
m_treeItems,
m_expansion,
ResolveUIEditorTreeViewMetrics());
ResolveUIEditorTreeViewMetrics(),
m_treeInteractionState.verticalOffset);
EmitReparentEvent(
dragResult.droppedToRoot ? EventKind::MovedToRoot : EventKind::Reparented,
dragResult.draggedItemId,
@@ -622,7 +623,8 @@ void HierarchyPanel::Update(
panelState->bounds,
m_treeItems,
m_expansion,
treeMetrics);
treeMetrics,
m_treeInteractionState.verticalOffset);
if (m_renameState.active || !m_pendingRenameItemId.empty()) {
m_treeFrame.layout = layout;

View File

@@ -1101,7 +1101,8 @@ std::vector<UIInputEvent> ProjectPanel::BuildTreeInteractionInputEvents(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
m_folderExpansion,
ResolveUIEditorTreeViewMetrics());
ResolveUIEditorTreeViewMetrics(),
m_treeInteractionState.verticalOffset);
return BuildUIEditorTreePanelInteractionInputEvents(
m_treeDragState,
layout,
@@ -1548,7 +1549,8 @@ void ProjectPanel::Update(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
m_folderExpansion,
treeMetrics);
treeMetrics,
m_treeInteractionState.verticalOffset);
m_treeFrame.result = {};
if ((m_renameState.active || !m_pendingRenameItemId.empty()) &&
@@ -1673,7 +1675,8 @@ void ProjectPanel::Update(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
m_folderExpansion,
treeMetrics);
treeMetrics,
m_treeInteractionState.verticalOffset);
}
struct ProjectAssetDragCallbacks {
@@ -1795,7 +1798,8 @@ void ProjectPanel::Update(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
m_folderExpansion,
treeMetrics);
treeMetrics,
m_treeInteractionState.verticalOffset);
}
const bool suppressPanelPointerEvents =

View File

@@ -1,5 +1,7 @@
#pragma once
#include <XCEditor/Collections/UIEditorScrollView.h>
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Widgets/UIExpansionModel.h>
#include <XCEngine/UI/Widgets/UISelectionModel.h>
@@ -32,6 +34,7 @@ struct UIEditorTreeViewItem {
struct UIEditorTreeViewState {
std::string hoveredItemId = {};
bool focused = false;
UIEditorScrollViewState scrollViewState = {};
};
struct UIEditorTreeViewMetrics {
@@ -48,6 +51,7 @@ struct UIEditorTreeViewMetrics {
float cornerRounding = 6.0f;
float borderThickness = 1.0f;
float focusedBorderThickness = 2.0f;
UIEditorScrollViewMetrics scrollViewMetrics = {};
};
struct UIEditorTreeViewPalette {
@@ -67,10 +71,12 @@ struct UIEditorTreeViewPalette {
::XCEngine::UI::UIColor(0.62f, 0.62f, 0.62f, 1.0f);
::XCEngine::UI::UIColor textColor =
::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f);
UIEditorScrollViewPalette scrollViewPalette = {};
};
struct UIEditorTreeViewLayout {
::XCEngine::UI::UIRect bounds = {};
UIEditorScrollViewLayout scrollViewLayout = {};
std::vector<std::size_t> visibleItemIndices = {};
std::vector<::XCEngine::UI::UIRect> rowRects = {};
std::vector<::XCEngine::UI::UIRect> disclosureRects = {};
@@ -111,11 +117,17 @@ std::size_t FindUIEditorTreeViewFirstVisibleChildItemIndex(
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
std::size_t itemIndex);
float MeasureUIEditorTreeViewContentHeight(
const std::vector<UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const UIEditorTreeViewMetrics& metrics = {});
UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const UIEditorTreeViewMetrics& metrics = {});
const UIEditorTreeViewMetrics& metrics = {},
float verticalOffset = 0.0f);
UIEditorTreeViewHitTarget HitTestUIEditorTreeView(
const UIEditorTreeViewLayout& layout,

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEditor/Collections/UIEditorScrollViewInteraction.h>
#include <XCEditor/Collections/UIEditorTreeView.h>
#include <XCEngine/UI/Types.h>
@@ -14,9 +15,11 @@ namespace XCEngine::UI::Editor {
struct UIEditorTreeViewInteractionState {
Widgets::UIEditorTreeViewState treeViewState = {};
UIEditorScrollViewInteractionState scrollViewInteractionState = {};
::XCEngine::UI::Widgets::UIKeyboardNavigationModel keyboardNavigation = {};
std::string selectionAnchorId = {};
::XCEngine::UI::UIPoint pointerPosition = {};
float verticalOffset = 0.0f;
bool hasPointerPosition = false;
};

View File

@@ -27,6 +27,26 @@ float ResolveTreeViewRowHeight(
return item.desiredHeight > 0.0f ? item.desiredHeight : metrics.rowHeight;
}
float ResolveContentHeight(
const std::vector<std::size_t>& visibleItemIndices,
const std::vector<UIEditorTreeViewItem>& items,
const UIEditorTreeViewMetrics& metrics) {
float contentHeight = 0.0f;
for (std::size_t visibleOffset = 0u; visibleOffset < visibleItemIndices.size(); ++visibleOffset) {
const std::size_t itemIndex = visibleItemIndices[visibleOffset];
if (itemIndex >= items.size()) {
continue;
}
contentHeight += ResolveTreeViewRowHeight(items[itemIndex], metrics);
if (visibleOffset + 1u < visibleItemIndices.size()) {
contentHeight += metrics.rowGap;
}
}
return ClampNonNegative(contentHeight);
}
float ResolveTextTop(
const ::XCEngine::UI::UIRect& rect,
float fontSize,
@@ -174,11 +194,21 @@ std::size_t FindUIEditorTreeViewFirstVisibleChildItemIndex(
: UIEditorTreeViewInvalidIndex;
}
float MeasureUIEditorTreeViewContentHeight(
const std::vector<UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const UIEditorTreeViewMetrics& metrics) {
const std::vector<std::size_t> visibleItemIndices =
CollectUIEditorTreeViewVisibleItemIndices(items, expansionModel);
return ResolveContentHeight(visibleItemIndices, items, metrics);
}
UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const UIEditorTreeViewMetrics& metrics) {
const UIEditorTreeViewMetrics& metrics,
float verticalOffset) {
UIEditorTreeViewLayout layout = {};
layout.bounds = ::XCEngine::UI::UIRect(
bounds.x,
@@ -186,6 +216,11 @@ UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
ClampNonNegative(bounds.width),
ClampNonNegative(bounds.height));
layout.visibleItemIndices = CollectUIEditorTreeViewVisibleItemIndices(items, expansionModel);
layout.scrollViewLayout = BuildUIEditorScrollViewLayout(
layout.bounds,
ResolveContentHeight(layout.visibleItemIndices, items, metrics),
verticalOffset,
metrics.scrollViewMetrics);
layout.rowRects.reserve(layout.visibleItemIndices.size());
layout.disclosureRects.reserve(layout.visibleItemIndices.size());
layout.iconRects.reserve(layout.visibleItemIndices.size());
@@ -193,7 +228,9 @@ UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
layout.itemHasChildren.reserve(layout.visibleItemIndices.size());
layout.itemExpanded.reserve(layout.visibleItemIndices.size());
float rowY = layout.bounds.y;
const ::XCEngine::UI::UIPoint contentOrigin =
ResolveUIEditorScrollViewContentOrigin(layout.scrollViewLayout);
float rowY = contentOrigin.y;
for (std::size_t visibleOffset = 0u;
visibleOffset < layout.visibleItemIndices.size();
++visibleOffset) {
@@ -204,9 +241,9 @@ UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
const bool expanded = hasChildren && expansionModel.IsExpanded(item.itemId);
const ::XCEngine::UI::UIRect rowRect(
layout.bounds.x,
layout.scrollViewLayout.contentRect.x,
rowY,
layout.bounds.width,
layout.scrollViewLayout.contentRect.width,
rowHeight);
const float contentX =
rowRect.x + metrics.horizontalPadding + static_cast<float>(item.depth) * metrics.indentWidth;
@@ -230,9 +267,11 @@ UIEditorTreeViewLayout BuildUIEditorTreeViewLayout(
const ::XCEngine::UI::UIRect labelRect(
labelStartX,
rowRect.y,
(rowRect.x + rowRect.width) -
labelStartX -
metrics.horizontalPadding,
(std::max)(
(rowRect.x + rowRect.width) -
labelStartX -
metrics.horizontalPadding,
0.0f),
rowRect.height);
layout.rowRects.push_back(rowRect);
@@ -278,13 +317,16 @@ void AppendUIEditorTreeViewBackground(
const UIEditorTreeViewState& state,
const UIEditorTreeViewPalette& palette,
const UIEditorTreeViewMetrics& metrics) {
drawList.AddFilledRect(layout.bounds, palette.surfaceColor, metrics.cornerRounding);
drawList.AddRectOutline(
layout.bounds,
state.focused ? palette.focusedBorderColor : palette.borderColor,
state.focused ? metrics.focusedBorderThickness : metrics.borderThickness,
metrics.cornerRounding);
UIEditorScrollViewState scrollViewState = state.scrollViewState;
scrollViewState.focused = state.focused;
AppendUIEditorScrollViewBackground(
drawList,
layout.scrollViewLayout,
scrollViewState,
palette.scrollViewPalette,
metrics.scrollViewMetrics);
drawList.PushClipRect(layout.scrollViewLayout.contentRect);
for (std::size_t visibleOffset = 0u; visibleOffset < layout.rowRects.size(); ++visibleOffset) {
const UIEditorTreeViewItem& item = items[layout.visibleItemIndices[visibleOffset]];
const bool selected = selectionModel.IsSelected(item.itemId);
@@ -299,6 +341,7 @@ void AppendUIEditorTreeViewBackground(
: palette.rowHoverColor;
drawList.AddFilledRect(layout.rowRects[visibleOffset], rowColor, metrics.cornerRounding);
}
drawList.PopClipRect();
}
void AppendUIEditorTreeViewForeground(
@@ -307,7 +350,7 @@ void AppendUIEditorTreeViewForeground(
const std::vector<UIEditorTreeViewItem>& items,
const UIEditorTreeViewPalette& palette,
const UIEditorTreeViewMetrics& metrics) {
drawList.PushClipRect(layout.bounds);
drawList.PushClipRect(layout.scrollViewLayout.contentRect);
for (std::size_t visibleOffset = 0u; visibleOffset < layout.rowRects.size(); ++visibleOffset) {
const UIEditorTreeViewItem& item = items[layout.visibleItemIndices[visibleOffset]];
if (layout.itemHasChildren[visibleOffset]) {
@@ -344,7 +387,7 @@ void AppendUIEditorTreeView(
const UIEditorTreeViewPalette& palette,
const UIEditorTreeViewMetrics& metrics) {
const UIEditorTreeViewLayout layout =
BuildUIEditorTreeViewLayout(bounds, items, expansionModel, metrics);
BuildUIEditorTreeViewLayout(bounds, items, expansionModel, metrics, 0.0f);
AppendUIEditorTreeViewBackground(
drawList,
layout,

View File

@@ -2,6 +2,7 @@
#include <XCEngine/Input/InputTypes.h>
#include <algorithm>
#include <utility>
namespace XCEngine::UI::Editor {
@@ -12,23 +13,48 @@ using ::XCEngine::Input::KeyCode;
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
using ::XCEngine::UI::UIPointerButton;
using Widgets::BuildUIEditorTreeViewLayout;
using ::XCEngine::UI::Widgets::UISelectionModel;
using Widgets::DoesUIEditorTreeViewItemHaveChildren;
using Widgets::FindUIEditorTreeViewFirstVisibleChildItemIndex;
using Widgets::FindUIEditorTreeViewItemIndex;
using Widgets::FindUIEditorTreeViewParentItemIndex;
using Widgets::HitTestUIEditorTreeView;
using Widgets::IsUIEditorTreeViewPointInside;
using Widgets::MeasureUIEditorTreeViewContentHeight;
using Widgets::UIEditorTreeViewHitTarget;
using Widgets::UIEditorTreeViewHitTargetKind;
using Widgets::UIEditorTreeViewInvalidIndex;
Widgets::UIEditorTreeViewLayout BuildLayout(
UIEditorTreeViewInteractionState& state,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const Widgets::UIEditorTreeViewMetrics& metrics) {
Widgets::UIEditorTreeViewLayout layout =
Widgets::BuildUIEditorTreeViewLayout(
bounds,
items,
expansionModel,
metrics,
state.verticalOffset);
state.verticalOffset = layout.scrollViewLayout.verticalOffset;
return layout;
}
void SyncScrollState(UIEditorTreeViewInteractionState& state) {
state.treeViewState.scrollViewState =
state.scrollViewInteractionState.scrollViewState;
state.treeViewState.scrollViewState.focused = state.treeViewState.focused;
}
bool ShouldUsePointerPosition(const UIInputEvent& event) {
switch (event.type) {
case UIInputEventType::PointerMove:
case UIInputEventType::PointerEnter:
case UIInputEventType::PointerButtonDown:
case UIInputEventType::PointerButtonUp:
case UIInputEventType::PointerWheel:
return true;
default:
return false;
@@ -81,7 +107,7 @@ std::size_t FindVisibleIndexForItemId(
void SyncKeyboardNavigation(
UIEditorTreeViewInteractionState& state,
const ::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
const UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items) {
state.keyboardNavigation.SetItemCount(layout.visibleItemIndices.size());
@@ -105,7 +131,7 @@ void SyncKeyboardNavigation(
void SyncSelectionAnchor(
UIEditorTreeViewInteractionState& state,
const ::XCEngine::UI::Widgets::UISelectionModel& selectionModel) {
const UISelectionModel& selectionModel) {
if (!selectionModel.HasSelection()) {
state.selectionAnchorId.clear();
return;
@@ -137,7 +163,7 @@ bool IsDescendantItem(
bool SelectVisibleItem(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::size_t visibleIndex,
@@ -165,7 +191,7 @@ bool SelectVisibleItem(
bool ToggleVisibleItemSelection(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::size_t visibleIndex,
@@ -191,7 +217,7 @@ bool ToggleVisibleItemSelection(
bool SelectVisibleItemRange(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::size_t visibleIndex,
@@ -262,7 +288,7 @@ void PopulateCurrentVisibleItemResult(
bool ApplyVerticalNavigation(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::int32_t keyCode,
@@ -311,7 +337,7 @@ bool ApplyVerticalNavigation(
bool ApplyHorizontalNavigation(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
@@ -396,7 +422,7 @@ bool ApplyHorizontalNavigation(
void NormalizeSelectionAfterCollapse(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
const Widgets::UIEditorTreeViewLayout& layout,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
std::string_view collapsedItemId,
@@ -429,24 +455,98 @@ void NormalizeSelectionAfterCollapse(
false);
}
float ResolveVisibleOffset(
const Widgets::UIEditorTreeViewLayout& layout,
std::size_t visibleIndex,
const Widgets::UIEditorTreeViewMetrics& metrics) {
if (visibleIndex >= layout.rowRects.size()) {
return layout.scrollViewLayout.verticalOffset;
}
const ::XCEngine::UI::UIRect& rowRect = layout.rowRects[visibleIndex];
const ::XCEngine::UI::UIRect& contentRect = layout.scrollViewLayout.contentRect;
const float rowBottom = rowRect.y + rowRect.height;
const float contentBottom = contentRect.y + contentRect.height;
float verticalOffset = layout.scrollViewLayout.verticalOffset;
if (rowRect.y < contentRect.y) {
verticalOffset -= contentRect.y - rowRect.y;
} else if (rowBottom > contentBottom) {
verticalOffset += rowBottom - contentBottom;
}
return Widgets::ClampUIEditorScrollViewOffset(
layout.bounds,
layout.scrollViewLayout.contentHeight,
verticalOffset,
metrics.scrollViewMetrics);
}
void EnsureVisibleSelection(
UIEditorTreeViewInteractionState& state,
UISelectionModel& selectionModel,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const ::XCEngine::UI::UIRect& bounds,
Widgets::UIEditorTreeViewLayout& layout,
UIEditorTreeViewInteractionResult& result,
const Widgets::UIEditorTreeViewMetrics& metrics) {
std::size_t targetVisibleIndex = result.selectedVisibleIndex;
if (targetVisibleIndex == UIEditorTreeViewInvalidIndex &&
selectionModel.HasSelection()) {
targetVisibleIndex =
FindVisibleIndexForItemId(layout, items, selectionModel.GetSelectedId());
}
if (targetVisibleIndex == UIEditorTreeViewInvalidIndex) {
return;
}
const float adjustedOffset =
ResolveVisibleOffset(layout, targetVisibleIndex, metrics);
if (adjustedOffset == state.verticalOffset) {
return;
}
state.verticalOffset = adjustedOffset;
layout = BuildLayout(state, bounds, items, expansionModel, metrics);
}
} // namespace
UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
UIEditorTreeViewInteractionState& state,
::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
UISelectionModel& selectionModel,
::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<Widgets::UIEditorTreeViewItem>& items,
const std::vector<UIInputEvent>& inputEvents,
const Widgets::UIEditorTreeViewMetrics& metrics) {
Widgets::UIEditorTreeViewLayout layout =
BuildUIEditorTreeViewLayout(bounds, items, expansionModel, metrics);
BuildLayout(state, bounds, items, expansionModel, metrics);
SyncKeyboardNavigation(state, selectionModel, layout, items);
SyncSelectionAnchor(state, selectionModel);
SyncHoverTarget(state, layout, items);
SyncScrollState(state);
UIEditorTreeViewInteractionResult interactionResult = {};
for (const UIInputEvent& event : inputEvents) {
state.scrollViewInteractionState.scrollViewState.focused =
state.treeViewState.focused;
const std::vector<UIInputEvent> scrollEvents = { event };
const UIEditorScrollViewInteractionFrame scrollFrame =
UpdateUIEditorScrollViewInteraction(
state.scrollViewInteractionState,
state.verticalOffset,
bounds,
MeasureUIEditorTreeViewContentHeight(items, expansionModel, metrics),
scrollEvents,
metrics.scrollViewMetrics);
state.treeViewState.focused =
state.scrollViewInteractionState.scrollViewState.focused;
SyncScrollState(state);
layout = BuildLayout(state, bounds, items, expansionModel, metrics);
if (ShouldUsePointerPosition(event)) {
state.pointerPosition = event.position;
state.hasPointerPosition = true;
@@ -468,6 +568,7 @@ UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
case UIInputEventType::PointerMove:
case UIInputEventType::PointerEnter:
case UIInputEventType::PointerWheel:
break;
case UIInputEventType::PointerLeave:
@@ -586,9 +687,7 @@ UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
case UIInputEventType::KeyDown:
if (state.treeViewState.focused &&
!event.modifiers.control &&
!event.modifiers.alt &&
!event.modifiers.super) {
!HasNavigationModifiers(event.modifiers)) {
if (event.keyCode == static_cast<std::int32_t>(KeyCode::F2) &&
selectionModel.HasSelection()) {
eventResult.renameRequested = true;
@@ -625,7 +724,12 @@ UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
break;
}
layout = BuildUIEditorTreeViewLayout(bounds, items, expansionModel, metrics);
eventResult.consumed =
eventResult.consumed ||
scrollFrame.result.consumed ||
scrollFrame.result.offsetChanged;
layout = BuildLayout(state, bounds, items, expansionModel, metrics);
if (eventResult.expansionChanged &&
!eventResult.toggledItemId.empty() &&
!expansionModel.IsExpanded(eventResult.toggledItemId)) {
@@ -637,9 +741,25 @@ UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
eventResult.toggledItemId,
eventResult);
}
if (eventResult.selectionChanged ||
eventResult.keyboardNavigated ||
eventResult.expansionChanged) {
EnsureVisibleSelection(
state,
selectionModel,
items,
expansionModel,
bounds,
layout,
eventResult,
metrics);
}
SyncKeyboardNavigation(state, selectionModel, layout, items);
SyncSelectionAnchor(state, selectionModel);
SyncHoverTarget(state, layout, items);
SyncScrollState(state);
if (eventResult.hitTarget.kind == UIEditorTreeViewHitTargetKind::None &&
state.hasPointerPosition) {
eventResult.hitTarget = HitTestUIEditorTreeView(layout, state.pointerPosition);
@@ -659,10 +779,11 @@ UIEditorTreeViewInteractionFrame UpdateUIEditorTreeViewInteraction(
}
}
layout = BuildUIEditorTreeViewLayout(bounds, items, expansionModel, metrics);
layout = BuildLayout(state, bounds, items, expansionModel, metrics);
SyncKeyboardNavigation(state, selectionModel, layout, items);
SyncSelectionAnchor(state, selectionModel);
SyncHoverTarget(state, layout, items);
SyncScrollState(state);
if (interactionResult.hitTarget.kind == UIEditorTreeViewHitTargetKind::None &&
state.hasPointerPosition) {
interactionResult.hitTarget = HitTestUIEditorTreeView(layout, state.pointerPosition);

View File

@@ -80,6 +80,13 @@ Widgets::UIEditorTreeViewPalette BuildTreeViewPalette() {
palette.rowSelectedFocusedColor = kSurfaceActive;
palette.disclosureColor = kTextMuted;
palette.textColor = kTextPrimary;
palette.scrollViewPalette.surfaceColor = palette.surfaceColor;
palette.scrollViewPalette.borderColor = palette.borderColor;
palette.scrollViewPalette.focusedBorderColor = palette.focusedBorderColor;
palette.scrollViewPalette.scrollbarTrackColor = kSurfaceLower;
palette.scrollViewPalette.scrollbarThumbColor = kSurfaceHover;
palette.scrollViewPalette.scrollbarThumbHoverColor = kSurfaceActive;
palette.scrollViewPalette.scrollbarThumbActiveColor = UIColor(0.20f, 0.20f, 0.20f, 1.0f);
return palette;
}
@@ -98,6 +105,12 @@ Widgets::UIEditorTreeViewMetrics BuildTreeViewMetrics() {
metrics.cornerRounding = 0.0f;
metrics.borderThickness = 0.0f;
metrics.focusedBorderThickness = 0.0f;
metrics.scrollViewMetrics.scrollbarWidth = 8.0f;
metrics.scrollViewMetrics.scrollbarInset = 3.0f;
metrics.scrollViewMetrics.minThumbHeight = 28.0f;
metrics.scrollViewMetrics.cornerRounding = metrics.cornerRounding;
metrics.scrollViewMetrics.borderThickness = metrics.borderThickness;
metrics.scrollViewMetrics.focusedBorderThickness = metrics.focusedBorderThickness;
return metrics;
}