feat(ui): move editing context breadcrumb to viewport overlay (#232) #236
@@ -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