Make mode hiding and style available from mode selector

Add the View > Modes menu as a context menu to the mode selector in the
emtpy areas. Add a context menu with "Hide" and the mode style to the
modes that don't have a menu, and extend existing mode menus (Debug
mode) with these items too.

Change-Id: I28106d9b6c4f0d69b2d06c4ec9664eb67e2b1216
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Eike Ziller
2024-07-09 15:57:48 +02:00
parent d386421998
commit e1560a3c7c
9 changed files with 105 additions and 47 deletions

View File

@@ -212,11 +212,10 @@ void FancyTabBar::mousePressEvent(QMouseEvent *event)
continue;
const QRect rect = tabRect(visibleIndex);
if (rect.contains(event->pos())) {
if (isTabEnabled(index)) {
if (isTabEnabled(index) && event->button() == Qt::LeftButton) {
if (m_tabs.at(index)->hasMenu
&& ((!m_iconsOnly && rect.right() - event->pos().x() <= kMenuButtonWidth)
|| event->button() == Qt::RightButton)) {
// menu arrow clicked or right-click
&& (!m_iconsOnly && rect.right() - event->pos().x() <= kMenuButtonWidth)) {
// menu arrow clicked
emit menuTriggered(index, event);
} else {
if (index != m_currentIndex) {
@@ -226,11 +225,16 @@ void FancyTabBar::mousePressEvent(QMouseEvent *event)
emit currentChanged(m_currentIndex);
}
}
} else if (event->button() == Qt::RightButton) {
emit menuTriggered(index, event);
}
break;
return;
}
++visibleIndex;
}
// not in a mode button
if (event->button() == Qt::RightButton)
emit menuTriggered(-1, event);
}
static void paintSelectedTabBackground(QPainter *painter, const QRect &spanRect)
@@ -457,7 +461,7 @@ public:
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
}
void mousePressEvent(QMouseEvent *ev) override { emit clicked(ev->button(), ev->modifiers()); }
void mousePressEvent(QMouseEvent *ev) override { emit clicked(ev); }
void paintEvent(QPaintEvent *event) override
{
@@ -475,7 +479,7 @@ public:
}
signals:
void clicked(Qt::MouseButton button, Qt::KeyboardModifiers modifiers);
void clicked(QMouseEvent *ev);
};
//////
@@ -490,7 +494,12 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
auto bar = new StyledBar;
auto fancyButton = new FancyColorButton;
connect(fancyButton, &FancyColorButton::clicked, this, &FancyTabWidget::topAreaClicked);
connect(fancyButton, &FancyColorButton::clicked, this, [this](QMouseEvent *event) {
if (event->button() == Qt::RightButton)
emit menuTriggered(-1, event);
else
emit topAreaClicked(event);
});
m_modesStack = new QStackedLayout;
m_modesStack->addWidget(new QWidget(this));
@@ -499,6 +508,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
QVBoxLayout *vlayout;
// clang-format off
using namespace Layouting;
Row { fancyButton, noMargin }.attachTo(bar);
Row {
@@ -507,10 +517,9 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
Column {
bar,
m_tabBar,
st,
Widget {
bindTo(&m_cornerWidgetContainer),
Column { st, spacing(0), noMargin },
Column { spacing(0), noMargin },
},
spacing(0), noMargin,
},
@@ -518,6 +527,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
Column { bindTo(&vlayout), m_modesStack, m_statusBar, spacing(0) },
spacing(1), noMargin,
}.attachTo(this);
// clang-format on
m_selectionWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);

View File

@@ -156,7 +156,7 @@ signals:
void currentAboutToShow(int index);
void currentChanged(int index);
void menuTriggered(int index, QMouseEvent *event);
void topAreaClicked(Qt::MouseButton button, Qt::KeyboardModifiers modifiers);
void topAreaClicked(QMouseEvent *event);
public slots:
void setCurrentIndex(int index);

View File

@@ -79,6 +79,7 @@
#include <QDebug>
#include <QDialogButtonBox>
#include <QLibraryInfo>
#include <QLoggingCategory>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
@@ -96,6 +97,8 @@
#include <malloc.h>
#endif
Q_LOGGING_CATEGORY(coreLog, "qtc.core", QtWarningMsg)
/*!
\namespace Core
\inmodule QtCreator
@@ -1373,8 +1376,8 @@ void ICorePrivate::init()
QApplication::setStyle(new ManhattanStyle(baseName));
m_modeManager = new ModeManager(m_modeStack);
connect(m_modeStack, &FancyTabWidget::topAreaClicked, this, [](Qt::MouseButton, Qt::KeyboardModifiers modifiers) {
if (modifiers & Qt::ShiftModifier) {
connect(m_modeStack, &FancyTabWidget::topAreaClicked, this, [](QMouseEvent *event) {
if (event->modifiers() & Qt::ShiftModifier) {
QColor color = QColorDialog::getColor(StyleHelper::requestedBaseColor(), ICore::dialogParent());
if (color.isValid())
StyleHelper::setBaseColor(color);
@@ -2412,6 +2415,10 @@ void ICorePrivate::updateContext()
uniquecontexts.add(id);
}
if (coreLog().isDebugEnabled()) {
qCDebug(coreLog) << "context changed:"
<< Utils::transform<QList<QString>>(uniquecontexts, &Id::toString);
}
ActionManager::setContext(uniquecontexts);
emit m_core->contextChanged(uniquecontexts);
}

View File

@@ -21,7 +21,7 @@ class IModePrivate
public:
QString m_displayName;
QIcon m_icon;
QMenu *m_menu = nullptr;
std::function<void(QMenu *)> m_menuFunction;
Utils::FancyMainWindow *m_mainWindow = nullptr;
int m_priority = -1;
Utils::Id m_id;
@@ -110,15 +110,6 @@ public:
This property holds the ID of the mode.
*/
/*!
\property IMode::menu
This property holds the mode's menu.
By default, a mode does not have a menu. When you set a menu, it is not
owned by the mode unless you set the parent explicitly.
*/
/*!
Creates an IMode with an optional \a parent.
@@ -194,9 +185,15 @@ void IMode::setId(Utils::Id id)
m_d->m_isVisible.readSettings();
}
void IMode::setMenu(QMenu *menu)
/*!
Sets a \a menuFunction that is used to add the mode specific items
to the mode's context menu. This is called every time the context
menu is requested with a new QMenu instance.
The menu is destroyed after the it closes.
*/
void IMode::setMenu(std::function<void(QMenu *)> menuFunction)
{
m_d->m_menu = menu;
m_d->m_menuFunction = menuFunction;
}
void IMode::setContext(const Context &context)
@@ -232,9 +229,25 @@ bool IMode::isVisible() const
return m_d->m_isVisible.value();
}
QMenu *IMode::menu() const
/*!
Returns if the mode provides mode specific context menu items.
\sa setMenu()
*/
bool IMode::hasMenu() const
{
return m_d->m_menu;
return bool(m_d->m_menuFunction);
}
/*!
Adds the mode specific items to the \a menu, if any.
\sa setMenu()
*/
void IMode::addToMenu(QMenu *menu) const
{
if (m_d->m_menuFunction)
m_d->m_menuFunction(menu);
}
Context IMode::context() const

View File

@@ -10,6 +10,7 @@
#include <QIcon>
#include <QMenu>
#include <functional>
#include <memory.h>
namespace Utils {
@@ -29,7 +30,6 @@ class CORE_EXPORT IMode : public QObject
Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
Q_PROPERTY(int priority READ priority WRITE setPriority)
Q_PROPERTY(Utils::Id id READ id WRITE setId)
Q_PROPERTY(QMenu *menu READ menu WRITE setMenu)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledStateChanged)
public:
@@ -42,7 +42,8 @@ public:
Utils::Id id() const;
bool isEnabled() const;
bool isVisible() const;
QMenu *menu() const;
bool hasMenu() const;
void addToMenu(QMenu *menu) const;
Context context() const;
QWidget *widget() const;
@@ -52,7 +53,7 @@ public:
void setIcon(const QIcon &icon);
void setPriority(int priority);
void setId(Utils::Id id);
void setMenu(QMenu *menu);
void setMenu(std::function<void(QMenu *)> menuFunction);
void setContext(const Context &context);
void setWidget(QWidget *widget);

View File

@@ -104,8 +104,34 @@ static int indexOf(Id id)
void ModeManagerPrivate::showMenu(int index, QMouseEvent *event)
{
QTC_ASSERT(m_modes.at(index)->menu(), return);
m_modes.at(index)->menu()->popup(event->globalPosition().toPoint());
if (index < 0) {
ActionContainer *viewContainer = ActionManager::actionContainer(
Constants::M_VIEW_MODESTYLES);
QTC_ASSERT(viewContainer, return);
QMenu *viewMenu = viewContainer->menu();
QTC_ASSERT(viewMenu, return);
QList<QAction *> actions = viewMenu->actions();
if (actions.isEmpty())
return;
auto menu = new QMenu(m_actionBar);
menu->setAttribute(Qt::WA_DeleteOnClose);
for (QAction *a : actions)
menu->addAction(a);
menu->popup(event->globalPosition().toPoint());
return;
}
IMode *mode = m_modes.value(index);
QTC_ASSERT(mode, return);
auto menu = new QMenu(m_actionBar);
menu->setAttribute(Qt::WA_DeleteOnClose);
mode->addToMenu(menu);
menu->addSeparator();
menu->addAction(Tr::tr("Hide"), mode, [mode] { mode->setVisible(false); });
menu->addSeparator();
menu->addAction(m_setModeSelectorStyleIconsAndTextAction);
menu->addAction(m_setModeSelectorStyleIconsOnlyAction);
menu->addAction(m_setModeSelectorStyleHiddenAction);
menu->popup(event->globalPosition().toPoint());
}
ModeManager::ModeManager(Internal::FancyTabWidget *modeStack)
@@ -277,8 +303,7 @@ void ModeManagerPrivate::appendMode(IMode *mode)
{
const int index = m_modeCommands.count();
m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(),
mode->menu() != nullptr);
m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(), mode->hasMenu());
m_modeStack->setTabEnabled(index, mode->isEnabled());
m_modeStack->setTabVisible(index, mode->isVisible());

View File

@@ -192,15 +192,7 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
m_perspectiveMenu = new QMenu;
connect(m_perspectiveMenu, &QMenu::aboutToShow, this, [this] {
m_perspectiveMenu->clear();
for (Perspective *perspective : std::as_const(m_perspectives)) {
m_perspectiveMenu->addAction(perspective->d->m_name, perspective, [perspective] {
if (auto subPerspective = Perspective::findPerspective(
perspective->d->m_lastActiveSubPerspectiveId))
subPerspective->select();
else
perspective->select();
});
}
DebuggerMainWindow::addPerspectiveMenu(m_perspectiveMenu);
});
auto viewButton = new QToolButton;
@@ -511,9 +503,19 @@ void DebuggerMainWindow::addSubPerspectiveSwitcher(QWidget *widget)
d->m_subPerspectiveSwitcherLayout->addWidget(widget);
}
QMenu *DebuggerMainWindow::perspectiveMenu()
void DebuggerMainWindow::addPerspectiveMenu(QMenu *menu)
{
return theMainWindow ? theMainWindow->d->m_perspectiveMenu : nullptr;
if (!theMainWindow)
return;
for (Perspective *perspective : std::as_const(theMainWindow->d->m_perspectives)) {
menu->addAction(perspective->d->m_name, perspective, [perspective] {
if (auto subPerspective = Perspective::findPerspective(
perspective->d->m_lastActiveSubPerspectiveId))
subPerspective->select();
else
perspective->select();
});
}
}
DebuggerMainWindow *DebuggerMainWindow::instance()

View File

@@ -142,7 +142,7 @@ public:
static QWidget *centralWidgetStack();
void addSubPerspectiveSwitcher(QWidget *widget);
static QMenu *perspectiveMenu();
static void addPerspectiveMenu(QMenu *menu);
static Perspective *currentPerspective();

View File

@@ -497,7 +497,7 @@ public:
setWidget(splitter);
setMainWindow(mainWindow);
setMenu(DebuggerMainWindow::perspectiveMenu());
setMenu(&DebuggerMainWindow::addPerspectiveMenu);
}
~DebugMode() { delete widget(); }