Revert "Update new_editor inspector layout and host rendering"

This reverts commit 5d81a64ef3.
This commit is contained in:
2026-04-21 13:55:30 +08:00
parent 64e778da65
commit 2c9e8dad49
62 changed files with 151 additions and 4417 deletions

View File

@@ -41,8 +41,8 @@ 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 = 0.0f;
inline constexpr float kGridInsetY = 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;
@@ -250,87 +250,6 @@ bool HasValidBounds(const UIRect& bounds) {
constexpr auto kGridDoubleClickInterval = std::chrono::milliseconds(400);
Widgets::UIEditorScrollViewMetrics BuildProjectGridScrollMetrics() {
Widgets::UIEditorScrollViewMetrics metrics = ResolveUIEditorScrollViewMetrics();
metrics.scrollbarWidth = 8.0f;
metrics.scrollbarInset = 3.0f;
metrics.minThumbHeight = 28.0f;
metrics.cornerRounding = 0.0f;
metrics.borderThickness = 0.0f;
metrics.focusedBorderThickness = 0.0f;
return metrics;
}
Widgets::UIEditorScrollViewPalette BuildProjectGridScrollPalette() {
Widgets::UIEditorScrollViewPalette palette = ResolveUIEditorScrollViewPalette();
palette.surfaceColor = kPaneColor;
return palette;
}
int ResolveProjectGridColumnCount(float gridWidth) {
const float effectiveTileWidth = kGridTileWidth + kGridTileGapX;
int columnCount = effectiveTileWidth > 0.0f
? static_cast<int>((ClampNonNegative(gridWidth) + kGridTileGapX) / effectiveTileWidth)
: 1;
if (columnCount < 1) {
columnCount = 1;
}
return columnCount;
}
float MeasureProjectGridContentHeight(
std::size_t itemCount,
int columnCount) {
if (itemCount == 0u || columnCount < 1) {
return 0.0f;
}
const std::size_t resolvedColumnCount = static_cast<std::size_t>(columnCount);
const std::size_t rowCount =
(itemCount + resolvedColumnCount - 1u) / resolvedColumnCount;
return static_cast<float>(rowCount) * kGridTileHeight +
static_cast<float>((std::max)(rowCount, std::size_t(1u)) - 1u) *
kGridTileGapY;
}
Widgets::UIEditorScrollViewLayout BuildProjectGridScrollLayout(
const UIRect& bounds,
std::size_t itemCount,
float verticalOffset,
const Widgets::UIEditorScrollViewMetrics& metrics,
int* resolvedColumnCount = nullptr) {
int columnCount = ResolveProjectGridColumnCount(bounds.width);
float contentHeight = MeasureProjectGridContentHeight(itemCount, columnCount);
Widgets::UIEditorScrollViewLayout scrollLayout = {};
for (int iteration = 0; iteration < 3; ++iteration) {
scrollLayout =
Widgets::BuildUIEditorScrollViewLayout(bounds, contentHeight, verticalOffset, metrics);
verticalOffset = scrollLayout.verticalOffset;
const int nextColumnCount =
ResolveProjectGridColumnCount(scrollLayout.contentRect.width);
const float nextContentHeight =
MeasureProjectGridContentHeight(itemCount, nextColumnCount);
if (nextColumnCount == columnCount &&
std::abs(nextContentHeight - contentHeight) <= 0.01f) {
columnCount = nextColumnCount;
contentHeight = nextContentHeight;
break;
}
columnCount = nextColumnCount;
contentHeight = nextContentHeight;
}
scrollLayout =
Widgets::BuildUIEditorScrollViewLayout(bounds, contentHeight, verticalOffset, metrics);
if (resolvedColumnCount != nullptr) {
*resolvedColumnCount = columnCount;
}
return scrollLayout;
}
Widgets::UIEditorMenuPopupItem BuildContextMenuCommandItem(
std::string itemId,
std::string label,
@@ -431,14 +350,12 @@ void ProjectPanel::SetTextMeasurer(const UIEditorTextMeasurer* textMeasurer) {
void ProjectPanel::ResetInteractionState() {
m_assetDragState = {};
m_treeDragState = {};
m_gridScrollInteractionState = {};
m_treeInteractionState = {};
m_treeFrame = {};
m_contextMenu = {};
ClearRenameState();
m_frameEvents.clear();
m_layout = {};
m_gridVerticalOffset = 0.0f;
m_hoveredAssetItemId.clear();
m_lastPrimaryClickedAssetId.clear();
m_lastPrimaryClickTime = {};
@@ -470,7 +387,6 @@ bool ProjectPanel::WantsHostPointerRelease() const {
bool ProjectPanel::HasActivePointerCapture() const {
return m_splitterDragging ||
m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb ||
GridDrag::HasActivePointerCapture(m_assetDragState) ||
TreeDrag::HasActivePointerCapture(m_treeDragState);
}
@@ -624,11 +540,6 @@ bool ProjectPanel::TryStartQueuedRenameSession() {
initialText = folder->label;
}
if (m_pendingRenameSurface == RenameSurface::Grid &&
HasValidBounds(m_layout.bounds)) {
EnsureAssetVisible(m_pendingRenameItemId, m_layout.bounds);
}
const UIRect bounds =
BuildRenameBounds(m_pendingRenameItemId, m_pendingRenameSurface);
if (!HasValidBounds(bounds)) {
@@ -798,10 +709,6 @@ bool ProjectPanel::NavigateToFolder(std::string_view itemId, EventSource source)
SyncCurrentFolderSelection();
SyncAssetSelectionFromRuntime();
ResetGridScrollPosition();
if (HasValidBounds(m_layout.bounds)) {
RebuildLayout(m_layout.bounds);
}
m_hoveredAssetItemId.clear();
m_lastPrimaryClickedAssetId.clear();
EmitEvent(
@@ -822,8 +729,7 @@ bool ProjectPanel::OpenProjectItem(std::string_view itemId, EventSource source)
if (navigated && HasValidBounds(m_layout.bounds)) {
SyncCurrentFolderSelection();
SyncAssetSelectionFromRuntime();
ResetGridScrollPosition();
RebuildLayout(m_layout.bounds);
m_layout = BuildLayout(m_layout.bounds);
m_hoveredAssetItemId.clear();
EmitEvent(
EventKind::FolderNavigated,
@@ -1293,9 +1199,6 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchAssetCommand(
m_lastPrimaryClickTime = {};
ResolveProjectRuntime()->SetSelection(createdItemId);
SyncAssetSelectionFromRuntime();
if (m_visible && HasValidBounds(m_layout.bounds)) {
EnsureAssetVisible(createdItemId, m_layout.bounds);
}
const AssetEntry* createdAsset = FindAssetEntry(createdItemId);
if (createdAsset == nullptr) {
@@ -1327,7 +1230,7 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchAssetCommand(
if (target.containerFolder->itemId != GetBrowserModel().GetCurrentFolderId()) {
NavigateToFolder(target.containerFolder->itemId, EventSource::GridSecondary);
if (HasValidBounds(m_layout.bounds)) {
RebuildLayout(m_layout.bounds);
m_layout = BuildLayout(m_layout.bounds);
}
}
@@ -1359,7 +1262,7 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchAssetCommand(
if (target.containerFolder->itemId != GetBrowserModel().GetCurrentFolderId()) {
NavigateToFolder(target.containerFolder->itemId, EventSource::GridSecondary);
if (HasValidBounds(m_layout.bounds)) {
RebuildLayout(m_layout.bounds);
m_layout = BuildLayout(m_layout.bounds);
}
}
@@ -1586,7 +1489,6 @@ void ProjectPanel::Update(
FindMountedProjectPanel(contentHostFrame);
if (panelState == nullptr) {
if (m_splitterDragging ||
m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb ||
m_assetDragState.dragging ||
m_treeDragState.dragging ||
m_renameState.active) {
@@ -1595,7 +1497,6 @@ void ProjectPanel::Update(
m_visible = false;
m_assetDragState = {};
m_treeDragState = {};
m_gridScrollInteractionState = {};
CloseContextMenu();
ClearRenameState();
ResetTransientFrames();
@@ -1603,11 +1504,7 @@ void ProjectPanel::Update(
}
if (!HasProjectRuntime()) {
if (m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb) {
m_requestPointerRelease = true;
}
m_visible = false;
m_gridScrollInteractionState = {};
CloseContextMenu();
ClearRenameState();
ResetTransientFrames();
@@ -1643,7 +1540,7 @@ void ProjectPanel::Update(
ClaimCommandFocus(filteredEvents, panelState->bounds, inputContext.allowInteraction);
m_navigationWidth = ClampNavigationWidth(m_navigationWidth, panelState->bounds.width);
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
if (m_contextMenu.open) {
RebuildContextMenu();
}
@@ -1687,7 +1584,7 @@ void ProjectPanel::Update(
m_treeFrame.result.selectedItemId != GetBrowserModel().GetCurrentFolderId()) {
CloseContextMenu();
NavigateToFolder(m_treeFrame.result.selectedItemId, EventSource::Tree);
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
}
if (m_treeFrame.result.renameRequested &&
!m_treeFrame.result.renameItemId.empty()) {
@@ -1773,7 +1670,7 @@ void ProjectPanel::Update(
EmitSelectionClearedEvent(EventSource::Tree);
}
SyncCurrentFolderSelection();
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
m_treeFrame.layout = Widgets::BuildUIEditorTreeViewLayout(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
@@ -1782,27 +1679,6 @@ void ProjectPanel::Update(
m_treeInteractionState.verticalOffset);
}
const Widgets::UIEditorScrollViewMetrics gridScrollMetrics =
BuildProjectGridScrollMetrics();
const bool hadGridScrollCapture =
m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb;
UpdateUIEditorScrollViewInteraction(
m_gridScrollInteractionState,
m_gridVerticalOffset,
m_layout.gridRect,
m_layout.gridScrollLayout.contentHeight,
filteredEvents,
gridScrollMetrics);
if (!hadGridScrollCapture &&
m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb) {
m_requestPointerCapture = true;
} else if (
hadGridScrollCapture &&
!m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb) {
m_requestPointerRelease = true;
}
RebuildLayout(panelState->bounds);
struct ProjectAssetDragCallbacks {
::XCEngine::UI::Widgets::UISelectionModel& assetSelection;
::XCEngine::UI::Widgets::UIExpansionModel& folderExpansion;
@@ -1822,10 +1698,6 @@ void ProjectPanel::Update(
}
std::string ResolveDraggableItem(const UIPoint& point) const {
if (!ContainsPoint(layout.gridScrollLayout.contentRect, point)) {
return {};
}
for (const AssetTileLayout& tile : layout.assetTiles) {
if (tile.itemIndex >= assetEntries.size()) {
continue;
@@ -1921,7 +1793,7 @@ void ProjectPanel::Update(
}
}
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
m_treeFrame.layout = Widgets::BuildUIEditorTreeViewLayout(
m_layout.treeRect,
GetBrowserModel().GetTreeItems(),
@@ -1973,7 +1845,7 @@ void ProjectPanel::Update(
if (m_splitterDragging) {
m_navigationWidth =
ClampNavigationWidth(event.position.x - panelState->bounds.x, panelState->bounds.width);
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
}
m_splitterHovered =
@@ -2008,7 +1880,7 @@ void ProjectPanel::Update(
m_pressedBreadcrumbIndex = HitTestBreadcrumbItem(event.position);
if (!ContainsPoint(m_layout.gridScrollLayout.contentRect, event.position)) {
if (!ContainsPoint(m_layout.gridRect, event.position)) {
break;
}
@@ -2049,7 +1921,7 @@ void ProjectPanel::Update(
}
if (event.pointerButton == ::XCEngine::UI::UIPointerButton::Right &&
ContainsPoint(m_layout.gridScrollLayout.contentRect, event.position)) {
ContainsPoint(m_layout.gridRect, event.position)) {
const auto& assetEntries = GetBrowserModel().GetAssetEntries();
const std::size_t hitIndex = HitTestAssetTile(event.position);
if (hitIndex >= assetEntries.size()) {
@@ -2094,7 +1966,7 @@ void ProjectPanel::Update(
m_layout.breadcrumbItems[releasedBreadcrumbIndex];
if (item.clickable) {
NavigateToFolder(item.targetFolderId, EventSource::Breadcrumb);
RebuildLayout(panelState->bounds);
m_layout = BuildLayout(panelState->bounds);
}
}
m_pressedBreadcrumbIndex = kInvalidLayoutIndex;
@@ -2157,15 +2029,6 @@ ProjectPanel::Layout ProjectPanel::BuildLayout(const UIRect& bounds) const {
layout.browserBodyRect.y + kGridInsetY,
ClampNonNegative(layout.browserBodyRect.width - kGridInsetX * 2.0f),
ClampNonNegative(layout.browserBodyRect.height - kGridInsetY * 2.0f));
const Widgets::UIEditorScrollViewMetrics gridScrollMetrics =
BuildProjectGridScrollMetrics();
int columnCount = 1;
layout.gridScrollLayout = BuildProjectGridScrollLayout(
layout.gridRect,
assetEntries.size(),
m_gridVerticalOffset,
gridScrollMetrics,
&columnCount);
const float breadcrumbRowHeight = kHeaderFontSize + kBreadcrumbItemPaddingY * 2.0f;
const float breadcrumbY =
@@ -2216,16 +2079,20 @@ ProjectPanel::Layout ProjectPanel::BuildLayout(const UIRect& bounds) const {
nextItemX += itemWidth + kBreadcrumbSpacing;
}
const UIPoint gridContentOrigin =
Widgets::ResolveUIEditorScrollViewContentOrigin(layout.gridScrollLayout);
const float effectiveTileWidth = kGridTileWidth + kGridTileGapX;
int columnCount = effectiveTileWidth > 0.0f
? static_cast<int>((layout.gridRect.width + kGridTileGapX) / effectiveTileWidth)
: 1;
if (columnCount < 1) {
columnCount = 1;
}
layout.assetTiles.reserve(assetEntries.size());
for (std::size_t index = 0; index < assetEntries.size(); ++index) {
const int column = static_cast<int>(index % static_cast<std::size_t>(columnCount));
const int row = static_cast<int>(index / static_cast<std::size_t>(columnCount));
const float tileX =
gridContentOrigin.x + static_cast<float>(column) * (kGridTileWidth + kGridTileGapX);
const float tileY =
gridContentOrigin.y + static_cast<float>(row) * (kGridTileHeight + kGridTileGapY);
const float tileX = layout.gridRect.x + static_cast<float>(column) * (kGridTileWidth + kGridTileGapX);
const float tileY = layout.gridRect.y + static_cast<float>(row) * (kGridTileHeight + kGridTileGapY);
AssetTileLayout tile = {};
tile.itemIndex = index;
@@ -2246,59 +2113,6 @@ ProjectPanel::Layout ProjectPanel::BuildLayout(const UIRect& bounds) const {
return layout;
}
void ProjectPanel::RebuildLayout(const UIRect& bounds) {
m_layout = BuildLayout(bounds);
m_gridVerticalOffset = m_layout.gridScrollLayout.verticalOffset;
}
void ProjectPanel::ResetGridScrollPosition() {
m_gridVerticalOffset = 0.0f;
m_gridScrollInteractionState.scrollViewState.draggingScrollbarThumb = false;
}
void ProjectPanel::EnsureAssetVisible(
std::string_view itemId,
const UIRect& bounds) {
if (itemId.empty() || !HasValidBounds(bounds)) {
return;
}
RebuildLayout(bounds);
const Widgets::UIEditorScrollViewMetrics gridScrollMetrics =
BuildProjectGridScrollMetrics();
const auto& assetEntries = GetBrowserModel().GetAssetEntries();
for (const AssetTileLayout& tile : m_layout.assetTiles) {
if (tile.itemIndex >= assetEntries.size()) {
continue;
}
if (assetEntries[tile.itemIndex].itemId != itemId) {
continue;
}
const UIRect& contentRect = m_layout.gridScrollLayout.contentRect;
float adjustedOffset = m_gridVerticalOffset;
const float tileBottom = tile.tileRect.y + tile.tileRect.height;
const float contentBottom = contentRect.y + contentRect.height;
if (tile.tileRect.y < contentRect.y) {
adjustedOffset -= contentRect.y - tile.tileRect.y;
} else if (tileBottom > contentBottom) {
adjustedOffset += tileBottom - contentBottom;
}
adjustedOffset = Widgets::ClampUIEditorScrollViewOffset(
m_layout.gridScrollLayout.bounds,
m_layout.gridScrollLayout.contentHeight,
adjustedOffset,
gridScrollMetrics);
if (std::abs(adjustedOffset - m_gridVerticalOffset) > 0.01f) {
m_gridVerticalOffset = adjustedOffset;
RebuildLayout(bounds);
}
return;
}
}
std::size_t ProjectPanel::HitTestBreadcrumbItem(const UIPoint& point) const {
for (std::size_t index = 0u; index < m_layout.breadcrumbItems.size(); ++index) {
const BreadcrumbItemLayout& item = m_layout.breadcrumbItems[index];
@@ -2311,10 +2125,6 @@ std::size_t ProjectPanel::HitTestBreadcrumbItem(const UIPoint& point) const {
}
std::size_t ProjectPanel::HitTestAssetTile(const UIPoint& point) const {
if (!ContainsPoint(m_layout.gridScrollLayout.contentRect, point)) {
return kInvalidLayoutIndex;
}
for (const AssetTileLayout& tile : m_layout.assetTiles) {
if (ContainsPoint(tile.tileRect, point)) {
return tile.itemIndex;
@@ -2385,16 +2195,6 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
m_layout.browserHeaderRect.width,
kHeaderBottomBorderThickness),
ResolveUIEditorDockHostPalette().splitterColor);
const Widgets::UIEditorScrollViewPalette gridScrollPalette =
BuildProjectGridScrollPalette();
const Widgets::UIEditorScrollViewMetrics gridScrollMetrics =
BuildProjectGridScrollMetrics();
AppendUIEditorScrollViewBackground(
drawList,
m_layout.gridScrollLayout,
m_gridScrollInteractionState.scrollViewState,
gridScrollPalette,
gridScrollMetrics);
const Widgets::UIEditorTreeViewPalette treePalette = ResolveUIEditorTreeViewPalette();
const Widgets::UIEditorTreeViewMetrics treeMetrics = ResolveUIEditorTreeViewMetrics();
@@ -2474,7 +2274,6 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
}
drawList.PopClipRect();
drawList.PushClipRect(m_layout.gridScrollLayout.contentRect);
for (const AssetTileLayout& tile : m_layout.assetTiles) {
if (tile.itemIndex >= assetEntries.size()) {
continue;
@@ -2540,7 +2339,6 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
break;
}
}
drawList.PopClipRect();
if (m_renameState.active) {
const Widgets::UIEditorTextFieldPalette textFieldPalette =
@@ -2553,30 +2351,19 @@ void ProjectPanel::Append(UIDrawList& drawList) const {
BuildUIEditorPropertyGridTextFieldMetrics(
ResolveUIEditorPropertyGridMetrics(),
ResolveUIEditorTextFieldMetrics()));
if (m_activeRenameSurface == RenameSurface::Grid) {
drawList.PushClipRect(m_layout.gridScrollLayout.contentRect);
AppendUIEditorInlineRenameSession(
drawList,
m_renameFrame,
m_renameState,
textFieldPalette,
textFieldMetrics);
drawList.PopClipRect();
} else {
AppendUIEditorInlineRenameSession(
drawList,
m_renameFrame,
m_renameState,
textFieldPalette,
textFieldMetrics);
}
AppendUIEditorInlineRenameSession(
drawList,
m_renameFrame,
m_renameState,
textFieldPalette,
textFieldMetrics);
}
if (assetEntries.empty()) {
const UIRect messageRect(
m_layout.gridScrollLayout.contentRect.x,
m_layout.gridScrollLayout.contentRect.y,
m_layout.gridScrollLayout.contentRect.width,
m_layout.gridRect.x,
m_layout.gridRect.y,
m_layout.gridRect.width,
18.0f);
drawList.AddText(
UIPoint(messageRect.x, ResolveTextTop(messageRect.y, messageRect.height, kHeaderFontSize)),