Skip to content

Complete bottom context panel slice - #455

Merged
fernandotonon merged 5 commits into
masterfrom
codex/bottom-context-panel-slice
May 9, 2026
Merged

Complete bottom context panel slice#455
fernandotonon merged 5 commits into
masterfrom
codex/bottom-context-panel-slice

Conversation

@fernandotonon

@fernandotonon fernandotonon commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • complete the bottom context panel slice with mode-specific summaries and keep the bottom panel informational
  • move workspace panel shortcuts into the Mode Tools tab and make the Context panel visible by default
  • tighten viewport dock/title-bar layout, trim the G/N/I/C button sizing, and update the default startup window size
  • address review feedback around dock redocking test stability and breadcrumb coverage for QML-triggered bottom-tool reveals

Testing

  • qmllint qml/ModeBar.qml qml/PropertiesPanel.qml qml/BottomContextPanel.qml
  • cmake --build build_local --target UnitTests -j"$(nproc)"
  • env QT_QPA_PLATFORM=offscreen build_local/bin/UnitTests --gtest_filter=MainWindowTest.BottomContextPanelLoadsAndTracksCurrentMode:MainWindowTest.BottomToolRevealTabsContextWithOtherBottomTools:MainWindowTest.BottomToolRevealReturnsDetachedContextDockToBottomArea:MainWindowTest.ModeBarLoadsAndModeChangeUpdatesStatusIndicator
  • env QT_QPA_PLATFORM=offscreen build_local/bin/UnitTests --gtest_filter=EditorViewportTest.OgreWidgetStartsFlushBelowTitleBar:EditorViewportTest.PaintEventDoesNotOverridePaletteForFocusedViewport
  • cmake --build build_local --target QtMeshEditor -j"$(nproc)"

Part of #391.

Summary by CodeRabbit

  • New Features

    • Workspace Panels shortcuts added for Context, Asset Browser, Dope Sheet, and Curve Editor.
    • Bottom context panel shows expanded, mode-specific summary info (objects, edit/animation/material/validation details) and exposes which summary is active.
    • Programmatic reveal of bottom tools from the UI.
  • Changes

    • Removed Edit/Exit Edit button from the mode bar.
    • Summary UI removes inline playback/validate/fix buttons and surfaces status/availability fields instead.
    • Viewport and window sizing/spacing adjusted for tighter layout.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 9, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 95f949f4-6792-4c79-9777-ce4907fe8c8c

📥 Commits

Reviewing files that changed from the base of the PR and between 2a9584e and a27d012.

📒 Files selected for processing (1)
  • src/EditorViewport_test.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/EditorViewport_test.cpp

📝 Walkthrough

Walkthrough

Adds QML/C++ wiring to reveal bottom-docked tools from the UI, refactors BottomContextPanel summaries (new helper functions and Loader), updates PropertiesPanel to host bottom-tool shortcuts, ensures dock tabification is allowed, tweaks viewport/title-bar sizing and layout margins, and adds tests for mode-tracking and dock behavior.

Changes

Bottom Tool Reveal & Enhanced Summary UI

Layer / File(s) Summary
Public Contracts
src/mainwindow.h, qml/BottomContextPanel.qml, qml/PropertiesPanel.qml
Declare MainWindow::revealBottomTool(toolId); add currentSummaryObjectName, issueSummary(), fileSummary(), rootFolderName() on BottomContextPanel root; add bottomToolHost and revealBottomTool(toolId) helper in PropertiesPanel.
Loader & Header
qml/BottomContextPanel.qml
Import AssetBrowser 1.0; replace header expand control with ToolButton (bottomContextExpandButton); add Loader summaryLoader (bottomContextSummaryLoader).
Summary UI Refactor
qml/BottomContextPanel.qml
Refactor object/edit/animation/material/validation summaries into ColumnLayout roots with expanded fields; replace inline action buttons with status/summary fields and use issueSummary() for findings.
ModeBar Layout
qml/ModeBar.qml
Remove Edit/Exit Edit button and add flexible Item to fill remaining space in the mode bar.
PropertiesPanel Workspace
qml/PropertiesPanel.qml
Add “Workspace Panels” CollapsibleSection and workspacePanelsComponent with ModeToolShortcutButton shortcuts that call root.revealBottomTool(...).
C++ Implementation
src/mainwindow.cpp
Set bottomToolHost on the QML properties panel root; reveal the context dock on creation; implement MainWindow::revealBottomTool(toolId) mapping IDs to bottom docks and showing/tabifying them; enable QMainWindow::AllowTabbedDocks before tabifying.
EditorViewport Layout
src/EditorViewport.cpp
Enforce zero contents margins on the dock’s internal layout after creating the OgreWidget and after title-bar setup.
ViewportTitleBar Sizing
src/ViewportTitleBar.cpp
Adjust bar/button/icon constants and set a new pixel font size kViewportButtonFontPixelSize for compact viewport letter buttons.
UI Layout
ui_files/mainwindow.ui
Update MainWindow default geometry and menu bar width.
Tests
src/mainwindow_test.cpp, src/EditorViewport_test.cpp
Add MainWindow tests for currentSummaryObjectName mode tracking, revealBottomTool tabification and re-docking; add EditorViewport geometry test verifying OgreWidget flush below title bar.

Sequence Diagram(s)

sequenceDiagram
  participant User as User / UI
  participant QML as BottomContextPanel / PropertiesPanel
  participant CPP as MainWindow
  participant Dock as Bottom Docks

  User->>QML: Click workspace shortcut (e.g., "Asset Browser")
  QML->>CPP: revealBottomTool("assetBrowser") via bottomToolHost
  CPP->>CPP: map toolId -> dock widget
  CPP->>CPP: enable AllowTabbedDocks flag
  CPP->>Dock: showBottomToolDock(selectedDock)
  Dock->>Dock: show & tabify with other bottom docks
  Dock->>QML: Dock becomes visible in bottom area
  QML->>User: UI reflects active bottom tool
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A rabbit hops from dock to pane,
Buttons shimmer, shortcuts reign—
Panels wake with one small click,
Summaries tidy, margins slick.
Tiny hops, big UI cheer!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Complete bottom context panel slice' accurately summarizes the main change—completing the bottom context panel feature with mode-specific summaries and integration improvements.
Description check ✅ Passed The description provides a clear summary section with specific details and includes a comprehensive testing section, though it deviates from the template by omitting Technical Details, Features, and Bugfixes headings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/bottom-context-panel-slice

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mainwindow_test.cpp`:
- Around line 390-407: The test
BottomToolRevealReturnsDetachedContextDockToBottomArea can be flaky because the
dock may not enter floating state when the main window isn't shown; before
calling window->m_bottomContextDock->setFloating(true) in MainWindowTest, call
window->show() and then app->processEvents() to ensure the window is visible to
Qt's state machine, then proceed with setFloating(true), app->processEvents(),
hide(), revealBottomTool(...), and the subsequent assertions.

In `@src/mainwindow.cpp`:
- Around line 1732-1746: revealBottomTool currently shows the requested dock
(m_bottomContextDock, m_assetBrowserDock, m_dopeSheetDock, m_curveEditorDock)
but does not emit telemetry; add a Sentry breadcrumb at the start of
MainWindow::revealBottomTool using SentryReporter::addBreadcrumb("ui.action",
"<Rail: Name>") where the message matches the existing rail labels (e.g., "Rail:
Dope Sheet", "Rail: Curve Editor", "Rail: Asset Browser", "Rail: Context")
depending on which toolId branch is taken, then call showBottomToolDock(dock) as
before so all QML-initiated reveals are tracked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a2e9987-0710-43da-bca7-6994bd09f4cf

📥 Commits

Reviewing files that changed from the base of the PR and between f56b4b4 and 1f1ff2d.

📒 Files selected for processing (4)
  • qml/BottomContextPanel.qml
  • src/mainwindow.cpp
  • src/mainwindow.h
  • src/mainwindow_test.cpp

Comment thread src/mainwindow_test.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/EditorViewport_test.cpp (1)

144-146: ⚡ Quick win

Harden geometry assertion timing to reduce CI flakiness.

At Line 144-Line 146, a single processEvents() after show() can still race with final geometry updates. Consider waiting for exposure/visibility before reading geometry().

Proposed patch
     viewport.resize(640, 360);
     viewport.show();
-    app->processEvents();
+    app->processEvents();
+    QTRY_VERIFY(viewport.isVisible());
+    QTRY_VERIFY(viewport.getOgreWidget()->isVisible());
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/EditorViewport_test.cpp` around lines 144 - 146, The current test calls
viewport.show() then a single app->processEvents() before reading
viewport.geometry(), which can race with final geometry updates; replace the
single processEvents() with a deterministic wait for the widget/window to be
exposed/visible (for example use QTest::qWaitForWindowExposed(&viewport) or wait
on QWindow::exposed/QWindow::visibilityChanged or poll QWidget::isVisible() with
processEvents) before calling geometry() so the geometry reflects the final
displayed size.
src/ViewportTitleBar.cpp (1)

177-179: ⚡ Quick win

Avoid hard-locking viewport button text to 8px.

At Line 178, forcing a fixed pixel size can make labels too small under DPI scaling/accessibility font settings. Prefer scaling relative to the current font and clamping a minimum.

Proposed patch
-    QFont buttonFont = button->font();
-    buttonFont.setPixelSize(kViewportButtonFontPixelSize);
-    button->setFont(buttonFont);
+    QFont buttonFont = button->font();
+    if (buttonFont.pointSizeF() > 0.0) {
+        buttonFont.setPointSizeF(qMax(7.0, buttonFont.pointSizeF() - 1.0));
+    } else if (buttonFont.pixelSize() > 0) {
+        buttonFont.setPixelSize(qMax(8, buttonFont.pixelSize() - 1));
+    } else {
+        buttonFont.setPixelSize(kViewportButtonFontPixelSize);
+    }
+    button->setFont(buttonFont);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ViewportTitleBar.cpp` around lines 177 - 179, The code currently forces a
fixed pixel size via kViewportButtonFontPixelSize on the button's QFont (QFont
buttonFont; buttonFont.setPixelSize(kViewportButtonFontPixelSize);
button->setFont(buttonFont)); change this to scale relative to the button's
existing font size and clamp a sensible minimum: read the current font size (use
pixelSize() or pointSizeF()), compute a scaled size (respecting devicePixelRatio
or QFontMetrics scaling) and ensure it is at least a minimum value, then apply
that size with setPixelSize or setPointSizeF before calling button->setFont;
reference QFont, buttonFont, kViewportButtonFontPixelSize, setPixelSize, and
setFont when locating and updating the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mainwindow.cpp`:
- Around line 1734-1763: revealBottomTool currently silently ignores unknown
toolId values; update it to explicitly handle the default/unknown case by adding
an else branch that logs a clear breadcrumb via SentryReporter::addBreadcrumb
(e.g., "ui.action" and a message like "Rail: Unknown bottom tool: <toolId>") and
optionally report or assert as appropriate, then avoid calling
showBottomToolDock; place this logic in MainWindow::revealBottomTool alongside
the existing branches (referencing revealBottomTool,
SentryReporter::addBreadcrumb, and showBottomToolDock) so missed QML wiring or
invalid IDs are recorded rather than being a silent no-op.

---

Nitpick comments:
In `@src/EditorViewport_test.cpp`:
- Around line 144-146: The current test calls viewport.show() then a single
app->processEvents() before reading viewport.geometry(), which can race with
final geometry updates; replace the single processEvents() with a deterministic
wait for the widget/window to be exposed/visible (for example use
QTest::qWaitForWindowExposed(&viewport) or wait on
QWindow::exposed/QWindow::visibilityChanged or poll QWidget::isVisible() with
processEvents) before calling geometry() so the geometry reflects the final
displayed size.

In `@src/ViewportTitleBar.cpp`:
- Around line 177-179: The code currently forces a fixed pixel size via
kViewportButtonFontPixelSize on the button's QFont (QFont buttonFont;
buttonFont.setPixelSize(kViewportButtonFontPixelSize);
button->setFont(buttonFont)); change this to scale relative to the button's
existing font size and clamp a sensible minimum: read the current font size (use
pixelSize() or pointSizeF()), compute a scaled size (respecting devicePixelRatio
or QFontMetrics scaling) and ensure it is at least a minimum value, then apply
that size with setPixelSize or setPointSizeF before calling button->setFont;
reference QFont, buttonFont, kViewportButtonFontPixelSize, setPixelSize, and
setFont when locating and updating the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 73c97547-7de3-4e25-a5b2-9024278800e5

📥 Commits

Reviewing files that changed from the base of the PR and between 1f1ff2d and 2a9584e.

📒 Files selected for processing (9)
  • qml/BottomContextPanel.qml
  • qml/ModeBar.qml
  • qml/PropertiesPanel.qml
  • src/EditorViewport.cpp
  • src/EditorViewport_test.cpp
  • src/ViewportTitleBar.cpp
  • src/mainwindow.cpp
  • src/mainwindow_test.cpp
  • ui_files/mainwindow.ui
💤 Files with no reviewable changes (1)
  • qml/ModeBar.qml
✅ Files skipped from review due to trivial changes (1)
  • ui_files/mainwindow.ui

Comment thread src/mainwindow.cpp
Comment on lines +1734 to +1763
void MainWindow::revealBottomTool(const QString& toolId)
{
QDockWidget* dock = nullptr;
QString breadcrumb;
if (toolId == QStringLiteral("context"))
{
dock = m_bottomContextDock;
breadcrumb = QStringLiteral("Rail: Context");
}
else if (toolId == QStringLiteral("assetBrowser"))
{
dock = m_assetBrowserDock;
breadcrumb = QStringLiteral("Rail: Asset Browser");
}
else if (toolId == QStringLiteral("dopeSheet"))
{
dock = m_dopeSheetDock;
breadcrumb = QStringLiteral("Rail: Dope Sheet");
}
else if (toolId == QStringLiteral("curveEditor"))
{
dock = m_curveEditorDock;
breadcrumb = QStringLiteral("Rail: Curve Editor");
}

if (dock) {
SentryReporter::addBreadcrumb("ui.action", breadcrumb);
showBottomToolDock(dock);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle unknown bottom-tool IDs explicitly in revealBottomTool.

Right now unknown toolId values are a silent no-op, which makes QML wiring mistakes hard to diagnose and leaves attempted user actions untracked.

🔧 Suggested hardening
 void MainWindow::revealBottomTool(const QString& toolId)
 {
     QDockWidget* dock = nullptr;
     QString breadcrumb;
@@
     else if (toolId == QStringLiteral("curveEditor"))
     {
         dock = m_curveEditorDock;
         breadcrumb = QStringLiteral("Rail: Curve Editor");
     }
 
-    if (dock) {
-        SentryReporter::addBreadcrumb("ui.action", breadcrumb);
-        showBottomToolDock(dock);
-    }
+    if (!dock) {
+        SentryReporter::addBreadcrumb(
+            "ui.action",
+            QStringLiteral("Rail: Unknown bottom tool (%1)").arg(toolId));
+        return;
+    }
+
+    SentryReporter::addBreadcrumb("ui.action", breadcrumb);
+    showBottomToolDock(dock);
 }

As per coding guidelines, "All user-facing actions and significant operations must be tracked with SentryReporter::addBreadcrumb(category, message)."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void MainWindow::revealBottomTool(const QString& toolId)
{
QDockWidget* dock = nullptr;
QString breadcrumb;
if (toolId == QStringLiteral("context"))
{
dock = m_bottomContextDock;
breadcrumb = QStringLiteral("Rail: Context");
}
else if (toolId == QStringLiteral("assetBrowser"))
{
dock = m_assetBrowserDock;
breadcrumb = QStringLiteral("Rail: Asset Browser");
}
else if (toolId == QStringLiteral("dopeSheet"))
{
dock = m_dopeSheetDock;
breadcrumb = QStringLiteral("Rail: Dope Sheet");
}
else if (toolId == QStringLiteral("curveEditor"))
{
dock = m_curveEditorDock;
breadcrumb = QStringLiteral("Rail: Curve Editor");
}
if (dock) {
SentryReporter::addBreadcrumb("ui.action", breadcrumb);
showBottomToolDock(dock);
}
}
void MainWindow::revealBottomTool(const QString& toolId)
{
QDockWidget* dock = nullptr;
QString breadcrumb;
if (toolId == QStringLiteral("context"))
{
dock = m_bottomContextDock;
breadcrumb = QStringLiteral("Rail: Context");
}
else if (toolId == QStringLiteral("assetBrowser"))
{
dock = m_assetBrowserDock;
breadcrumb = QStringLiteral("Rail: Asset Browser");
}
else if (toolId == QStringLiteral("dopeSheet"))
{
dock = m_dopeSheetDock;
breadcrumb = QStringLiteral("Rail: Dope Sheet");
}
else if (toolId == QStringLiteral("curveEditor"))
{
dock = m_curveEditorDock;
breadcrumb = QStringLiteral("Rail: Curve Editor");
}
if (!dock) {
SentryReporter::addBreadcrumb(
"ui.action",
QStringLiteral("Rail: Unknown bottom tool (%1)").arg(toolId));
return;
}
SentryReporter::addBreadcrumb("ui.action", breadcrumb);
showBottomToolDock(dock);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mainwindow.cpp` around lines 1734 - 1763, revealBottomTool currently
silently ignores unknown toolId values; update it to explicitly handle the
default/unknown case by adding an else branch that logs a clear breadcrumb via
SentryReporter::addBreadcrumb (e.g., "ui.action" and a message like "Rail:
Unknown bottom tool: <toolId>") and optionally report or assert as appropriate,
then avoid calling showBottomToolDock; place this logic in
MainWindow::revealBottomTool alongside the existing branches (referencing
revealBottomTool, SentryReporter::addBreadcrumb, and showBottomToolDock) so
missed QML wiring or invalid IDs are recorded rather than being a silent no-op.

@sonarqubecloud

sonarqubecloud Bot commented May 9, 2026

Copy link
Copy Markdown

@fernandotonon
fernandotonon merged commit 988e7d6 into master May 9, 2026
17 checks passed
@fernandotonon
fernandotonon deleted the codex/bottom-context-panel-slice branch May 9, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant