211 lines
6.6 KiB
C++
211 lines
6.6 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2024 Pierre-Louis Boyer <development[at]Ondsel.com> *
|
|
* *
|
|
* This file is part of FreeCAD. *
|
|
* *
|
|
* FreeCAD is free software: you can redistribute it and/or modify it *
|
|
* under the terms of the GNU Lesser General Public License as *
|
|
* published by the Free Software Foundation, either version 2.1 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* FreeCAD is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
* License along with FreeCAD. If not, see *
|
|
* <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef GUI_WORKBENCHSELECTOR_H
|
|
#define GUI_WORKBENCHSELECTOR_H
|
|
|
|
#include <QComboBox>
|
|
#include <QTabBar>
|
|
#include <QMenu>
|
|
#include <QToolButton>
|
|
#include <QLayout>
|
|
#include <QWheelEvent>
|
|
|
|
#include <FCGlobal.h>
|
|
#include <Gui/ToolBarManager.h>
|
|
#include <map>
|
|
|
|
namespace Gui
|
|
{
|
|
class WorkbenchGroup;
|
|
|
|
enum class WorkbenchItemStyle
|
|
{
|
|
IconAndText = 0,
|
|
IconOnly = 1,
|
|
TextOnly = 2
|
|
};
|
|
|
|
class GuiExport WorkbenchComboBox: public QComboBox
|
|
{
|
|
Q_OBJECT // NOLINT
|
|
|
|
public: explicit WorkbenchComboBox(WorkbenchGroup* aGroup, QWidget* parent = nullptr);
|
|
~WorkbenchComboBox() override = default;
|
|
WorkbenchComboBox(WorkbenchComboBox&& rhs) = delete;
|
|
void showPopup() override;
|
|
|
|
WorkbenchComboBox operator=(WorkbenchComboBox&& rhs) = delete;
|
|
|
|
public Q_SLOTS:
|
|
void refreshList(QList<QAction*>);
|
|
|
|
private:
|
|
Q_DISABLE_COPY(WorkbenchComboBox)
|
|
};
|
|
|
|
|
|
class GuiExport WorkbenchTabWidget: public QWidget
|
|
{
|
|
Q_OBJECT // NOLINT
|
|
Q_PROPERTY(Qt::LayoutDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
|
|
|
|
class WbTabBar: public QTabBar
|
|
{
|
|
public:
|
|
explicit WbTabBar(QWidget* parent)
|
|
: QTabBar(parent)
|
|
{}
|
|
|
|
QSize tabSizeHint(int index) const override
|
|
{
|
|
auto sizeFromParent = QTabBar::tabSizeHint(index);
|
|
|
|
if (itemStyle() != WorkbenchItemStyle::IconOnly) {
|
|
return sizeFromParent;
|
|
}
|
|
|
|
QStyleOptionTab opt;
|
|
|
|
initStyleOption(&opt, index);
|
|
|
|
int padding = style()->pixelMetric(QStyle::PM_TabBarTabHSpace, &opt, this);
|
|
|
|
auto csz = iconSize();
|
|
auto isHorizontal = opt.shape == RoundedNorth || opt.shape == RoundedSouth;
|
|
|
|
if (isHorizontal) {
|
|
csz.setWidth(csz.width() + padding);
|
|
}
|
|
else {
|
|
csz.setHeight(csz.height() + padding);
|
|
}
|
|
|
|
auto size = style()->sizeFromContents(QStyle::CT_TabBarTab, &opt, csz, this);
|
|
|
|
if (isHorizontal) {
|
|
size.setHeight(sizeFromParent.height());
|
|
}
|
|
else {
|
|
size.setWidth(sizeFromParent.width());
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
void wheelEvent(QWheelEvent* wheelEvent) override
|
|
{
|
|
// Qt does not expose any way to programmatically control scroll of QTabBar hence
|
|
// we need to use a bit hacky solution of simulating clicks on the scroll buttons
|
|
const auto buttonToClickName = wheelEvent->angleDelta().y() < 0
|
|
? QStringLiteral("ScrollLeftButton")
|
|
: QStringLiteral("ScrollRightButton");
|
|
|
|
// Qt introduces named buttons in Qt 6.3 and 5.15.6, before that they are not available
|
|
if (const auto button = findChild<QAbstractButton*>(buttonToClickName)) {
|
|
button->click();
|
|
}
|
|
}
|
|
|
|
WorkbenchItemStyle itemStyle() const
|
|
{
|
|
return _itemStyle;
|
|
}
|
|
|
|
void setItemStyle(WorkbenchItemStyle itemStyle)
|
|
{
|
|
_itemStyle = itemStyle;
|
|
setProperty("style", QString::fromUtf8(workbenchItemStyleToString(itemStyle)));
|
|
}
|
|
|
|
private:
|
|
WorkbenchItemStyle _itemStyle {WorkbenchItemStyle::IconAndText};
|
|
|
|
static const char* workbenchItemStyleToString(WorkbenchItemStyle style)
|
|
{
|
|
switch (style) {
|
|
case WorkbenchItemStyle::IconAndText:
|
|
return "icon-and-text";
|
|
case WorkbenchItemStyle::IconOnly:
|
|
return "icon-only";
|
|
case WorkbenchItemStyle::TextOnly:
|
|
return "text-only";
|
|
default:
|
|
return "WorkbenchItemStyle-internal-error";
|
|
}
|
|
}
|
|
};
|
|
|
|
public:
|
|
explicit WorkbenchTabWidget(WorkbenchGroup* aGroup, QWidget* parent = nullptr);
|
|
|
|
void setToolBarArea(Gui::ToolBarArea area);
|
|
void buildPrefMenu();
|
|
|
|
Qt::LayoutDirection direction() const;
|
|
void setDirection(Qt::LayoutDirection direction);
|
|
|
|
void adjustSize();
|
|
|
|
public Q_SLOTS:
|
|
void handleWorkbenchSelection(QAction* selectedWorkbenchAction);
|
|
void handleTabChange(int selectedTabIndex);
|
|
|
|
void updateLayout();
|
|
void updateWorkbenchList();
|
|
|
|
Q_SIGNALS:
|
|
void directionChanged(const Qt::LayoutDirection&);
|
|
|
|
protected:
|
|
int addWorkbenchTab(QAction* workbenchActivateAction, int index = -1);
|
|
|
|
void setTemporaryWorkbenchTab(QAction* workbenchActivateAction);
|
|
int temporaryWorkbenchTabIndex() const;
|
|
|
|
QAction* workbenchActivateActionByTabIndex(int tabIndex) const;
|
|
int tabIndexForWorkbenchActivateAction(QAction* workbenchActivateAction) const;
|
|
|
|
WorkbenchItemStyle itemStyle() const;
|
|
|
|
private:
|
|
bool isInitializing = false;
|
|
|
|
WorkbenchGroup* wbActionGroup;
|
|
QToolButton* moreButton;
|
|
WbTabBar* tabBar;
|
|
QBoxLayout* layout;
|
|
|
|
Qt::LayoutDirection _direction = Qt::LeftToRight;
|
|
|
|
// this action is used for workbenches that are typically disabled
|
|
QAction* temporaryWorkbenchAction = nullptr;
|
|
|
|
std::map<QAction*, int> actionToTabIndex;
|
|
std::map<int, QAction*> tabIndexToAction;
|
|
};
|
|
|
|
|
|
} // namespace Gui
|
|
|
|
#endif // GUI_WORKBENCHSELECTOR_H
|