feat(ui): move editing context breadcrumb to viewport overlay (#232)
Some checks failed
Build and Test / build (pull_request) Has been cancelled
Some checks failed
Build and Test / build (pull_request) Has been cancelled
Convert BreadcrumbToolBar from a QToolBar in the MainWindow toolbar area to a QFrame overlay at the top-left of each 3D viewport. Changes: - BreadcrumbToolBar: change base class from QToolBar to QFrame, use QHBoxLayout instead of toolbar actions, semi-transparent overlay background with rounded corners - MainWindow: remove breadcrumb toolbar creation, toolbar break, and signal connection - View3DInventor: create per-view BreadcrumbToolBar as a child of the GL viewer widget, positioned at (8,8) with event filter to keep it raised on viewport resize Each 3D view now has its own breadcrumb instance connected to the EditingContextResolver singleton. This reclaims the full-width toolbar row and keeps the editing context visually tied to the viewport.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "EditingContext.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
|
||||
@@ -40,7 +41,6 @@ using namespace Gui;
|
||||
|
||||
static QString chipStyle(const QString& bgHex)
|
||||
{
|
||||
// Darken background slightly for contrast, use white text
|
||||
QColor bg(bgHex);
|
||||
QColor textColor(QStringLiteral("#cdd6f4")); // Catppuccin Text
|
||||
|
||||
@@ -81,24 +81,25 @@ static QString separatorStyle()
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
BreadcrumbToolBar::BreadcrumbToolBar(QWidget* parent)
|
||||
: QToolBar(parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setObjectName(QStringLiteral("BreadcrumbToolBar"));
|
||||
setWindowTitle(tr("Editing Context"));
|
||||
setMovable(false);
|
||||
setFloatable(false);
|
||||
setIconSize(QSize(16, 16));
|
||||
|
||||
// Thin toolbar with minimal margins
|
||||
_layout = new QHBoxLayout(this);
|
||||
_layout->setContentsMargins(6, 4, 6, 4);
|
||||
_layout->setSpacing(2);
|
||||
|
||||
// Semi-transparent overlay background
|
||||
setStyleSheet(QStringLiteral(
|
||||
"QToolBar {"
|
||||
" background: #1e1e2e;" // Catppuccin Base
|
||||
" border: none;"
|
||||
" spacing: 2px;"
|
||||
" padding: 2px 4px;"
|
||||
" max-height: 24px;"
|
||||
"QFrame#BreadcrumbToolBar {"
|
||||
" background-color: rgba(30, 30, 46, 200);" // Catppuccin Base, ~78% opacity
|
||||
" border: 1px solid rgba(69, 71, 90, 150);" // Surface1
|
||||
" border-radius: 6px;"
|
||||
"}"
|
||||
));
|
||||
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
setFixedHeight(28);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +111,7 @@ void BreadcrumbToolBar::updateContext(const EditingContext& ctx)
|
||||
{
|
||||
clearSegments();
|
||||
buildSegments(ctx);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -120,17 +122,16 @@ void BreadcrumbToolBar::updateContext(const EditingContext& ctx)
|
||||
void BreadcrumbToolBar::clearSegments()
|
||||
{
|
||||
for (auto* btn : _segments) {
|
||||
removeAction(btn->defaultAction());
|
||||
_layout->removeWidget(btn);
|
||||
delete btn;
|
||||
}
|
||||
_segments.clear();
|
||||
|
||||
for (auto* sep : _separators) {
|
||||
_layout->removeWidget(sep);
|
||||
delete sep;
|
||||
}
|
||||
_separators.clear();
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void BreadcrumbToolBar::buildSegments(const EditingContext& ctx)
|
||||
@@ -144,7 +145,7 @@ void BreadcrumbToolBar::buildSegments(const EditingContext& ctx)
|
||||
if (i > 0) {
|
||||
auto* sep = new QLabel(QStringLiteral("\u203A")); // › character
|
||||
sep->setStyleSheet(separatorStyle());
|
||||
addWidget(sep);
|
||||
_layout->addWidget(sep);
|
||||
_separators.append(sep);
|
||||
}
|
||||
|
||||
@@ -168,7 +169,7 @@ void BreadcrumbToolBar::buildSegments(const EditingContext& ctx)
|
||||
segmentClicked(segmentIndex);
|
||||
});
|
||||
|
||||
addWidget(btn);
|
||||
_layout->addWidget(btn);
|
||||
_segments.append(btn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
#ifndef GUI_BREADCRUMBTOOLBAR_H
|
||||
#define GUI_BREADCRUMBTOOLBAR_H
|
||||
|
||||
#include <QToolBar>
|
||||
#include <QFrame>
|
||||
#include <QList>
|
||||
#include <FCGlobal.h>
|
||||
|
||||
class QHBoxLayout;
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
|
||||
@@ -38,11 +39,14 @@ namespace Gui
|
||||
struct EditingContext;
|
||||
|
||||
/**
|
||||
* A thin toolbar that displays the current editing context as color-coded
|
||||
* breadcrumb segments. Each segment is a clickable QToolButton; clicking
|
||||
* a parent segment navigates up (exits the current edit, etc.).
|
||||
* A small overlay widget that displays the current editing context as
|
||||
* color-coded breadcrumb segments. Each segment is a clickable QToolButton;
|
||||
* clicking a parent segment navigates up (exits the current edit, etc.).
|
||||
*
|
||||
* Intended to be parented to the 3D viewport widget so it floats at the
|
||||
* top-left corner of the view.
|
||||
*/
|
||||
class GuiExport BreadcrumbToolBar: public QToolBar
|
||||
class GuiExport BreadcrumbToolBar: public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -59,6 +63,7 @@ private:
|
||||
void clearSegments();
|
||||
void buildSegments(const EditingContext& ctx);
|
||||
|
||||
QHBoxLayout* _layout;
|
||||
QList<QToolButton*> _segments;
|
||||
QList<QLabel*> _separators;
|
||||
};
|
||||
|
||||
@@ -105,8 +105,7 @@
|
||||
#include "SelectionView.h"
|
||||
#include "SplashScreen.h"
|
||||
#include "StatusBarLabel.h"
|
||||
#include "BreadcrumbToolBar.h"
|
||||
#include "EditingContext.h"
|
||||
|
||||
#include "ToolBarManager.h"
|
||||
#include "ToolBoxManager.h"
|
||||
#include "Tree.h"
|
||||
@@ -307,7 +306,6 @@ struct MainWindowP
|
||||
QLabel* actionLabel;
|
||||
InputHintWidget* hintLabel;
|
||||
QLabel* rightSideLabel;
|
||||
BreadcrumbToolBar* breadcrumbBar = nullptr;
|
||||
QTimer* actionTimer;
|
||||
QTimer* statusTimer;
|
||||
QTimer* activityTimer;
|
||||
@@ -492,20 +490,6 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags f)
|
||||
#endif
|
||||
connect(d->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::onWindowActivated);
|
||||
|
||||
// Breadcrumb toolbar for editing context display
|
||||
d->breadcrumbBar = new BreadcrumbToolBar(this);
|
||||
addToolBar(Qt::TopToolBarArea, d->breadcrumbBar);
|
||||
insertToolBarBreak(d->breadcrumbBar);
|
||||
|
||||
// Initialize the editing context resolver and connect to breadcrumb
|
||||
auto* ctxResolver = EditingContextResolver::instance();
|
||||
connect(
|
||||
ctxResolver,
|
||||
&EditingContextResolver::contextChanged,
|
||||
d->breadcrumbBar,
|
||||
&BreadcrumbToolBar::updateContext
|
||||
);
|
||||
|
||||
setupDockWindows();
|
||||
|
||||
// accept drops on the window, get handled in dropEvent, dragEnterEvent
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
#include "View3DInventor.h"
|
||||
#include "View3DSettings.h"
|
||||
#include "Application.h"
|
||||
#include "BreadcrumbToolBar.h"
|
||||
#include "BitmapFactory.h"
|
||||
#include "EditingContext.h"
|
||||
#include "Camera.h"
|
||||
#include "Document.h"
|
||||
#include "FileDialog.h"
|
||||
@@ -145,6 +147,19 @@ View3DInventor::View3DInventor(
|
||||
// apply the user settings
|
||||
applySettings();
|
||||
|
||||
// Breadcrumb overlay at top-left of viewport
|
||||
_breadcrumb = new BreadcrumbToolBar(_viewer->getWidget());
|
||||
_breadcrumb->move(8, 8);
|
||||
_breadcrumb->raise();
|
||||
_breadcrumb->show();
|
||||
_viewer->getWidget()->installEventFilter(this);
|
||||
|
||||
auto* ctxResolver = EditingContextResolver::instance();
|
||||
connect(ctxResolver, &EditingContextResolver::contextChanged,
|
||||
_breadcrumb, &BreadcrumbToolBar::updateContext);
|
||||
// Apply the current context immediately
|
||||
_breadcrumb->updateContext(ctxResolver->currentContext());
|
||||
|
||||
stopSpinTimer = new QTimer(this);
|
||||
connect(stopSpinTimer, &QTimer::timeout, this, &View3DInventor::stopAnimating);
|
||||
|
||||
@@ -935,6 +950,17 @@ void View3DInventor::contextMenuEvent(QContextMenuEvent* e)
|
||||
MDIView::contextMenuEvent(e);
|
||||
}
|
||||
|
||||
bool View3DInventor::eventFilter(QObject* obj, QEvent* ev)
|
||||
{
|
||||
if (obj == _viewer->getWidget() && ev->type() == QEvent::Resize) {
|
||||
// Keep breadcrumb at top-left after viewport resize
|
||||
if (_breadcrumb) {
|
||||
_breadcrumb->raise();
|
||||
}
|
||||
}
|
||||
return MDIView::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void View3DInventor::customEvent(QEvent* e)
|
||||
{
|
||||
if (e->type() == QEvent::User) {
|
||||
|
||||
@@ -40,6 +40,7 @@ class QStackedWidget;
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
class BreadcrumbToolBar;
|
||||
class Document;
|
||||
class View3DInventorViewer;
|
||||
class View3DPy;
|
||||
@@ -155,11 +156,13 @@ protected:
|
||||
void keyPressEvent(QKeyEvent* e) override;
|
||||
void keyReleaseEvent(QKeyEvent* e) override;
|
||||
void focusInEvent(QFocusEvent* e) override;
|
||||
bool eventFilter(QObject* obj, QEvent* ev) override;
|
||||
void customEvent(QEvent* e) override;
|
||||
void contextMenuEvent(QContextMenuEvent* e) override;
|
||||
|
||||
private:
|
||||
View3DInventorViewer* _viewer;
|
||||
BreadcrumbToolBar* _breadcrumb;
|
||||
PyObject* _viewerPy;
|
||||
QTimer* stopSpinTimer;
|
||||
QStackedWidget* stack;
|
||||
|
||||
Reference in New Issue
Block a user