diff --git a/src/Gui/BreadcrumbToolBar.cpp b/src/Gui/BreadcrumbToolBar.cpp index 8eaff9216a..f6fd3de4c8 100644 --- a/src/Gui/BreadcrumbToolBar.cpp +++ b/src/Gui/BreadcrumbToolBar.cpp @@ -26,6 +26,7 @@ #include "EditingContext.h" #include +#include #include #include @@ -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); } } diff --git a/src/Gui/BreadcrumbToolBar.h b/src/Gui/BreadcrumbToolBar.h index 13558aaab4..082f126bc0 100644 --- a/src/Gui/BreadcrumbToolBar.h +++ b/src/Gui/BreadcrumbToolBar.h @@ -25,10 +25,11 @@ #ifndef GUI_BREADCRUMBTOOLBAR_H #define GUI_BREADCRUMBTOOLBAR_H -#include +#include #include #include +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 _segments; QList _separators; }; diff --git a/src/Gui/MainWindow.cpp b/src/Gui/MainWindow.cpp index 159cf60cf7..7be5dc5c22 100644 --- a/src/Gui/MainWindow.cpp +++ b/src/Gui/MainWindow.cpp @@ -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 diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 2dab86ec05..81719fea91 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -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) { diff --git a/src/Gui/View3DInventor.h b/src/Gui/View3DInventor.h index c3afe5fdee..7a860dfee5 100644 --- a/src/Gui/View3DInventor.h +++ b/src/Gui/View3DInventor.h @@ -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;