Gui: add support for transparent overlay docking widget
@@ -2082,6 +2082,13 @@ void Application::runApplication()
|
||||
<< QString::fromUtf8((App::Application::getResourceDir() + "Gui/Stylesheets/").c_str())
|
||||
<< QLatin1String(":/stylesheets");
|
||||
QDir::setSearchPaths(QString::fromLatin1("qss"), qssPaths);
|
||||
// setup the search paths for Qt overlay style sheets
|
||||
QStringList qssOverlayPaths;
|
||||
qssOverlayPaths << QString::fromUtf8((App::Application::getUserAppDataDir()
|
||||
+ "Gui/Stylesheets/overlay").c_str())
|
||||
<< QString::fromUtf8((App::Application::getResourceDir()
|
||||
+ "Gui/Stylesheets/overlay").c_str());
|
||||
QDir::setSearchPaths(QStringLiteral("overlay"), qssOverlayPaths);
|
||||
|
||||
// set search paths for images
|
||||
QStringList imagePaths;
|
||||
|
||||
@@ -1066,10 +1066,12 @@ SOURCE_GROUP("Widget" FILES ${Widget_SRCS})
|
||||
|
||||
SET(Params_CPP_SRCS
|
||||
TreeParams.cpp
|
||||
OverlayParams.cpp
|
||||
)
|
||||
|
||||
SET(Params_HPP_SRCS
|
||||
TreeParams.h
|
||||
OverlayParams.h
|
||||
)
|
||||
|
||||
SET(Params_SRCS
|
||||
@@ -1103,6 +1105,8 @@ SOURCE_GROUP("View" FILES ${View_SRCS})
|
||||
# The workbench sources
|
||||
SET(Workbench_CPP_SRCS
|
||||
DockWindowManager.cpp
|
||||
OverlayManager.cpp
|
||||
OverlayWidgets.cpp
|
||||
MenuManager.cpp
|
||||
PythonWorkbenchPyImp.cpp
|
||||
ToolBarManager.cpp
|
||||
@@ -1116,6 +1120,8 @@ SET(Workbench_CPP_SRCS
|
||||
SET(Workbench_SRCS
|
||||
${Workbench_CPP_SRCS}
|
||||
DockWindowManager.h
|
||||
OverlayManager.h
|
||||
OverlayWidgets.h
|
||||
MenuManager.h
|
||||
ToolBarManager.h
|
||||
ToolBoxManager.h
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef GUI_DOCKWND_COMBOVIEW_H
|
||||
#define GUI_DOCKWND_COMBOVIEW_H
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include "DockWindow.h"
|
||||
|
||||
|
||||
@@ -70,6 +71,8 @@ public:
|
||||
*/
|
||||
ComboView(Gui::Document* pcDocument, QWidget *parent=nullptr);
|
||||
|
||||
void setShowModel(bool);
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* A more elaborate description of the destructor.
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
#include "Macro.h"
|
||||
#include "MainWindow.h"
|
||||
#include "NavigationStyle.h"
|
||||
#include "OverlayParams.h"
|
||||
#include "OverlayManager.h"
|
||||
#include "SceneInspector.h"
|
||||
#include "Selection.h"
|
||||
#include "SelectionObject.h"
|
||||
@@ -3715,6 +3717,279 @@ Action * StdCmdSelBoundingBox::createAction()
|
||||
return pcAction;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayAll
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayAll)
|
||||
|
||||
StdCmdDockOverlayAll::StdCmdDockOverlayAll()
|
||||
:Command("Std_DockOverlayAll")
|
||||
{
|
||||
sGroup = "View";
|
||||
sMenuText = QT_TR_NOOP("Toggle overlay for all");
|
||||
sToolTipText = QT_TR_NOOP("Toggle overlay mode for all docked windows");
|
||||
sWhatsThis = "Std_DockOverlayAll";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "F4";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayAll::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleAll);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayTransparentAll
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayTransparentAll)
|
||||
|
||||
StdCmdDockOverlayTransparentAll::StdCmdDockOverlayTransparentAll()
|
||||
:Command("Std_DockOverlayTransparentAll")
|
||||
{
|
||||
sGroup = "View";
|
||||
sMenuText = QT_TR_NOOP("Toggle transparent for all");
|
||||
sToolTipText = QT_TR_NOOP("Toggle transparent for all overlay docked window.\n"
|
||||
"This makes the docked widget stay transparent at all times.");
|
||||
sWhatsThis = "Std_DockOverlayTransparentAll";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+F4";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayTransparentAll::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTransparentAll);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggle
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggle)
|
||||
|
||||
StdCmdDockOverlayToggle::StdCmdDockOverlayToggle()
|
||||
:Command("Std_DockOverlayToggle")
|
||||
{
|
||||
sGroup = "View";
|
||||
sMenuText = QT_TR_NOOP("Toggle overlay");
|
||||
sToolTipText = QT_TR_NOOP("Toggle overlay mode of the docked window under cursor");
|
||||
sWhatsThis = "Std_DockOverlayToggle";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "F3";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggle::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleActive);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggleTransparent
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggleTransparent)
|
||||
|
||||
StdCmdDockOverlayToggleTransparent::StdCmdDockOverlayToggleTransparent()
|
||||
:Command("Std_DockOverlayToggleTransparent")
|
||||
{
|
||||
sGroup = "Standard-View";
|
||||
sMenuText = QT_TR_NOOP("Toggle transparent");
|
||||
sToolTipText = QT_TR_NOOP("Toggle transparent mode for the docked widget under cursor.\n"
|
||||
"This makes the docked widget stay transparent at all times.");
|
||||
sWhatsThis = "Std_DockOverlayToggleTransparent";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+F3";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggleTransparent::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTransparent);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggleLeft
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggleLeft)
|
||||
|
||||
StdCmdDockOverlayToggleLeft::StdCmdDockOverlayToggleLeft()
|
||||
:Command("Std_DockOverlayToggleLeft")
|
||||
{
|
||||
sGroup = "Standard-View";
|
||||
sMenuText = QT_TR_NOOP("Toggle left");
|
||||
sToolTipText = QT_TR_NOOP("Show/hide left overlay panel");
|
||||
sWhatsThis = "Std_DockOverlayToggleLeft";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+Left";
|
||||
sPixmap = "qss:overlay/close.svg";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggleLeft::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleLeft);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggleRight
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggleRight)
|
||||
|
||||
StdCmdDockOverlayToggleRight::StdCmdDockOverlayToggleRight()
|
||||
:Command("Std_DockOverlayToggleRight")
|
||||
{
|
||||
sGroup = "Standard-View";
|
||||
sMenuText = QT_TR_NOOP("Toggle right");
|
||||
sToolTipText = QT_TR_NOOP("Show/hide right overlay panel");
|
||||
sWhatsThis = "Std_DockOverlayToggleRight";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+Right";
|
||||
sPixmap = "qss:overlay/close.svg";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggleRight::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleRight);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggleTop
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggleTop)
|
||||
|
||||
StdCmdDockOverlayToggleTop::StdCmdDockOverlayToggleTop()
|
||||
:Command("Std_DockOverlayToggleTop")
|
||||
{
|
||||
sGroup = "Standard-View";
|
||||
sMenuText = QT_TR_NOOP("Toggle top");
|
||||
sToolTipText = QT_TR_NOOP("Show/hide top overlay panel");
|
||||
sWhatsThis = "Std_DockOverlayToggleTop";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+Up";
|
||||
sPixmap = "qss:overlay/close.svg";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggleTop::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTop);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayToggleBottom
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdDockOverlayToggleBottom)
|
||||
|
||||
StdCmdDockOverlayToggleBottom::StdCmdDockOverlayToggleBottom()
|
||||
:Command("Std_DockOverlayToggleBottom")
|
||||
{
|
||||
sGroup = "Standard-View";
|
||||
sMenuText = QT_TR_NOOP("Toggle bottom");
|
||||
sToolTipText = QT_TR_NOOP("Show/hide bottom overlay panel");
|
||||
sWhatsThis = "Std_DockOverlayToggleBottom";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "SHIFT+Down";
|
||||
sPixmap = "qss:overlay/close.svg";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayToggleBottom::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleBottom);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_DockOverlayMouseTransparent
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD_AC(StdCmdDockOverlayMouseTransparent)
|
||||
|
||||
StdCmdDockOverlayMouseTransparent::StdCmdDockOverlayMouseTransparent()
|
||||
:Command("Std_DockOverlayMouseTransparent")
|
||||
{
|
||||
sGroup = "View";
|
||||
sMenuText = QT_TR_NOOP("Bypass mouse events in dock overlay");
|
||||
sToolTipText = QT_TR_NOOP("Bypass all mouse events in dock overlay");
|
||||
sWhatsThis = "Std_DockOverlayMouseTransparent";
|
||||
sStatusTip = sToolTipText;
|
||||
sAccel = "T, T";
|
||||
eType = NoTransaction;
|
||||
}
|
||||
|
||||
void StdCmdDockOverlayMouseTransparent::activated(int iMsg)
|
||||
{
|
||||
(void)iMsg;
|
||||
bool checked = !OverlayManager::instance()->isMouseTransparent();
|
||||
OverlayManager::instance()->setMouseTransparent(checked);
|
||||
if(_pcAction)
|
||||
_pcAction->setChecked(checked,true);
|
||||
}
|
||||
|
||||
Action * StdCmdDockOverlayMouseTransparent::createAction(void) {
|
||||
Action *pcAction = Command::createAction();
|
||||
pcAction->setCheckable(true);
|
||||
pcAction->setIcon(QIcon());
|
||||
_pcAction = pcAction;
|
||||
isActive();
|
||||
return pcAction;
|
||||
}
|
||||
|
||||
bool StdCmdDockOverlayMouseTransparent::isActive() {
|
||||
bool checked = OverlayManager::instance()->isMouseTransparent();
|
||||
if(_pcAction && _pcAction->isChecked()!=checked)
|
||||
_pcAction->setChecked(checked,true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class StdCmdDockOverlay : public GroupCommand
|
||||
{
|
||||
public:
|
||||
StdCmdDockOverlay()
|
||||
:GroupCommand("Std_DockOverlay")
|
||||
{
|
||||
sGroup = "View";
|
||||
sMenuText = QT_TR_NOOP("Dock window overlay");
|
||||
sToolTipText = QT_TR_NOOP("Setting docked window overlay mode");
|
||||
sWhatsThis = "Std_DockOverlay";
|
||||
sStatusTip = sToolTipText;
|
||||
eType = 0;
|
||||
bCanLog = false;
|
||||
|
||||
addCommand(new StdCmdDockOverlayAll());
|
||||
addCommand(new StdCmdDockOverlayTransparentAll());
|
||||
addCommand();
|
||||
addCommand(new StdCmdDockOverlayToggle());
|
||||
addCommand(new StdCmdDockOverlayToggleTransparent());
|
||||
addCommand();
|
||||
addCommand(new StdCmdDockOverlayMouseTransparent());
|
||||
addCommand();
|
||||
addCommand(new StdCmdDockOverlayToggleLeft());
|
||||
addCommand(new StdCmdDockOverlayToggleRight());
|
||||
addCommand(new StdCmdDockOverlayToggleTop());
|
||||
addCommand(new StdCmdDockOverlayToggleBottom());
|
||||
};
|
||||
virtual const char* className() const {return "StdCmdDockOverlay";}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Std_StoreWorkingView
|
||||
//===========================================================================
|
||||
@@ -3859,6 +4134,7 @@ void CreateViewStdCommands()
|
||||
rcCmdMgr.addCommand(new CmdViewMeasureToggleAll());
|
||||
rcCmdMgr.addCommand(new StdCmdSelBoundingBox());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeViewActions());
|
||||
rcCmdMgr.addCommand(new StdCmdDockOverlay());
|
||||
|
||||
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
if(hGrp->GetASCII("GestureRollFwdCommand").empty())
|
||||
|
||||
@@ -25,15 +25,23 @@
|
||||
#ifndef _PreComp_
|
||||
# include <array>
|
||||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QDockWidget>
|
||||
# include <QMap>
|
||||
# include <QMouseEvent>
|
||||
# include <QPointer>
|
||||
# include <QTimer>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "DockWindowManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "OverlayManager.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
@@ -45,7 +53,7 @@ DockWindowItems::~DockWindowItems() = default;
|
||||
void DockWindowItems::addDockWidget(const char* name, Qt::DockWidgetArea pos, bool visibility, bool tabbed)
|
||||
{
|
||||
DockWindowItem item;
|
||||
item.name = QString::fromLatin1(name);
|
||||
item.name = QString::fromUtf8(name);
|
||||
item.pos = pos;
|
||||
item.visibility = visibility;
|
||||
item.tabbed = tabbed;
|
||||
@@ -55,7 +63,7 @@ void DockWindowItems::addDockWidget(const char* name, Qt::DockWidgetArea pos, bo
|
||||
void DockWindowItems::setDockingArea(const char* name, Qt::DockWidgetArea pos)
|
||||
{
|
||||
for (QList<DockWindowItem>::iterator it = _items.begin(); it != _items.end(); ++it) {
|
||||
if (it->name == QLatin1String(name)) {
|
||||
if (it->name == QString::fromUtf8(name)) {
|
||||
it->pos = pos;
|
||||
break;
|
||||
}
|
||||
@@ -65,7 +73,7 @@ void DockWindowItems::setDockingArea(const char* name, Qt::DockWidgetArea pos)
|
||||
void DockWindowItems::setVisibility(const char* name, bool v)
|
||||
{
|
||||
for (QList<DockWindowItem>::iterator it = _items.begin(); it != _items.end(); ++it) {
|
||||
if (it->name == QLatin1String(name)) {
|
||||
if (it->name == QString::fromUtf8(name)) {
|
||||
it->visibility = v;
|
||||
break;
|
||||
}
|
||||
@@ -87,11 +95,66 @@ const QList<DockWindowItem>& DockWindowItems::dockWidgets() const
|
||||
// -----------------------------------------------------------
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class DockWidgetEventFilter: public QObject {
|
||||
public:
|
||||
bool eventFilter(QObject *o, QEvent *e) {
|
||||
if (!o->isWidgetType() || e->type() != QEvent::MouseMove)
|
||||
return false;
|
||||
auto widget = qobject_cast<QDockWidget*>(o);
|
||||
if (!widget || !widget->isFloating()) {
|
||||
if (overridden) {
|
||||
overridden = false;
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (static_cast<QMouseEvent*>(e)->buttons() != Qt::NoButton)
|
||||
return false;
|
||||
auto pos = QCursor::pos();
|
||||
QPoint topLeft = widget->mapToGlobal(QPoint(cursorMargin, cursorMargin));
|
||||
int h = widget->frameGeometry().height();
|
||||
int w = widget->frameGeometry().width();
|
||||
QPoint bottomRight = widget->mapToGlobal(QPoint(w-cursorMargin, h-cursorMargin));
|
||||
bool left = QRect(topLeft - QPoint(cursorMargin,cursorMargin), QSize(cursorMargin, h)).contains(pos);
|
||||
bool right = QRect(bottomRight.x(), topLeft.y(), cursorMargin, h).contains(pos);
|
||||
bool bottom = QRect(topLeft.x()-cursorMargin, bottomRight.y(), w, cursorMargin).contains(pos);
|
||||
auto cursor = Qt::ArrowCursor;
|
||||
if (left && bottom)
|
||||
cursor = Qt::SizeBDiagCursor;
|
||||
else if (right && bottom)
|
||||
cursor = Qt::SizeFDiagCursor;
|
||||
else if (bottom)
|
||||
cursor = Qt::SizeVerCursor;
|
||||
else if (left || right)
|
||||
cursor = Qt::SizeHorCursor;
|
||||
else if (overridden) {
|
||||
overridden = false;
|
||||
QApplication::restoreOverrideCursor();
|
||||
return false;
|
||||
}
|
||||
if (overridden)
|
||||
QApplication::changeOverrideCursor(cursor);
|
||||
else {
|
||||
overridden = true;
|
||||
QApplication::setOverrideCursor(cursor);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool overridden = false;
|
||||
int cursorMargin = 5;
|
||||
};
|
||||
|
||||
struct DockWindowManagerP
|
||||
{
|
||||
QList<QDockWidget*> _dockedWindows;
|
||||
QMap<QString, QPointer<QWidget> > _dockWindows;
|
||||
DockWindowItems _dockWindowItems;
|
||||
ParameterGrp::handle _hPref;
|
||||
boost::signals2::scoped_connection _connParam;
|
||||
QTimer _timer;
|
||||
DockWidgetEventFilter _dockWidgetEventFilter;
|
||||
};
|
||||
} // namespace Gui
|
||||
|
||||
@@ -113,6 +176,39 @@ void DockWindowManager::destruct()
|
||||
DockWindowManager::DockWindowManager()
|
||||
{
|
||||
d = new DockWindowManagerP;
|
||||
qApp->installEventFilter(&d->_dockWidgetEventFilter);
|
||||
d->_hPref = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/MainWindow/DockWindows");
|
||||
d->_dockWidgetEventFilter.cursorMargin = d->_hPref->GetInt("CursorMargin", 5);
|
||||
d->_connParam = d->_hPref->Manager()->signalParamChanged.connect(
|
||||
[this](ParameterGrp *Param, ParameterGrp::ParamType Type, const char *name, const char *) {
|
||||
if(Param == d->_hPref) {
|
||||
switch(Type) {
|
||||
case ParameterGrp::ParamType::FCBool:
|
||||
// For batch process UI setting changes, e.g. loading new preferences
|
||||
d->_timer.start(100);
|
||||
break;
|
||||
case ParameterGrp::ParamType::FCInt:
|
||||
if (name && boost::equals(name, "CursorMargin"))
|
||||
d->_dockWidgetEventFilter.cursorMargin = d->_hPref->GetInt("CursorMargin", 5);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
d->_timer.setSingleShot(true);
|
||||
|
||||
connect(&d->_timer, &QTimer::timeout, [this](){
|
||||
for(auto w : this->getDockWindows()) {
|
||||
if (auto dw = qobject_cast<QDockWidget*>(w)) {
|
||||
QSignalBlocker blocker(dw);
|
||||
QByteArray dockName = dw->toggleViewAction()->data().toByteArray();
|
||||
dw->setVisible(d->_hPref->GetBool(dockName, dw->isVisible()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DockWindowManager::~DockWindowManager()
|
||||
@@ -126,9 +222,17 @@ DockWindowManager::~DockWindowManager()
|
||||
*/
|
||||
QDockWidget* DockWindowManager::addDockWindow(const char* name, QWidget* widget, Qt::DockWidgetArea pos)
|
||||
{
|
||||
if(!widget)
|
||||
return nullptr;
|
||||
QDockWidget *dw = qobject_cast<QDockWidget*>(widget->parentWidget());
|
||||
if(dw)
|
||||
return dw;
|
||||
|
||||
// creates the dock widget as container to embed this widget
|
||||
MainWindow* mw = getMainWindow();
|
||||
auto dw = new QDockWidget(mw);
|
||||
dw = new QDockWidget(mw);
|
||||
OverlayManager::instance()->setupTitleBar(dw);
|
||||
|
||||
// Note: By default all dock widgets are hidden but the user can show them manually in the view menu.
|
||||
// First, hide immediately the dock widget to avoid flickering, after setting up the dock widgets
|
||||
// MainWindow::loadLayoutSettings() is called to restore the layout.
|
||||
@@ -152,13 +256,28 @@ QDockWidget* DockWindowManager::addDockWindow(const char* name, QWidget* widget,
|
||||
dw->setWidget(widget);
|
||||
|
||||
// set object name and window title needed for i18n stuff
|
||||
dw->setObjectName(QLatin1String(name));
|
||||
dw->setWindowTitle(QDockWidget::tr(name));
|
||||
dw->setObjectName(QString::fromUtf8(name));
|
||||
QString title = widget->windowTitle();
|
||||
if (title.isEmpty())
|
||||
title = QDockWidget::tr(name);
|
||||
dw->setWindowTitle(title);
|
||||
dw->setFeatures(QDockWidget::DockWidgetClosable
|
||||
| QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable);
|
||||
|
||||
d->_dockedWindows.push_back(dw);
|
||||
|
||||
OverlayManager::instance()->initDockWidget(dw);
|
||||
|
||||
connect(dw->toggleViewAction(), &QAction::triggered, [this, dw](){
|
||||
Base::ConnectionBlocker block(d->_connParam);
|
||||
QByteArray dockName = dw->toggleViewAction()->data().toByteArray();
|
||||
d->_hPref->SetBool(dockName.constData(), dw->isVisible());
|
||||
});
|
||||
|
||||
auto cb = []() {getMainWindow()->saveWindowSettings(true);};
|
||||
connect(dw, &QDockWidget::topLevelChanged, cb);
|
||||
connect(dw, &QDockWidget::dockLocationChanged, cb);
|
||||
return dw;
|
||||
}
|
||||
|
||||
@@ -169,7 +288,7 @@ QDockWidget* DockWindowManager::addDockWindow(const char* name, QWidget* widget,
|
||||
QWidget* DockWindowManager::getDockWindow(const char* name) const
|
||||
{
|
||||
for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
|
||||
if ((*it)->objectName() == QLatin1String(name))
|
||||
if ((*it)->objectName() == QString::fromUtf8(name))
|
||||
return (*it)->widget();
|
||||
}
|
||||
|
||||
@@ -208,9 +327,10 @@ QWidget* DockWindowManager::removeDockWindow(const char* name)
|
||||
{
|
||||
QWidget* widget=nullptr;
|
||||
for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
|
||||
if ((*it)->objectName() == QLatin1String(name)) {
|
||||
if ((*it)->objectName() == QString::fromUtf8(name)) {
|
||||
QDockWidget* dw = *it;
|
||||
d->_dockedWindows.erase(it);
|
||||
OverlayManager::instance()->unsetupDockWidget(dw);
|
||||
getMainWindow()->removeDockWidget(dw);
|
||||
// avoid to destruct the embedded widget
|
||||
widget = dw->widget();
|
||||
@@ -234,10 +354,13 @@ QWidget* DockWindowManager::removeDockWindow(const char* name)
|
||||
*/
|
||||
void DockWindowManager::removeDockWindow(QWidget* widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
|
||||
if ((*it)->widget() == widget) {
|
||||
QDockWidget* dw = *it;
|
||||
d->_dockedWindows.erase(it);
|
||||
OverlayManager::instance()->unsetupDockWidget(dw);
|
||||
getMainWindow()->removeDockWidget(dw);
|
||||
// avoid to destruct the embedded widget
|
||||
widget->setParent(nullptr);
|
||||
@@ -283,7 +406,11 @@ void DockWindowManager::activate(QWidget* widget)
|
||||
void DockWindowManager::retranslate()
|
||||
{
|
||||
for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
|
||||
(*it)->setWindowTitle(QDockWidget::tr((*it)->objectName().toLatin1()));
|
||||
QString title = (*it)->windowTitle();
|
||||
if (title.isEmpty())
|
||||
(*it)->setWindowTitle(QDockWidget::tr((*it)->objectName().toUtf8()));
|
||||
else
|
||||
(*it)->setWindowTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,10 +435,10 @@ void DockWindowManager::retranslate()
|
||||
*/
|
||||
bool DockWindowManager::registerDockWindow(const char* name, QWidget* widget)
|
||||
{
|
||||
QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QLatin1String(name));
|
||||
QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QString::fromUtf8(name));
|
||||
if (it != d->_dockWindows.end() || !widget)
|
||||
return false;
|
||||
d->_dockWindows[QLatin1String(name)] = widget;
|
||||
d->_dockWindows[QString::fromUtf8(name)] = widget;
|
||||
widget->hide(); // hide the widget if not used
|
||||
return true;
|
||||
}
|
||||
@@ -319,14 +446,22 @@ bool DockWindowManager::registerDockWindow(const char* name, QWidget* widget)
|
||||
QWidget* DockWindowManager::unregisterDockWindow(const char* name)
|
||||
{
|
||||
QWidget* widget = nullptr;
|
||||
QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QLatin1String(name));
|
||||
QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QString::fromUtf8(name));
|
||||
if (it != d->_dockWindows.end()) {
|
||||
widget = d->_dockWindows.take(QLatin1String(name));
|
||||
widget = d->_dockWindows.take(QString::fromUtf8(name));
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget* DockWindowManager::findRegisteredDockWindow(const char* name)
|
||||
{
|
||||
QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QString::fromUtf8(name));
|
||||
if (it != d->_dockWindows.end())
|
||||
return it.value();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** Sets up the dock windows of the activated workbench. */
|
||||
void DockWindowManager::setup(DockWindowItems* items)
|
||||
{
|
||||
@@ -334,14 +469,12 @@ void DockWindowManager::setup(DockWindowItems* items)
|
||||
saveState();
|
||||
d->_dockWindowItems = *items;
|
||||
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("DockWindows");
|
||||
QList<QDockWidget*> docked = d->_dockedWindows;
|
||||
const QList<DockWindowItem>& dws = items->dockWidgets();
|
||||
for (const auto& it : dws) {
|
||||
QDockWidget* dw = findDockWidget(docked, it.name);
|
||||
QByteArray dockName = it.name.toLatin1();
|
||||
bool visible = hPref->GetBool(dockName.constData(), it.visibility);
|
||||
bool visible = d->_hPref->GetBool(dockName.constData(), it.visibility);
|
||||
|
||||
if (!dw) {
|
||||
QMap<QString, QPointer<QWidget> >::Iterator jt = d->_dockWindows.find(it.name);
|
||||
@@ -358,6 +491,9 @@ void DockWindowManager::setup(DockWindowItems* items)
|
||||
int index = docked.indexOf(dw);
|
||||
docked.removeAt(index);
|
||||
}
|
||||
|
||||
if(dw && visible)
|
||||
OverlayManager::instance()->setupDockWidget(dw);
|
||||
}
|
||||
|
||||
tabifyDockWidgets(items);
|
||||
@@ -417,15 +553,12 @@ void DockWindowManager::tabifyDockWidgets(DockWindowItems* items)
|
||||
|
||||
void DockWindowManager::saveState()
|
||||
{
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("DockWindows");
|
||||
|
||||
const QList<DockWindowItem>& dockItems = d->_dockWindowItems.dockWidgets();
|
||||
for (QList<DockWindowItem>::ConstIterator it = dockItems.begin(); it != dockItems.end(); ++it) {
|
||||
QDockWidget* dw = findDockWidget(d->_dockedWindows, it->name);
|
||||
if (dw) {
|
||||
QByteArray dockName = dw->toggleViewAction()->data().toByteArray();
|
||||
hPref->SetBool(dockName.constData(), dw->isVisible());
|
||||
d->_hPref->SetBool(dockName.constData(), dw->isVisible());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,7 +571,7 @@ void DockWindowManager::loadState()
|
||||
for (QList<DockWindowItem>::ConstIterator it = dockItems.begin(); it != dockItems.end(); ++it) {
|
||||
QDockWidget* dw = findDockWidget(d->_dockedWindows, it->name);
|
||||
if (dw) {
|
||||
QByteArray dockName = it->name.toLatin1();
|
||||
QByteArray dockName = it->name.toUtf8();
|
||||
bool visible = hPref->GetBool(dockName.constData(), it->visibility);
|
||||
dw->setVisible(visible);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <QObject>
|
||||
#include <FCGlobal.h>
|
||||
|
||||
|
||||
class QDockWidget;
|
||||
class QWidget;
|
||||
|
||||
@@ -70,6 +69,7 @@ public:
|
||||
|
||||
bool registerDockWindow(const char* name, QWidget* widget);
|
||||
QWidget* unregisterDockWindow(const char* name);
|
||||
QWidget* findRegisteredDockWindow(const char* name);
|
||||
void setup(DockWindowItems*);
|
||||
|
||||
/// Adds a QDockWidget to the main window and sets \a widget as its widget
|
||||
|
||||
88
src/Gui/Icons/cursor-through.svg
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cursor-through.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.9992772,0,0,1.9992772,-0.23550294,-1052.047)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4136"
|
||||
id="linearGradient4146"
|
||||
x1="3.2922609"
|
||||
y1="1048.2958"
|
||||
x2="7.3351092"
|
||||
y2="1045.6942"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4136">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4138" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop4140" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="2.4698679"
|
||||
inkscape:cy="4.0737083"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1301"
|
||||
inkscape:window-height="744"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1020.3622)">
|
||||
<path
|
||||
style="fill:url(#linearGradient4146);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 9.9393899,1030.4959 6e-7,18.5201 4.2134615,-4.1523 2.912554,6.4989 3.001123,-1.6055 -3.18829,-6.9637 5.402014,-0.2053 z"
|
||||
id="path4134"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -255,6 +255,7 @@
|
||||
<file>folder.svg</file>
|
||||
<file>document-python.svg</file>
|
||||
<file>document-package.svg</file>
|
||||
<file>cursor-through.svg</file>
|
||||
<file>Std_Alignment.svg</file>
|
||||
<file>Std_DuplicateSelection.svg</file>
|
||||
<file>Std_UserEditModeDefault.svg</file>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
# include <QCloseEvent>
|
||||
# include <QContextMenuEvent>
|
||||
# include <QDesktopServices>
|
||||
# include <QDesktopWidget>
|
||||
# include <QDockWidget>
|
||||
# include <QFontMetrics>
|
||||
# include <QKeySequence>
|
||||
@@ -58,6 +59,8 @@
|
||||
# include <QtPlatformHeaders/QWindowsWindowFunctions>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
@@ -68,6 +71,7 @@
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/Stream.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <DAGView/DAGView.h>
|
||||
#include <TaskView/TaskView.h>
|
||||
@@ -83,6 +87,7 @@
|
||||
#include "FileDialog.h"
|
||||
#include "MenuManager.h"
|
||||
#include "NotificationArea.h"
|
||||
#include "OverlayManager.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "PropertyView.h"
|
||||
#include "PythonConsole.h"
|
||||
@@ -243,6 +248,8 @@ struct MainWindowP
|
||||
QTimer* actionTimer;
|
||||
QTimer* statusTimer;
|
||||
QTimer* activityTimer;
|
||||
QTimer saveStateTimer;
|
||||
QTimer restoreStateTimer;
|
||||
QMdiArea* mdiArea;
|
||||
QPointer<MDIView> activeView;
|
||||
QSignalMapper* windowMapper;
|
||||
@@ -254,6 +261,13 @@ struct MainWindowP
|
||||
int currentStatusType = 100;
|
||||
int actionUpdateDelay = 0;
|
||||
QMap<QString, QPointer<UrlHandler> > urlHandler;
|
||||
std::string hiddenDockWindows;
|
||||
int screen = -1;
|
||||
boost::signals2::scoped_connection connParam;
|
||||
ParameterGrp::handle hGrp;
|
||||
bool _restoring = false;
|
||||
QTime _showNormal;
|
||||
void restoreWindowState(const QByteArray &);
|
||||
};
|
||||
|
||||
class MDITabbar : public QTabBar
|
||||
@@ -352,6 +366,32 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f)
|
||||
// global access
|
||||
instance = this;
|
||||
|
||||
d->connParam = App::GetApplication().GetUserParameter().signalParamChanged.connect(
|
||||
[this](ParameterGrp *Param, ParameterGrp::ParamType, const char *Name, const char *) {
|
||||
if (Param != d->hGrp || !Name)
|
||||
return;
|
||||
if (boost::equals(Name, "StatusBar")) {
|
||||
if(auto sb = getMainWindow()->statusBar())
|
||||
sb->setVisible(d->hGrp->GetBool("StatusBar", sb->isVisible()));
|
||||
}
|
||||
else if (boost::equals(Name, "MainWindowState")) {
|
||||
OverlayManager::instance()->reload(OverlayManager::ReloadMode::ReloadPause);
|
||||
d->restoreStateTimer.start(100);
|
||||
}
|
||||
});
|
||||
|
||||
d->hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/MainWindow");
|
||||
d->saveStateTimer.setSingleShot(true);
|
||||
connect(&d->saveStateTimer, &QTimer::timeout, [this](){this->saveWindowSettings();});
|
||||
|
||||
d->restoreStateTimer.setSingleShot(true);
|
||||
connect(&d->restoreStateTimer, &QTimer::timeout, [this](){
|
||||
d->restoreWindowState(QByteArray::fromBase64(d->hGrp->GetASCII("MainWindowState").c_str()));
|
||||
ToolBarManager::getInstance()->restoreState();
|
||||
OverlayManager::instance()->reload(OverlayManager::ReloadMode::ReloadResume);
|
||||
});
|
||||
|
||||
// support for grouped dragging of dockwidgets
|
||||
// https://woboq.com/blog/qdockwidget-changes-in-56.html
|
||||
setDockOptions(dockOptions() | QMainWindow::GroupedDragging);
|
||||
@@ -461,31 +501,46 @@ MainWindow* MainWindow::getInstance()
|
||||
return instance;
|
||||
}
|
||||
|
||||
void MainWindow::setupDockWindows()
|
||||
// Helper function to update dock widget according to the user parameter
|
||||
// settings, e.g. register/unregister, enable/disable, show/hide.
|
||||
template<class T>
|
||||
static inline void _updateDockWidget(const char *name,
|
||||
bool enabled,
|
||||
bool show,
|
||||
Qt::DockWidgetArea pos,
|
||||
T callback)
|
||||
{
|
||||
std::string hiddenDockWindows;
|
||||
const std::map<std::string,std::string>& config = App::Application::Config();
|
||||
auto ht = config.find("HiddenDockWindow");
|
||||
if (ht != config.end())
|
||||
hiddenDockWindows = ht->second;
|
||||
|
||||
setupTreeView(hiddenDockWindows);
|
||||
setupPropertyView(hiddenDockWindows);
|
||||
setupTaskView(hiddenDockWindows);
|
||||
setupSelectionView(hiddenDockWindows);
|
||||
setupComboView(hiddenDockWindows);
|
||||
|
||||
// Report view must be created before PythonConsole!
|
||||
setupReportView(hiddenDockWindows);
|
||||
setupPythonConsole(hiddenDockWindows);
|
||||
setupDAGView(hiddenDockWindows);
|
||||
|
||||
this->setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North);
|
||||
auto pDockMgr = DockWindowManager::instance();
|
||||
auto widget = pDockMgr->findRegisteredDockWindow(name);
|
||||
if (!enabled) {
|
||||
if(widget) {
|
||||
pDockMgr->removeDockWindow(widget);
|
||||
pDockMgr->unregisterDockWindow(name);
|
||||
widget->deleteLater();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Use callback to perform specific update for each type of dock widget
|
||||
widget = callback(widget);
|
||||
if(!widget)
|
||||
return;
|
||||
DockWindowManager::instance()->registerDockWindow(name, widget);
|
||||
if(show) {
|
||||
auto dock = pDockMgr->addDockWindow(
|
||||
widget->objectName().toUtf8().constData(), widget, pos);
|
||||
if(dock) {
|
||||
if(!dock->toggleViewAction()->isChecked())
|
||||
dock->toggleViewAction()->activate(QAction::Trigger);
|
||||
OverlayManager::instance()->refresh(dock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::setupTreeView(const std::string& hiddenDockWindows)
|
||||
void MainWindow::initDockWindows(bool show)
|
||||
{
|
||||
if (hiddenDockWindows.find("Std_TreeView") == std::string::npos) {
|
||||
bool treeView = false;
|
||||
|
||||
if (d->hiddenDockWindows.find("Std_TreeView") == std::string::npos) {
|
||||
//work through parameter.
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("TreeView");
|
||||
@@ -495,111 +550,82 @@ bool MainWindow::setupTreeView(const std::string& hiddenDockWindows)
|
||||
->GetGroup("MainWindow")->GetGroup("DockWindows")->GetBool("Std_TreeView", false);
|
||||
}
|
||||
group->SetBool("Enabled", enabled); //ensure entry exists.
|
||||
if (enabled) {
|
||||
auto tree = new TreeDockWidget(nullptr, this);
|
||||
tree->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Tree view")));
|
||||
tree->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_TreeView", tree);
|
||||
return true;
|
||||
}
|
||||
treeView = enabled;
|
||||
_updateDockWidget("Std_TreeView", enabled, show, Qt::RightDockWidgetArea,
|
||||
[](QWidget *widget) {
|
||||
if(widget)
|
||||
return widget;
|
||||
TreeDockWidget* tree = new TreeDockWidget(0,getMainWindow());
|
||||
tree->setObjectName(QStringLiteral(QT_TRANSLATE_NOOP("QDockWidget","Tree view")));
|
||||
tree->setMinimumWidth(210);
|
||||
widget = tree;
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupTaskView(const std::string& hiddenDockWindows)
|
||||
{
|
||||
// Task view
|
||||
if (hiddenDockWindows.find("Std_TaskView") == std::string::npos) {
|
||||
auto taskView = new Gui::TaskView::TaskView(this);
|
||||
taskView->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Tasks")));
|
||||
taskView->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_TaskView", taskView);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupPropertyView(const std::string& hiddenDockWindows)
|
||||
{
|
||||
// Property view
|
||||
if (hiddenDockWindows.find("Std_PropertyView") == std::string::npos) {
|
||||
if (d->hiddenDockWindows.find("Std_PropertyView") == std::string::npos) {
|
||||
//work through parameter.
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("PropertyView");
|
||||
bool enabled = group->GetBool("Enabled", true);
|
||||
if (enabled != group->GetBool("Enabled", false)) {
|
||||
bool enabled = treeView || group->GetBool("Enabled", false);
|
||||
if (!treeView && enabled != group->GetBool("Enabled", true)) {
|
||||
enabled = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("DockWindows")->GetBool("Std_PropertyView", false);
|
||||
}
|
||||
group->SetBool("Enabled", enabled); //ensure entry exists.
|
||||
if (enabled) {
|
||||
auto pcPropView = new PropertyDockView(nullptr, this);
|
||||
pcPropView->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Property view")));
|
||||
pcPropView->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_PropertyView", pcPropView);
|
||||
return true;
|
||||
}
|
||||
_updateDockWidget("Std_PropertyView", enabled, show, Qt::RightDockWidgetArea,
|
||||
[](QWidget *widget) {
|
||||
if(widget)
|
||||
return widget;
|
||||
PropertyDockView* pcPropView = new PropertyDockView(0, getMainWindow());
|
||||
pcPropView->setObjectName(QStringLiteral(QT_TRANSLATE_NOOP("QDockWidget","Property view")));
|
||||
pcPropView->setMinimumWidth(210);
|
||||
widget = pcPropView;
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupSelectionView(const std::string& hiddenDockWindows)
|
||||
{
|
||||
// Selection view
|
||||
if (hiddenDockWindows.find("Std_SelectionView") == std::string::npos) {
|
||||
auto pcSelectionView = new SelectionView(nullptr, this);
|
||||
pcSelectionView->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Selection view")));
|
||||
pcSelectionView->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_SelectionView", pcSelectionView);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupComboView(const std::string& hiddenDockWindows)
|
||||
{
|
||||
// Combo view
|
||||
if (hiddenDockWindows.find("Std_ComboView") == std::string::npos) {
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("ComboView");
|
||||
bool enable = group->GetBool("Enabled", true);
|
||||
|
||||
if (enable) {
|
||||
auto pcComboView = new ComboView(nullptr, this);
|
||||
pcComboView->setObjectName(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget", "Model")));
|
||||
pcComboView->setMinimumWidth(150);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_ComboView", pcComboView);
|
||||
return true;
|
||||
if (d->hiddenDockWindows.find("Std_ComboView") == std::string::npos) {
|
||||
bool enable = !treeView;
|
||||
if (!enable) {
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("ComboView");
|
||||
enable = group->GetBool("Enabled", true);
|
||||
}
|
||||
_updateDockWidget("Std_ComboView", enable, show, Qt::LeftDockWidgetArea,
|
||||
[](QWidget *widget) {
|
||||
auto pcComboView = qobject_cast<ComboView*>(widget);
|
||||
if(widget)
|
||||
return widget;
|
||||
pcComboView = new ComboView(nullptr, getMainWindow());
|
||||
pcComboView->setObjectName(QStringLiteral(QT_TRANSLATE_NOOP("QDockWidget", "Model")));
|
||||
pcComboView->setMinimumWidth(150);
|
||||
widget = pcComboView;
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupDAGView(const std::string& hiddenDockWindows)
|
||||
{
|
||||
//TODO: Add external object support for DAGView
|
||||
//Task List (task watcher).
|
||||
if (d->hiddenDockWindows.find("Std_TaskWatcher") == std::string::npos) {
|
||||
//work through parameter.
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp/Preferences/DockWindows/TaskWatcher");
|
||||
bool enabled = group->GetBool("Enabled", false);
|
||||
group->SetBool("Enabled", enabled); //ensure entry exists.
|
||||
_updateDockWidget("Std_TaskWatcher", enabled, show, Qt::RightDockWidgetArea,
|
||||
[](QWidget *widget) {
|
||||
if(widget)
|
||||
return widget;
|
||||
widget = new TaskView::TaskView(getMainWindow());
|
||||
widget->setObjectName(QStringLiteral(QT_TRANSLATE_NOOP("QDockWidget","Task List")));
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
|
||||
//Dag View.
|
||||
if (hiddenDockWindows.find("Std_DAGView") == std::string::npos) {
|
||||
if (d->hiddenDockWindows.find("Std_DAGView") == std::string::npos) {
|
||||
//work through parameter.
|
||||
// old group name
|
||||
ParameterGrp::handle deprecateGroup = App::GetApplication().GetUserParameter().
|
||||
@@ -614,24 +640,68 @@ bool MainWindow::setupDAGView(const std::string& hiddenDockWindows)
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DockWindows")->GetGroup("DAGView");
|
||||
enabled = group->GetBool("Enabled", enabled);
|
||||
group->SetBool("Enabled", enabled); //ensure entry exists.
|
||||
if (enabled) {
|
||||
auto dagDockWindow = new DAG::DockWindow(nullptr, this);
|
||||
dagDockWindow->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","DAG View")));
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_DAGView", dagDockWindow);
|
||||
return true;
|
||||
}
|
||||
_updateDockWidget("Std_DAGView", enabled, show, Qt::RightDockWidgetArea,
|
||||
[](QWidget *widget) {
|
||||
if(widget)
|
||||
return widget;
|
||||
DAG::DockWindow *dagDockWindow = new DAG::DockWindow(nullptr, getMainWindow());
|
||||
dagDockWindow->setObjectName(QStringLiteral(QT_TRANSLATE_NOOP("QDockWidget","DAG View")));
|
||||
widget = dagDockWindow;
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setupDockWindows()
|
||||
{
|
||||
// Report view must be created before PythonConsole!
|
||||
setupReportView();
|
||||
setupPythonConsole();
|
||||
setupSelectionView();
|
||||
setupTaskView();
|
||||
|
||||
initDockWindows(false);
|
||||
}
|
||||
|
||||
bool MainWindow::setupTaskView()
|
||||
{
|
||||
// Task view
|
||||
if (d->hiddenDockWindows.find("Std_TaskView") == std::string::npos) {
|
||||
auto taskView = new Gui::TaskView::TaskView(this);
|
||||
taskView->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Tasks")));
|
||||
taskView->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_TaskView", taskView);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupReportView(const std::string& hiddenDockWindows)
|
||||
bool MainWindow::setupSelectionView()
|
||||
{
|
||||
// Selection view
|
||||
if (d->hiddenDockWindows.find("Std_SelectionView") == std::string::npos) {
|
||||
auto pcSelectionView = new SelectionView(nullptr, this);
|
||||
pcSelectionView->setObjectName
|
||||
(QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Selection view")));
|
||||
pcSelectionView->setMinimumWidth(210);
|
||||
|
||||
DockWindowManager* pDockMgr = DockWindowManager::instance();
|
||||
pDockMgr->registerDockWindow("Std_SelectionView", pcSelectionView);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupReportView()
|
||||
{
|
||||
// Report view
|
||||
if (hiddenDockWindows.find("Std_ReportView") == std::string::npos) {
|
||||
if (d->hiddenDockWindows.find("Std_ReportView") == std::string::npos) {
|
||||
auto pcReport = new ReportOutput(this);
|
||||
pcReport->setWindowIcon(BitmapFactory().pixmap("MacroEditor"));
|
||||
pcReport->setObjectName
|
||||
@@ -648,10 +718,10 @@ bool MainWindow::setupReportView(const std::string& hiddenDockWindows)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::setupPythonConsole(const std::string& hiddenDockWindows)
|
||||
bool MainWindow::setupPythonConsole()
|
||||
{
|
||||
// Python console
|
||||
if (hiddenDockWindows.find("Std_PythonView") == std::string::npos) {
|
||||
if (d->hiddenDockWindows.find("Std_PythonView") == std::string::npos) {
|
||||
auto pcPython = new PythonConsole(this);
|
||||
pcPython->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
|
||||
pcPython->setObjectName
|
||||
@@ -1589,37 +1659,49 @@ void MainWindow::switchToDockedMode()
|
||||
|
||||
void MainWindow::loadWindowSettings()
|
||||
{
|
||||
QString vendor = QString::fromLatin1(App::Application::Config()["ExeVendor"].c_str());
|
||||
QString application = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
|
||||
QString vendor = QString::fromUtf8(App::Application::Config()["ExeVendor"].c_str());
|
||||
QString application = QString::fromUtf8(App::Application::Config()["ExeName"].c_str());
|
||||
int major = (QT_VERSION >> 0x10) & 0xff;
|
||||
int minor = (QT_VERSION >> 0x08) & 0xff;
|
||||
QString qtver = QString::fromLatin1("Qt%1.%2").arg(major).arg(minor);
|
||||
QString qtver = QStringLiteral("Qt%1.%2").arg(major).arg(minor);
|
||||
QSettings config(vendor, application);
|
||||
|
||||
QRect rect = QApplication::primaryScreen()->availableGeometry();
|
||||
int maxHeight = rect.height();
|
||||
int maxWidth = rect.width();
|
||||
QRect rect = QApplication::desktop()->availableGeometry(d->screen);
|
||||
|
||||
config.beginGroup(qtver);
|
||||
QPoint pos = config.value(QString::fromLatin1("Position"), this->pos()).toPoint();
|
||||
maxWidth -= pos.x();
|
||||
maxHeight -= pos.y();
|
||||
this->resize(config.value(QString::fromLatin1("Size"), QSize(maxWidth, maxHeight)).toSize());
|
||||
QPoint pos = config.value(QStringLiteral("Position"), this->pos()).toPoint();
|
||||
QSize size = config.value(QStringLiteral("Size"), rect.size()).toSize();
|
||||
bool max = config.value(QStringLiteral("Maximized"), false).toBool();
|
||||
bool showStatusBar = config.value(QStringLiteral("StatusBar"), true).toBool();
|
||||
QByteArray windowState = config.value(QStringLiteral("MainWindowState")).toByteArray();
|
||||
config.endGroup();
|
||||
|
||||
int x1,x2,y1,y2;
|
||||
// make sure that the main window is not totally out of the visible rectangle
|
||||
rect.getCoords(&x1, &y1, &x2, &y2);
|
||||
pos.setX(qMin(qMax(pos.x(),x1-this->width()+30),x2-30));
|
||||
pos.setY(qMin(qMax(pos.y(),y1-10),y2-10));
|
||||
this->move(pos);
|
||||
{
|
||||
// tmp. disable the report window to suppress some bothering warnings
|
||||
const Base::ILoggerBlocker blocker("ReportOutput", Base::ConsoleSingleton::MsgType_Wrn);
|
||||
this->restoreState(config.value(QString::fromLatin1("MainWindowState")).toByteArray());
|
||||
std::string geometry = d->hGrp->GetASCII("Geometry");
|
||||
std::istringstream iss(geometry);
|
||||
int x,y,w,h;
|
||||
if (iss >> x >> y >> w >> h) {
|
||||
pos = QPoint(x,y);
|
||||
size = QSize(w,h);
|
||||
}
|
||||
max = d->hGrp->GetBool("Maximized", max);
|
||||
showStatusBar = d->hGrp->GetBool("StatusBar", showStatusBar);
|
||||
std::string wstate = d->hGrp->GetASCII("MainWindowState");
|
||||
if (wstate.size())
|
||||
windowState = QByteArray::fromBase64(wstate.c_str());
|
||||
|
||||
x = std::max<int>(rect.left(), std::min<int>(rect.left()+rect.width()/2, pos.x()));
|
||||
y = std::max<int>(rect.top(), std::min<int>(rect.top()+rect.height()/2, pos.y()));
|
||||
w = std::min<int>(rect.width(), size.width());
|
||||
h = std::min<int>(rect.height(), size.height());
|
||||
|
||||
this->move(x, y);
|
||||
this->resize(w, h);
|
||||
|
||||
Base::StateLocker guard(d->_restoring);
|
||||
|
||||
d->restoreWindowState(windowState);
|
||||
std::clog << "Main window restored" << std::endl;
|
||||
|
||||
bool max = config.value(QString::fromLatin1("Maximized"), false).toBool();
|
||||
max ? showMaximized() : show();
|
||||
|
||||
// make menus and tooltips usable in fullscreen under Windows, see issue #7563
|
||||
@@ -1629,31 +1711,84 @@ void MainWindow::loadWindowSettings()
|
||||
}
|
||||
#endif
|
||||
|
||||
statusBar()->setVisible(config.value(QString::fromLatin1("StatusBar"), true).toBool());
|
||||
config.endGroup();
|
||||
statusBar()->setVisible(showStatusBar);
|
||||
|
||||
ToolBarManager::getInstance()->restoreState();
|
||||
std::clog << "Toolbars restored" << std::endl;
|
||||
|
||||
OverlayManager::instance()->restore();
|
||||
}
|
||||
|
||||
void MainWindow::saveWindowSettings()
|
||||
bool MainWindow::isRestoringWindowState() const
|
||||
{
|
||||
QString vendor = QString::fromLatin1(App::Application::Config()["ExeVendor"].c_str());
|
||||
QString application = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
|
||||
return d->_restoring;
|
||||
}
|
||||
|
||||
void MainWindowP::restoreWindowState(const QByteArray &windowState)
|
||||
{
|
||||
if (windowState.isEmpty())
|
||||
return;
|
||||
|
||||
Base::StateLocker guard(_restoring);
|
||||
|
||||
// tmp. disable the report window to suppress some bothering warnings
|
||||
if (Base::Console().IsMsgTypeEnabled("ReportOutput", Base::ConsoleSingleton::MsgType_Wrn)) {
|
||||
Base::Console().SetEnabledMsgType("ReportOutput", Base::ConsoleSingleton::MsgType_Wrn, false);
|
||||
getMainWindow()->restoreState(windowState);
|
||||
Base::Console().SetEnabledMsgType("ReportOutput", Base::ConsoleSingleton::MsgType_Wrn, true);
|
||||
} else
|
||||
getMainWindow()->restoreState(windowState);
|
||||
|
||||
Base::ConnectionBlocker block(connParam);
|
||||
// as a notification for user code on window state restore
|
||||
hGrp->SetBool("WindowStateRestored", !hGrp->GetBool("WindowStateRestored", false));
|
||||
}
|
||||
|
||||
void MainWindow::saveWindowSettings(bool canDelay)
|
||||
{
|
||||
if (isRestoringWindowState())
|
||||
return;
|
||||
|
||||
if (canDelay) {
|
||||
d->saveStateTimer.start(100);
|
||||
return;
|
||||
}
|
||||
|
||||
QString vendor = QString::fromUtf8(App::Application::Config()["ExeVendor"].c_str());
|
||||
QString application = QString::fromUtf8(App::Application::Config()["ExeName"].c_str());
|
||||
int major = (QT_VERSION >> 0x10) & 0xff;
|
||||
int minor = (QT_VERSION >> 0x08) & 0xff;
|
||||
QString qtver = QString::fromLatin1("Qt%1.%2").arg(major).arg(minor);
|
||||
QString qtver = QStringLiteral("Qt%1.%2").arg(major).arg(minor);
|
||||
QSettings config(vendor, application);
|
||||
|
||||
#if 0
|
||||
config.beginGroup(qtver);
|
||||
config.setValue(QString::fromLatin1("Size"), this->size());
|
||||
config.setValue(QString::fromLatin1("Position"), this->pos());
|
||||
config.setValue(QString::fromLatin1("Maximized"), this->isMaximized());
|
||||
config.setValue(QString::fromLatin1("MainWindowState"), this->saveState());
|
||||
config.setValue(QString::fromLatin1("StatusBar"), this->statusBar()->isVisible());
|
||||
config.setValue(QStringLiteral("Size"), this->size());
|
||||
config.setValue(QStringLiteral("Position"), this->pos());
|
||||
config.setValue(QStringLiteral("Maximized"), this->isMaximized());
|
||||
config.setValue(QStringLiteral("MainWindowState"), this->saveState());
|
||||
config.setValue(QStringLiteral("StatusBar"), this->statusBar()->isVisible());
|
||||
config.endGroup();
|
||||
#else
|
||||
// We are migrating from saving qt main window layout state in QSettings to
|
||||
// FreeCAD parameters, for more control. The old settings is explicitly
|
||||
// remove from old QSettings conf to allow easier complete reset of
|
||||
// application state by just removing FC user.cfg file.
|
||||
config.remove(qtver);
|
||||
#endif
|
||||
|
||||
Base::ConnectionBlocker block(d->connParam);
|
||||
d->hGrp->SetBool("Maximized", this->isMaximized());
|
||||
d->hGrp->SetBool("StatusBar", this->statusBar()->isVisible());
|
||||
d->hGrp->SetASCII("MainWindowState", this->saveState().toBase64().constData());
|
||||
|
||||
std::ostringstream ss;
|
||||
QRect rect(this->pos(), this->size());
|
||||
ss << rect.left() << " " << rect.top() << " " << rect.width() << " " << rect.height();
|
||||
d->hGrp->SetASCII("Geometry", ss.str().c_str());
|
||||
|
||||
DockWindowManager::instance()->saveState();
|
||||
OverlayManager::instance()->save();
|
||||
ToolBarManager::getInstance()->saveState();
|
||||
}
|
||||
|
||||
@@ -1669,6 +1804,7 @@ void MainWindow::startSplasher()
|
||||
if (hGrp->GetBool("ShowSplasher", true)) {
|
||||
d->splashscreen = new SplashScreen(this->splashImage());
|
||||
d->splashscreen->show();
|
||||
d->screen = QApplication::desktop()->screenNumber(d->splashscreen);
|
||||
}
|
||||
else
|
||||
d->splashscreen = nullptr;
|
||||
@@ -2296,6 +2432,11 @@ void MainWindow::customEvent(QEvent* e)
|
||||
}
|
||||
}
|
||||
|
||||
QMdiArea *MainWindow::getMdiArea() const
|
||||
{
|
||||
return d->mdiArea;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
StatusBarObserver::StatusBarObserver()
|
||||
|
||||
@@ -105,6 +105,10 @@ public:
|
||||
* Returns a list of all MDI windows in the worpspace.
|
||||
*/
|
||||
QList<QWidget*> windows(QMdiArea::WindowOrder order = QMdiArea::CreationOrder) const;
|
||||
/**
|
||||
* Returns the internal QMdiArea instance.
|
||||
*/
|
||||
QMdiArea *getMdiArea() const;
|
||||
/**
|
||||
* Can be called after the caption of an MDIView has changed to update the tab's caption.
|
||||
*/
|
||||
@@ -152,7 +156,7 @@ public:
|
||||
/// Loads the main window settings.
|
||||
void loadWindowSettings();
|
||||
/// Saves the main window settings.
|
||||
void saveWindowSettings();
|
||||
void saveWindowSettings(bool canDelay = false);
|
||||
//@}
|
||||
|
||||
/** @name Menu
|
||||
@@ -203,6 +207,8 @@ public:
|
||||
enum StatusType {None, Err, Wrn, Pane, Msg, Log, Tmp, Critical};
|
||||
void showStatus(int type, const QString & message);
|
||||
|
||||
void initDockWindows(bool show);
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Updates the standard actions of a text editor such as Cut, Copy, Paste, Undo and Redo.
|
||||
@@ -254,6 +260,8 @@ public Q_SLOTS:
|
||||
|
||||
void showMessage (const QString & message, int timeout = 0);
|
||||
|
||||
bool isRestoringWindowState() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This method checks if the main window can be closed by checking all open documents and views.
|
||||
@@ -283,14 +291,10 @@ protected:
|
||||
|
||||
private:
|
||||
void setupDockWindows();
|
||||
bool setupTreeView(const std::string&);
|
||||
bool setupTaskView(const std::string&);
|
||||
bool setupPropertyView(const std::string&);
|
||||
bool setupSelectionView(const std::string&);
|
||||
bool setupComboView(const std::string&);
|
||||
bool setupDAGView(const std::string&);
|
||||
bool setupReportView(const std::string&);
|
||||
bool setupPythonConsole(const std::string&);
|
||||
bool setupTaskView();
|
||||
bool setupSelectionView();
|
||||
bool setupReportView();
|
||||
bool setupPythonConsole();
|
||||
|
||||
static void renderDevBuildWarning(QPainter &painter, const QPoint startPosition, const QSize maxSize);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
int m_CubeWidgetSize = 132;
|
||||
static int m_CubeWidgetSize;
|
||||
QColor m_BaseColor;
|
||||
QColor m_EmphaseColor;
|
||||
QColor m_HiliteColor;
|
||||
@@ -201,6 +201,13 @@ private:
|
||||
QMenu* m_Menu;
|
||||
};
|
||||
|
||||
int NaviCubeImplementation::m_CubeWidgetSize = 132;
|
||||
|
||||
int NaviCube::getNaviCubeSize()
|
||||
{
|
||||
return NaviCubeImplementation::m_CubeWidgetSize;
|
||||
}
|
||||
|
||||
NaviCube::NaviCube(Gui::View3DInventorViewer* viewer) {
|
||||
m_NaviCubeImplementation = new NaviCubeImplementation(viewer);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
// Label order: front, top, right, rear, bottom, left
|
||||
void setNaviCubeLabels(const std::vector<std::string>& labels);
|
||||
static void setNaviCubeCommands(const std::vector<std::string>& cmd);
|
||||
static int getNaviCubeSize();
|
||||
|
||||
private:
|
||||
NaviCubeImplementation* m_NaviCubeImplementation;
|
||||
|
||||
2052
src/Gui/OverlayManager.cpp
Normal file
190
src/Gui/OverlayManager.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FC_OVERLAYMANAGER_H
|
||||
#define FC_OVERLAYMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QAction;
|
||||
class QDockWidget;
|
||||
class QString;
|
||||
class QPoint;
|
||||
class QWidget;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class OverlayTabWidget;
|
||||
|
||||
/// Class that manages overlay dockable widgets
|
||||
class GuiExport OverlayManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlayManager();
|
||||
virtual ~OverlayManager();
|
||||
|
||||
/// restore states
|
||||
void restore();
|
||||
/// save states
|
||||
void save();
|
||||
/// Retranslate text on language change
|
||||
void retranslate();
|
||||
/// Reload icon images
|
||||
void refreshIcons();
|
||||
|
||||
/// Reload mode
|
||||
enum class ReloadMode {
|
||||
/// Reload is pending
|
||||
ReloadPending = 0,
|
||||
/// Reload is paused
|
||||
ReloadPause = 1,
|
||||
/// Resume state reload
|
||||
ReloadResume = 2,
|
||||
};
|
||||
/** Set reload mode
|
||||
*
|
||||
* An internal timer is used to batch handle all relevant parameter
|
||||
* changes. The function is provided to let other code temporarily disable
|
||||
* the timer before changing the parameter, and then resume it after done.
|
||||
*/
|
||||
void reload(ReloadMode mode = ReloadMode::ReloadPending);
|
||||
|
||||
/** Refresh overlay internal layout
|
||||
* @param widget: optional source widget that triggers the refresh
|
||||
* @param refreshStyle: whether to reload stylesheet
|
||||
*/
|
||||
void refresh(QWidget *widget=nullptr, bool refreshStyle=false);
|
||||
|
||||
/// Setup title bar for a QDockWidget
|
||||
void setupTitleBar(QDockWidget *);
|
||||
|
||||
/// Overlay mode
|
||||
enum class OverlayMode {
|
||||
/// Toggle the focused widget between normal and overlay on top of MDI client area
|
||||
ToggleActive,
|
||||
/// Toggle overlay dock widget background between opaque and transparent
|
||||
ToggleTransparent,
|
||||
/// Make the focused widget switch to overlay on top of MDI client area
|
||||
EnableActive,
|
||||
/// Make the focused widget switch back to normal dockable widget
|
||||
DisableActive,
|
||||
/// Make all docked widget switch to overlay
|
||||
EnableAll,
|
||||
/// Make all docked widget switch back to normal
|
||||
DisableAll,
|
||||
/// Toggle all docked widget between normal and overlay
|
||||
ToggleAll,
|
||||
/// Set all overlay dock widget to transparent background
|
||||
TransparentAll,
|
||||
/// Set all overlay dock widget to opaque background
|
||||
TransparentNone,
|
||||
/// Toggle all overlay dock widget background between opaque and transparent
|
||||
ToggleTransparentAll,
|
||||
/// Toggle show/hide of the left docked widgets
|
||||
ToggleLeft,
|
||||
/// Toggle show/hide of the right docked widgets
|
||||
ToggleRight,
|
||||
/// Toggle show/hide of the top docked widgets
|
||||
ToggleTop,
|
||||
/// Toggle show/hide of the bottom docked widgets
|
||||
ToggleBottom,
|
||||
};
|
||||
/// Set overlay mode
|
||||
void setOverlayMode(OverlayMode mode);
|
||||
|
||||
/// Enable/disable mouse transparent mode
|
||||
void setMouseTransparent(bool enabled);
|
||||
/// Report if mouse transparent mode is active
|
||||
bool isMouseTransparent() const;
|
||||
|
||||
/// Check if the cursor is within an overlay docked widget
|
||||
bool isUnderOverlay() const;
|
||||
|
||||
/// Initialize a newly created dock widget
|
||||
void initDockWidget(QDockWidget *);
|
||||
/// Prepare a dock widget for overlay display
|
||||
void setupDockWidget(QDockWidget *, int dockArea = Qt::NoDockWidgetArea);
|
||||
/// Switch a dock widget back to normal display
|
||||
void unsetupDockWidget(QDockWidget *);
|
||||
|
||||
/** Mouse event handler for dragging a dock widget
|
||||
* @param pos: mouse cursor position
|
||||
* @param widget: dragging widget, can either be a QDockWidget if it is
|
||||
* floating, or a OverlayTabWidget if docked in overlay mode
|
||||
* @param offset: offset from the mouse cursor to the widget origin
|
||||
* @param size: widget size before dragging start
|
||||
* @param drop: whether to drop after drag to the position
|
||||
*/
|
||||
void dragDockWidget(const QPoint &pos,
|
||||
QWidget *widget,
|
||||
const QPoint &offset,
|
||||
const QSize &size,
|
||||
bool drop = false);
|
||||
|
||||
/// Float an overlay docked widget
|
||||
void floatDockWidget(QDockWidget *);
|
||||
|
||||
/// Return the last widget whose mouse event got intercepted by the overlay manager for mouse pass through
|
||||
QWidget *getLastMouseInterceptWidget() const;
|
||||
|
||||
/// Return the stylesheet for overlay widgets
|
||||
const QString &getStyleSheet() const;
|
||||
|
||||
/// Check whether to hide tab in overlay dock widget
|
||||
bool getHideTab() const;
|
||||
|
||||
/// Helper function to set focus when switching active sub window
|
||||
static void setFocusView();
|
||||
|
||||
/// Return the singleton instance of the overlay manager
|
||||
static OverlayManager * instance();
|
||||
/// Destroy the overlay manager
|
||||
static void destruct();
|
||||
|
||||
class Private;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *ev);
|
||||
|
||||
/// Register a named docked widget with an overlay tab widget
|
||||
void registerDockWidget(const QString &name, OverlayTabWidget *);
|
||||
/// Unregister a named docked widget with an overlay tab widget
|
||||
void unregisterDockWidget(const QString &name, OverlayTabWidget *);
|
||||
|
||||
private:
|
||||
void onToggleDockWidget(bool checked);
|
||||
void onDockVisibleChange(bool visible);
|
||||
void onDockWidgetTitleChange(const QString &);
|
||||
void onTaskViewUpdate();
|
||||
void onFocusChanged(QWidget *, QWidget *);
|
||||
void onAction();
|
||||
void raiseAll();
|
||||
|
||||
private:
|
||||
friend class Private;
|
||||
friend class OverlayTabWidget;
|
||||
Private * d;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif // FC_OVERLAYMANAGER_H
|
||||
1151
src/Gui/OverlayParams.cpp
Normal file
422
src/Gui/OverlayParams.h
Normal file
@@ -0,0 +1,422 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef GUI_OVERLAY_PARAMS_H
|
||||
#define GUI_OVERLAY_PARAMS_H
|
||||
|
||||
/*[[[cog
|
||||
import OverlayParams
|
||||
OverlayParams.declare()
|
||||
]]]*/
|
||||
|
||||
// Auto generated code (Gui/OverlayParams.py:158)
|
||||
#include <QString>
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:72)
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:78)
|
||||
namespace Gui {
|
||||
/** Convenient class to obtain overlay widgets related parameters
|
||||
|
||||
* The parameters are under group "User parameter:BaseApp/Preferences/View"
|
||||
*
|
||||
* This class is auto generated by Gui/OverlayParams.py. Modify that file
|
||||
* instead of this one, if you want to add any parameter. You need
|
||||
* to install Cog Python package for code generation:
|
||||
* @code
|
||||
* pip install cogapp
|
||||
* @endcode
|
||||
*
|
||||
* Once modified, you can regenerate the header and the source file,
|
||||
* @code
|
||||
* python3 -m cogapp -r Gui/OverlayParams.h Gui/OverlayParams.cpp
|
||||
* @endcode
|
||||
*
|
||||
* You can add a new parameter by adding lines in Gui/OverlayParams.py. Available
|
||||
* parameter types are 'Int, UInt, String, Bool, Float'. For example, to add
|
||||
* a new Int type parameter,
|
||||
* @code
|
||||
* ParamInt(parameter_name, default_value, documentation, on_change=False)
|
||||
* @endcode
|
||||
*
|
||||
* If there is special handling on parameter change, pass in on_change=True.
|
||||
* And you need to provide a function implementation in Gui/OverlayParams.cpp with
|
||||
* the following signature.
|
||||
* @code
|
||||
* void OverlayParams:on<parameter_name>Changed()
|
||||
* @endcode
|
||||
*/
|
||||
class GuiExport OverlayParams {
|
||||
public:
|
||||
static ParameterGrp::handle getHandle();
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter CornerNaviCube
|
||||
static const long & getCornerNaviCube();
|
||||
static const long & defaultCornerNaviCube();
|
||||
static void removeCornerNaviCube();
|
||||
static void setCornerNaviCube(const long &v);
|
||||
static const char *docCornerNaviCube();
|
||||
static void onCornerNaviCubeChanged();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayAutoView
|
||||
static const bool & getDockOverlayAutoView();
|
||||
static const bool & defaultDockOverlayAutoView();
|
||||
static void removeDockOverlayAutoView();
|
||||
static void setDockOverlayAutoView(const bool &v);
|
||||
static const char *docDockOverlayAutoView();
|
||||
static void onDockOverlayAutoViewChanged();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayDelay
|
||||
///
|
||||
/// Overlay dock (re),layout delay.
|
||||
static const long & getDockOverlayDelay();
|
||||
static const long & defaultDockOverlayDelay();
|
||||
static void removeDockOverlayDelay();
|
||||
static void setDockOverlayDelay(const long &v);
|
||||
static const char *docDockOverlayDelay();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayRevealDelay
|
||||
static const long & getDockOverlayRevealDelay();
|
||||
static const long & defaultDockOverlayRevealDelay();
|
||||
static void removeDockOverlayRevealDelay();
|
||||
static void setDockOverlayRevealDelay(const long &v);
|
||||
static const char *docDockOverlayRevealDelay();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlaySplitterHandleTimeout
|
||||
///
|
||||
/// Overlay splitter handle auto hide delay. Set zero to disable auto hiding.
|
||||
static const long & getDockOverlaySplitterHandleTimeout();
|
||||
static const long & defaultDockOverlaySplitterHandleTimeout();
|
||||
static void removeDockOverlaySplitterHandleTimeout();
|
||||
static void setDockOverlaySplitterHandleTimeout(const long &v);
|
||||
static const char *docDockOverlaySplitterHandleTimeout();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayActivateOnHover
|
||||
///
|
||||
/// Show auto hidden dock overlay on mouse over.
|
||||
/// If disabled, then show on mouse click.
|
||||
static const bool & getDockOverlayActivateOnHover();
|
||||
static const bool & defaultDockOverlayActivateOnHover();
|
||||
static void removeDockOverlayActivateOnHover();
|
||||
static void setDockOverlayActivateOnHover(const bool &v);
|
||||
static const char *docDockOverlayActivateOnHover();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayAutoMouseThrough
|
||||
///
|
||||
/// Auto mouse click through transparent part of dock overlay.
|
||||
static const bool & getDockOverlayAutoMouseThrough();
|
||||
static const bool & defaultDockOverlayAutoMouseThrough();
|
||||
static void removeDockOverlayAutoMouseThrough();
|
||||
static void setDockOverlayAutoMouseThrough(const bool &v);
|
||||
static const char *docDockOverlayAutoMouseThrough();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayWheelPassThrough
|
||||
///
|
||||
/// Auto pass through mouse wheel event on transparent dock overlay.
|
||||
static const bool & getDockOverlayWheelPassThrough();
|
||||
static const bool & defaultDockOverlayWheelPassThrough();
|
||||
static void removeDockOverlayWheelPassThrough();
|
||||
static void setDockOverlayWheelPassThrough(const bool &v);
|
||||
static const char *docDockOverlayWheelPassThrough();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayWheelDelay
|
||||
///
|
||||
/// Delay capturing mouse wheel event for passing through if it is
|
||||
/// previously handled by other widget.
|
||||
static const long & getDockOverlayWheelDelay();
|
||||
static const long & defaultDockOverlayWheelDelay();
|
||||
static void removeDockOverlayWheelDelay();
|
||||
static void setDockOverlayWheelDelay(const long &v);
|
||||
static const char *docDockOverlayWheelDelay();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayAlphaRadius
|
||||
///
|
||||
/// If auto mouse click through is enabled, then this radius
|
||||
/// defines a region of alpha test under the mouse cursor.
|
||||
/// Auto click through is only activated if all pixels within
|
||||
/// the region are non-opaque.
|
||||
static const long & getDockOverlayAlphaRadius();
|
||||
static const long & defaultDockOverlayAlphaRadius();
|
||||
static void removeDockOverlayAlphaRadius();
|
||||
static void setDockOverlayAlphaRadius(const long &v);
|
||||
static const char *docDockOverlayAlphaRadius();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayCheckNaviCube
|
||||
///
|
||||
/// Leave space for Navigation Cube in dock overlay
|
||||
static const bool & getDockOverlayCheckNaviCube();
|
||||
static const bool & defaultDockOverlayCheckNaviCube();
|
||||
static void removeDockOverlayCheckNaviCube();
|
||||
static void setDockOverlayCheckNaviCube(const bool &v);
|
||||
static const char *docDockOverlayCheckNaviCube();
|
||||
static void onDockOverlayCheckNaviCubeChanged();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintTriggerSize
|
||||
///
|
||||
/// Auto hide hint visual display triggering width
|
||||
static const long & getDockOverlayHintTriggerSize();
|
||||
static const long & defaultDockOverlayHintTriggerSize();
|
||||
static void removeDockOverlayHintTriggerSize();
|
||||
static void setDockOverlayHintTriggerSize(const long &v);
|
||||
static const char *docDockOverlayHintTriggerSize();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintSize
|
||||
///
|
||||
/// Auto hide hint visual display width
|
||||
static const long & getDockOverlayHintSize();
|
||||
static const long & defaultDockOverlayHintSize();
|
||||
static void removeDockOverlayHintSize();
|
||||
static void setDockOverlayHintSize(const long &v);
|
||||
static const char *docDockOverlayHintSize();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintLeftLength
|
||||
///
|
||||
/// Auto hide hint visual display length for left panel. Set to zero to fill the space.
|
||||
static const long & getDockOverlayHintLeftLength();
|
||||
static const long & defaultDockOverlayHintLeftLength();
|
||||
static void removeDockOverlayHintLeftLength();
|
||||
static void setDockOverlayHintLeftLength(const long &v);
|
||||
static const char *docDockOverlayHintLeftLength();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintRightLength
|
||||
///
|
||||
/// Auto hide hint visual display length for right panel. Set to zero to fill the space.
|
||||
static const long & getDockOverlayHintRightLength();
|
||||
static const long & defaultDockOverlayHintRightLength();
|
||||
static void removeDockOverlayHintRightLength();
|
||||
static void setDockOverlayHintRightLength(const long &v);
|
||||
static const char *docDockOverlayHintRightLength();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintTopLength
|
||||
///
|
||||
/// Auto hide hint visual display length for top panel. Set to zero to fill the space.
|
||||
static const long & getDockOverlayHintTopLength();
|
||||
static const long & defaultDockOverlayHintTopLength();
|
||||
static void removeDockOverlayHintTopLength();
|
||||
static void setDockOverlayHintTopLength(const long &v);
|
||||
static const char *docDockOverlayHintTopLength();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintBottomLength
|
||||
///
|
||||
/// Auto hide hint visual display length for bottom panel. Set to zero to fill the space.
|
||||
static const long & getDockOverlayHintBottomLength();
|
||||
static const long & defaultDockOverlayHintBottomLength();
|
||||
static void removeDockOverlayHintBottomLength();
|
||||
static void setDockOverlayHintBottomLength(const long &v);
|
||||
static const char *docDockOverlayHintBottomLength();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintLeftOffset
|
||||
///
|
||||
/// Auto hide hint visual display offset for left panel
|
||||
static const long & getDockOverlayHintLeftOffset();
|
||||
static const long & defaultDockOverlayHintLeftOffset();
|
||||
static void removeDockOverlayHintLeftOffset();
|
||||
static void setDockOverlayHintLeftOffset(const long &v);
|
||||
static const char *docDockOverlayHintLeftOffset();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintRightOffset
|
||||
///
|
||||
/// Auto hide hint visual display offset for right panel
|
||||
static const long & getDockOverlayHintRightOffset();
|
||||
static const long & defaultDockOverlayHintRightOffset();
|
||||
static void removeDockOverlayHintRightOffset();
|
||||
static void setDockOverlayHintRightOffset(const long &v);
|
||||
static const char *docDockOverlayHintRightOffset();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintTopOffset
|
||||
///
|
||||
/// Auto hide hint visual display offset for top panel
|
||||
static const long & getDockOverlayHintTopOffset();
|
||||
static const long & defaultDockOverlayHintTopOffset();
|
||||
static void removeDockOverlayHintTopOffset();
|
||||
static void setDockOverlayHintTopOffset(const long &v);
|
||||
static const char *docDockOverlayHintTopOffset();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintBottomOffset
|
||||
///
|
||||
/// Auto hide hint visual display offset for bottom panel
|
||||
static const long & getDockOverlayHintBottomOffset();
|
||||
static const long & defaultDockOverlayHintBottomOffset();
|
||||
static void removeDockOverlayHintBottomOffset();
|
||||
static void setDockOverlayHintBottomOffset(const long &v);
|
||||
static const char *docDockOverlayHintBottomOffset();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintTabBar
|
||||
///
|
||||
/// Show tab bar on mouse over when auto hide
|
||||
static const bool & getDockOverlayHintTabBar();
|
||||
static const bool & defaultDockOverlayHintTabBar();
|
||||
static void removeDockOverlayHintTabBar();
|
||||
static void setDockOverlayHintTabBar(const bool &v);
|
||||
static const char *docDockOverlayHintTabBar();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHideTabBar
|
||||
///
|
||||
/// Hide tab bar in dock overlay
|
||||
static const bool & getDockOverlayHideTabBar();
|
||||
static const bool & defaultDockOverlayHideTabBar();
|
||||
static void removeDockOverlayHideTabBar();
|
||||
static void setDockOverlayHideTabBar(const bool &v);
|
||||
static const char *docDockOverlayHideTabBar();
|
||||
static void onDockOverlayHideTabBarChanged();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHintDelay
|
||||
///
|
||||
/// Delay before show hint visual
|
||||
static const long & getDockOverlayHintDelay();
|
||||
static const long & defaultDockOverlayHintDelay();
|
||||
static void removeDockOverlayHintDelay();
|
||||
static void setDockOverlayHintDelay(const long &v);
|
||||
static const char *docDockOverlayHintDelay();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayAnimationDuration
|
||||
///
|
||||
/// Auto hide animation duration, 0 to disable
|
||||
static const long & getDockOverlayAnimationDuration();
|
||||
static const long & defaultDockOverlayAnimationDuration();
|
||||
static void removeDockOverlayAnimationDuration();
|
||||
static void setDockOverlayAnimationDuration(const long &v);
|
||||
static const char *docDockOverlayAnimationDuration();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayAnimationCurve
|
||||
///
|
||||
/// Auto hide animation curve type
|
||||
static const long & getDockOverlayAnimationCurve();
|
||||
static const long & defaultDockOverlayAnimationCurve();
|
||||
static void removeDockOverlayAnimationCurve();
|
||||
static void setDockOverlayAnimationCurve(const long &v);
|
||||
static const char *docDockOverlayAnimationCurve();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayHidePropertyViewScrollBar
|
||||
///
|
||||
/// Hide property view scroll bar in dock overlay
|
||||
static const bool & getDockOverlayHidePropertyViewScrollBar();
|
||||
static const bool & defaultDockOverlayHidePropertyViewScrollBar();
|
||||
static void removeDockOverlayHidePropertyViewScrollBar();
|
||||
static void setDockOverlayHidePropertyViewScrollBar(const bool &v);
|
||||
static const char *docDockOverlayHidePropertyViewScrollBar();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:122)
|
||||
//@{
|
||||
/// Accessor for parameter DockOverlayMinimumSize
|
||||
///
|
||||
/// Minimum overlay dock widget width/height
|
||||
static const long & getDockOverlayMinimumSize();
|
||||
static const long & defaultDockOverlayMinimumSize();
|
||||
static void removeDockOverlayMinimumSize();
|
||||
static void setDockOverlayMinimumSize(const long &v);
|
||||
static const char *docDockOverlayMinimumSize();
|
||||
static void onDockOverlayMinimumSizeChanged();
|
||||
//@}
|
||||
|
||||
// Auto generated code (Gui/OverlayParams.py:164)
|
||||
static const std::vector<QString> AnimationCurveTypes;
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:150)
|
||||
}; // class OverlayParams
|
||||
} // namespace Gui
|
||||
//[[[end]]]
|
||||
|
||||
#endif // GUI_OVERLAY_PARAMS_H
|
||||
182
src/Gui/OverlayParams.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com>*
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program 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 Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
'''Auto code generator for overlay widgets related parameters in Preferences/View
|
||||
'''
|
||||
import cog
|
||||
import inspect, sys
|
||||
from os import sys, path
|
||||
|
||||
# import Tools/params_utils.py
|
||||
sys.path.append(path.join(path.dirname(path.dirname(path.abspath(__file__))), 'Tools'))
|
||||
import params_utils
|
||||
|
||||
from params_utils import ParamBool, ParamInt, ParamString, ParamUInt, ParamHex, \
|
||||
ParamFloat, ParamProxy, ParamLinePattern, ParamFile, \
|
||||
ParamComboBox, ParamColor, ParamSpinBox, auto_comment
|
||||
|
||||
NameSpace = 'Gui'
|
||||
ClassName = 'OverlayParams'
|
||||
ParamPath = 'User parameter:BaseApp/Preferences/View'
|
||||
ClassDoc = 'Convenient class to obtain overlay widgets related parameters'
|
||||
|
||||
AnimationCurveTypes = (
|
||||
"Linear",
|
||||
"InQuad",
|
||||
"OutQuad",
|
||||
"InOutQuad",
|
||||
"OutInQuad",
|
||||
"InCubic",
|
||||
"OutCubic",
|
||||
"InOutCubic",
|
||||
"OutInCubic",
|
||||
"InQuart",
|
||||
"OutQuart",
|
||||
"InOutQuart",
|
||||
"OutInQuart",
|
||||
"InQuint",
|
||||
"OutQuint",
|
||||
"InOutQuint",
|
||||
"OutInQuint",
|
||||
"InSine",
|
||||
"OutSine",
|
||||
"InOutSine",
|
||||
"OutInSine",
|
||||
"InExpo",
|
||||
"OutExpo",
|
||||
"InOutExpo",
|
||||
"OutInExpo",
|
||||
"InCirc",
|
||||
"OutCirc",
|
||||
"InOutCirc",
|
||||
"OutInCirc",
|
||||
"InElastic",
|
||||
"OutElastic",
|
||||
"InOutElastic",
|
||||
"OutInElastic",
|
||||
"InBack",
|
||||
"OutBack",
|
||||
"InOutBack",
|
||||
"OutInBack",
|
||||
"InBounce",
|
||||
"OutBounce",
|
||||
"InOutBounce",
|
||||
"OutInBounce",
|
||||
)
|
||||
|
||||
class ParamAnimationCurve(ParamProxy):
|
||||
WidgetType = 'Gui::PrefComboBox'
|
||||
|
||||
def widget_setter(self, _param):
|
||||
return None
|
||||
|
||||
def init_widget(self, param, row, group_name):
|
||||
super().init_widget(param, row, group_name)
|
||||
cog.out(f'''
|
||||
{auto_comment()}
|
||||
for (const auto &item : OverlayParams::AnimationCurveTypes)
|
||||
{param.widget_name}->addItem(item);''')
|
||||
cog.out(f'''
|
||||
{param.widget_name}->setCurrentIndex({param.namespace}::{param.class_name}::default{param.name}());''')
|
||||
|
||||
Params = [
|
||||
ParamInt('CornerNaviCube', 1, on_change=True),
|
||||
ParamBool('DockOverlayAutoView', True, on_change=True, title="Auto hide in non 3D view"),
|
||||
ParamInt('DockOverlayDelay', 200, "Overlay dock (re),layout delay.", title="Layout delay (ms)", proxy=ParamSpinBox(0, 5000, 100)),
|
||||
ParamInt('DockOverlayRevealDelay', 2000),
|
||||
ParamInt('DockOverlaySplitterHandleTimeout', 0, title="Splitter auto hide delay (ms)", proxy=ParamSpinBox(0, 99999, 100),
|
||||
doc="Overlay splitter handle auto hide delay. Set zero to disable auto hiding."),
|
||||
ParamBool('DockOverlayActivateOnHover', True, title="Activate on hover",
|
||||
doc="Show auto hidden dock overlay on mouse over.\n"
|
||||
"If disabled, then show on mouse click."),
|
||||
ParamBool('DockOverlayAutoMouseThrough', True,
|
||||
"Auto mouse click through transparent part of dock overlay.", title="Auto mouse pass through"),
|
||||
ParamBool('DockOverlayWheelPassThrough', True,
|
||||
"Auto pass through mouse wheel event on transparent dock overlay.", title="Auto mouse wheel pass through"),
|
||||
ParamInt('DockOverlayWheelDelay', 1000, title="Delay mouse wheel pass through (ms)", proxy=ParamSpinBox(0, 99999, 1),
|
||||
doc="Delay capturing mouse wheel event for passing through if it is\n"
|
||||
"previously handled by other widget."),
|
||||
ParamInt('DockOverlayAlphaRadius', 2, title="Alpha test radius", proxy=ParamSpinBox(1, 100, 1), doc=\
|
||||
"If auto mouse click through is enabled, then this radius\n"
|
||||
"defines a region of alpha test under the mouse cursor.\n"
|
||||
"Auto click through is only activated if all pixels within\n"
|
||||
"the region are non-opaque."),
|
||||
ParamBool('DockOverlayCheckNaviCube', True, on_change=True, title="Check Navigation Cube",
|
||||
doc="Leave space for Navigation Cube in dock overlay"),
|
||||
ParamInt('DockOverlayHintTriggerSize', 16, title="Hint trigger size", proxy=ParamSpinBox(1, 100, 1),
|
||||
doc="Auto hide hint visual display triggering width"),
|
||||
ParamInt('DockOverlayHintSize', 8, title="Hint width", proxy=ParamSpinBox(1, 100, 1),
|
||||
doc="Auto hide hint visual display width"),
|
||||
ParamInt('DockOverlayHintLeftLength', 100, title='Left panel hint length', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display length for left panel. Set to zero to fill the space."),
|
||||
ParamInt('DockOverlayHintRightLength', 100, title='Right panel hint length', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display length for right panel. Set to zero to fill the space."),
|
||||
ParamInt('DockOverlayHintTopLength', 100, title='Top panel hint length', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display length for top panel. Set to zero to fill the space."),
|
||||
ParamInt('DockOverlayHintBottomLength', 100, title='Bottom panel hint length', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display length for bottom panel. Set to zero to fill the space."),
|
||||
ParamInt('DockOverlayHintLeftOffset', 0, title='Left panel hint offset', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display offset for left panel"),
|
||||
ParamInt('DockOverlayHintRightOffset', 0, title='Right panel hint offset', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display offset for right panel"),
|
||||
ParamInt('DockOverlayHintTopOffset', 0, title='Top panel hint offset', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display offset for top panel"),
|
||||
ParamInt('DockOverlayHintBottomOffset', 0, title='Bottom panel hint offset', proxy=ParamSpinBox(0, 10000, 10),
|
||||
doc="Auto hide hint visual display offset for bottom panel"),
|
||||
ParamBool('DockOverlayHintTabBar', False, "Show tab bar on mouse over when auto hide", title="Hint show tab bar"),
|
||||
ParamBool('DockOverlayHideTabBar', True, on_change=True, doc="Hide tab bar in dock overlay", title='Hide tab bar'),
|
||||
ParamInt('DockOverlayHintDelay', 200, "Delay before show hint visual", title="Hint delay (ms)", proxy=ParamSpinBox(0, 1000, 100)),
|
||||
ParamInt('DockOverlayAnimationDuration', 200, "Auto hide animation duration, 0 to disable",
|
||||
title="Animation duration (ms)", proxy=ParamSpinBox(0, 5000, 100)),
|
||||
ParamInt('DockOverlayAnimationCurve', 7, "Auto hide animation curve type", title="Animation curve type", proxy=ParamAnimationCurve()),
|
||||
ParamBool('DockOverlayHidePropertyViewScrollBar', False, "Hide property view scroll bar in dock overlay", title="Hide property view scroll bar"),
|
||||
ParamInt('DockOverlayMinimumSize', 30, on_change=True,
|
||||
doc="Minimum overlay dock widget width/height",
|
||||
title="Minimum dock widget size"),
|
||||
]
|
||||
|
||||
def declare():
|
||||
cog.out(f'''
|
||||
{auto_comment()}
|
||||
#include <QString>
|
||||
''')
|
||||
|
||||
params_utils.declare_begin(sys.modules[__name__])
|
||||
cog.out(f'''
|
||||
{auto_comment()}
|
||||
static const std::vector<QString> AnimationCurveTypes;
|
||||
''')
|
||||
params_utils.declare_end(sys.modules[__name__])
|
||||
|
||||
def define():
|
||||
params_utils.define(sys.modules[__name__])
|
||||
cog.out(f'''
|
||||
{auto_comment()}
|
||||
const std::vector<QString> OverlayParams::AnimationCurveTypes = {{''')
|
||||
for item in AnimationCurveTypes:
|
||||
cog.out(f'''
|
||||
QStringLiteral("{item}"),''')
|
||||
cog.out(f'''
|
||||
}};
|
||||
''')
|
||||
|
||||
|
||||
params_utils.init_params(Params, NameSpace, ClassName, ParamPath)
|
||||
2487
src/Gui/OverlayWidgets.cpp
Normal file
630
src/Gui/OverlayWidgets.h
Normal file
@@ -0,0 +1,630 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2020 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FC_OVERLAYWIDGETS_H
|
||||
#define FC_OVERLAYWIDGETS_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include <QAction>
|
||||
#include <QToolButton>
|
||||
#include <QGraphicsEffect>
|
||||
#include <QImage>
|
||||
#include <QDockWidget>
|
||||
#include <QSplitter>
|
||||
#include <QMenu>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#include "OverlayManager.h"
|
||||
|
||||
class QPropertyAnimation;
|
||||
class QLayoutItem;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class OverlayTabWidget;
|
||||
class OverlayTitleBar;
|
||||
class OverlaySplitterHandle;
|
||||
class OverlaySizeGrip;
|
||||
class OverlayProxyWidget;
|
||||
class OverlayGraphicsEffect;
|
||||
class OverlayDragFrame;
|
||||
|
||||
/// Tab widget to contain dock widgets in overlay mode
|
||||
class OverlayTabWidget: public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/** @name Graphics effect properties for customization through stylesheet */
|
||||
//@{
|
||||
Q_PROPERTY(QColor effectColor READ effectColor WRITE setEffectColor) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(int effectWidth READ effectWidth WRITE setEffectWidth) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(int effectHeight READ effectHeight WRITE setEffectHeight) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(qreal effectOffsetX READ effectOffsetX WRITE setEffectOffsetX) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(qreal effectOffsetY READ effectOffsetY WRITE setEffectOffsetY) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(qreal effectBlurRadius READ effectBlurRadius WRITE setEffectBlurRadius) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(bool enableEffect READ effectEnabled WRITE setEffectEnabled) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(qreal animation READ animation WRITE setAnimation) // clazy:exclude=qproperty-without-notify
|
||||
//@}
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
* @param parent: parent widget
|
||||
* @param pos: docking position
|
||||
*/
|
||||
OverlayTabWidget(QWidget *parent, Qt::DockWidgetArea pos);
|
||||
|
||||
/// Enable/disable overlay mode for this tab widget
|
||||
void setOverlayMode(bool enable);
|
||||
|
||||
/// Update splitter handle according to overlay status
|
||||
void updateSplitterHandles();
|
||||
|
||||
/** Add a dock widget
|
||||
* @param widget: dock widget to be added
|
||||
* @param title: title for the dock widget
|
||||
*/
|
||||
void addWidget(QDockWidget *widget, const QString &title);
|
||||
|
||||
/** Remove a dock widget
|
||||
* @param widget: dock widget to be removed
|
||||
* @param last: optional non overlaid widget. If given, then the removed
|
||||
* dock widget will be tabified together with this one.
|
||||
*/
|
||||
void removeWidget(QDockWidget *widget, QDockWidget *last=nullptr);
|
||||
|
||||
/** Set the current dock widget
|
||||
* @param widget: an overlay dock widget
|
||||
*
|
||||
* All other dock widget in the same tab widget will be collapsed, and the
|
||||
* give widget will take the whole space. This is actually handled inside
|
||||
* onCurrentChanged().
|
||||
*/
|
||||
void setCurrent(QDockWidget *widget);
|
||||
|
||||
/** Handle ESC key press
|
||||
*
|
||||
* If the this overlay tab widget is hidden and its hint/tabs are visible,
|
||||
* pressing ESC will hide the hint and tabs.
|
||||
*
|
||||
* If this overlay tab widget is visible and the current mouse cursor is on
|
||||
* top of the tab widget title bar or any of its split handler, then
|
||||
* pressing ESC will hide the title bar and split handler.
|
||||
*/
|
||||
bool onEscape();
|
||||
|
||||
/// Enable/disable transparent background mode
|
||||
void setTransparent(bool enable);
|
||||
|
||||
/// Check if transparent background mode is active
|
||||
bool isTransparent() const;
|
||||
|
||||
/// Auto mode to show or hide the tab widget
|
||||
enum class AutoMode {
|
||||
/// No auto show or hide
|
||||
NoAutoMode,
|
||||
/// Auto hide tab widget on lost of focus
|
||||
AutoHide,
|
||||
/// Auto show tab widget on any new editing task
|
||||
EditShow,
|
||||
/// Auto hide tab widget on any new editing task
|
||||
EditHide,
|
||||
/// Auto show on any task panel e.g. suggestive task panel in PartDesign
|
||||
TaskShow,
|
||||
};
|
||||
/// Set auto mode to show or hide the tab widget
|
||||
void setAutoMode(AutoMode mode);
|
||||
/// Get current auto mode
|
||||
AutoMode getAutoMode() const { return autoMode; }
|
||||
|
||||
/// Touch the tab widget to trigger saving of settings
|
||||
void touch() {touched = true;}
|
||||
/// Check if the tab widget settings need to be saved
|
||||
bool isTouched() const {return touched;}
|
||||
|
||||
/// Set geometry of this tab widget
|
||||
void setRect(QRect rect);
|
||||
|
||||
/// Get the geometry of this tab widget
|
||||
const QRect &getRect();
|
||||
|
||||
/// Overlay query option
|
||||
enum class QueryOption {
|
||||
/// Report the current overlay status
|
||||
QueryOverlay,
|
||||
/// Report true if transparency status has been changed
|
||||
TransparencyChanged,
|
||||
/// Report true if transparency status has not been changed
|
||||
TransparencyNotChanged,
|
||||
};
|
||||
/// Query overlay status
|
||||
bool isOverlaid(QueryOption option=QueryOption::QueryOverlay) const;
|
||||
/** Check if needs to auto hide this tab widget
|
||||
*
|
||||
* Besides when auto hide mode is activated by user, the tab widget will
|
||||
* also auto hide if the current view does not have panning capability
|
||||
* (queried through MdiView::hasMsg("CanPan")). The user can explicitly
|
||||
* disable this auto hide if no pan by setting user parameter
|
||||
* View/DockOverlayAutoView, or preference option Display -> UI -> Auto
|
||||
* hide in non 3D view.
|
||||
*/
|
||||
bool checkAutoHide() const;
|
||||
/** Obtain geometry of auto hiding tab widget
|
||||
* @param rect: output geometry of the tab widget
|
||||
* @return Return true if the tab widget should be auto hiding
|
||||
*/
|
||||
bool getAutoHideRect(QRect &rect) const;
|
||||
/// Handler of various actions exposed as buttons on title bar
|
||||
void onAction(QAction *);
|
||||
/// Sync relevant actions status with the current auto mode
|
||||
void syncAutoMode();
|
||||
|
||||
/** Set tab widget position offset
|
||||
* @param ofs: the offset size. Width is the x offset for top and bottom
|
||||
* docking tab widget, and y offset for left and right ones. Height is the y
|
||||
* offset for top and bottom, and x offset for left and right ones.
|
||||
*/
|
||||
void setOffset(const QSize &ofs);
|
||||
/// Get the tab widget position offset
|
||||
const QSize &getOffset() const {return offset;}
|
||||
|
||||
/** Set tab widget size delta
|
||||
* @param delta: the size delta. For left and right widget, the delta is
|
||||
* added to the height of the tab widget. For top and bottom widget, it is
|
||||
* added to the width.
|
||||
*/
|
||||
void setSizeDelta(int delta);
|
||||
/// Get the tab widget size delta
|
||||
int getSizeDelta() const {return sizeDelta;}
|
||||
|
||||
/// Obtain the proxy widget
|
||||
OverlayProxyWidget *getProxyWidget() {return proxyWidget;}
|
||||
|
||||
/// Obtain the current dock widget
|
||||
QDockWidget *currentDockWidget() const;
|
||||
/// Obtain the dock widget by index
|
||||
QDockWidget *dockWidget(int index) const;
|
||||
/// Obtain the index of a given dock widget
|
||||
int dockWidgetIndex(QDockWidget *) const;
|
||||
|
||||
/// Set the title bar for this tab widget
|
||||
void setTitleBar(QWidget *);
|
||||
|
||||
/// Get the splitter
|
||||
QSplitter *getSplitter() const {return splitter;}
|
||||
/// Get the title bar
|
||||
QWidget *getTitleBar() const {return titleBar;}
|
||||
|
||||
/// Get the docking position of this tab widget
|
||||
Qt::DockWidgetArea getDockArea() const {return dockArea;}
|
||||
|
||||
/// Get delay time for animated reveal
|
||||
const QTime &getRevealTime() const {return revealTime;}
|
||||
/// Set delay time for animated reveal
|
||||
void setRevealTime(const QTime &time);
|
||||
|
||||
/// Restore state
|
||||
void restore(ParameterGrp::handle handle);
|
||||
/// Save tab orders and positions
|
||||
void saveTabs();
|
||||
|
||||
/** @name Graphics effect properties setters and getters */
|
||||
//@{
|
||||
QColor effectColor() const;
|
||||
void setEffectColor(const QColor&);
|
||||
int effectWidth() const;
|
||||
void setEffectWidth(int);
|
||||
int effectHeight() const;
|
||||
void setEffectHeight(int);
|
||||
qreal effectOffsetX() const;
|
||||
void setEffectOffsetX(qreal);
|
||||
qreal effectOffsetY() const;
|
||||
void setEffectOffsetY(qreal);
|
||||
qreal effectBlurRadius() const;
|
||||
void setEffectBlurRadius(qreal);
|
||||
bool effectEnabled() const;
|
||||
void setEffectEnabled(bool);
|
||||
qreal animation() const {return _animation;}
|
||||
void setAnimation(qreal);
|
||||
//@}
|
||||
|
||||
/// Schedule for repaint
|
||||
void scheduleRepaint();
|
||||
|
||||
/** Return the pixel alpha value at the give position
|
||||
* @param pos: position
|
||||
* @param radiusScale: scale of the radius to check for alpha.
|
||||
*
|
||||
* @return Returns the largest alpha value of a circular area of 'pos' as
|
||||
* center and radius as defined by user parameter
|
||||
* View/DockOverlayAlphaRadius. May return -1 if out side of the widget, or
|
||||
* zero if transparent.
|
||||
*/
|
||||
int testAlpha(const QPoint &pos, int radiusScale);
|
||||
|
||||
/// Start animated showing
|
||||
void startShow();
|
||||
/// Start animated hiding
|
||||
void startHide();
|
||||
|
||||
/// Internal state of the tab widget
|
||||
enum class State {
|
||||
/// The tab widget is showing
|
||||
Showing,
|
||||
/// Normal visible state
|
||||
Normal,
|
||||
/// Visual hint is visible
|
||||
Hint,
|
||||
/// Hint is hidden by user after pressing ESC
|
||||
HintHidden,
|
||||
/// The tab widget is explicitly hidden by user
|
||||
Hidden,
|
||||
};
|
||||
/// Set state of the tab widget
|
||||
void setState(State);
|
||||
/// Get the state of the widget
|
||||
State getState() const {return _state;}
|
||||
|
||||
/// Handle splitter resize
|
||||
void onSplitterResize(int index);
|
||||
|
||||
/// Check if the tab widget is saving its state
|
||||
bool isSaving() const {return _saving;}
|
||||
|
||||
/// Helper function to create title bar for a dock widget
|
||||
static QWidget *createTitleButton(QAction *action, int size);
|
||||
/// Helper function to prepare a widget as a title widget
|
||||
static QLayoutItem *prepareTitleWidget(QWidget *widget, const QList<QAction*> &actions);
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
void changeEvent(QEvent*);
|
||||
void resizeEvent(QResizeEvent*);
|
||||
void paintEvent(QPaintEvent *);
|
||||
bool event(QEvent *ev);
|
||||
bool eventFilter(QObject *, QEvent *ev);
|
||||
|
||||
void retranslate();
|
||||
void refreshIcons();
|
||||
|
||||
/// Overlay mode options
|
||||
enum class OverlayOption {
|
||||
/// Enable overlay
|
||||
Enable,
|
||||
/// Disable overlay
|
||||
Disable,
|
||||
/// Enable overlay and show tab bar
|
||||
ShowTab,
|
||||
};
|
||||
/// Toggle overlay mode for a given widget
|
||||
void setOverlayMode(QWidget *widget, OverlayOption option);
|
||||
/// Helper function to set overlay mode for a give widget
|
||||
static void _setOverlayMode(QWidget *widget, OverlayOption option);
|
||||
|
||||
protected:
|
||||
void onCurrentChanged(int index);
|
||||
void onTabMoved(int from, int to);
|
||||
void onRepaint();
|
||||
void onAnimationStateChanged();
|
||||
void setupLayout();
|
||||
void onSizeGripMove(const QPoint &);
|
||||
|
||||
private:
|
||||
friend class OverlayProxyWidget;
|
||||
friend class OverlayTitleBar;
|
||||
friend class OverlayManager;
|
||||
friend class OverlayManager::Private;
|
||||
friend class OverlaySplitterHandle;
|
||||
friend class OverlaySizeGrip;
|
||||
|
||||
QSize offset;
|
||||
int sizeDelta = 0;
|
||||
QRect rectOverlay;
|
||||
OverlayProxyWidget *proxyWidget;
|
||||
QSplitter *splitter = nullptr;
|
||||
QWidget *titleBar = nullptr;
|
||||
QAction actNoAutoMode;
|
||||
QAction actAutoHide;
|
||||
QAction actEditHide;
|
||||
QAction actEditShow;
|
||||
QAction actTaskShow;
|
||||
QAction actAutoMode;
|
||||
QMenu autoModeMenu;
|
||||
QAction actTransparent;
|
||||
QAction actIncrease;
|
||||
QAction actDecrease;
|
||||
QAction actOverlay;
|
||||
QTimer timer;
|
||||
QTimer repaintTimer;
|
||||
AutoMode autoMode = AutoMode::NoAutoMode;
|
||||
bool repainting = false;
|
||||
bool overlaid = false;
|
||||
bool currentTransparent = false;
|
||||
bool touched = false;
|
||||
bool busy = false;
|
||||
Qt::DockWidgetArea dockArea;
|
||||
int tabSize = 0;
|
||||
QTime revealTime;
|
||||
ParameterGrp::handle hGrp;
|
||||
|
||||
OverlayGraphicsEffect *_graphicsEffect = nullptr;
|
||||
OverlayGraphicsEffect *_graphicsEffectTab = nullptr;
|
||||
bool _effectEnabled = false;
|
||||
|
||||
QImage _image;
|
||||
qreal _imageScale;
|
||||
|
||||
qreal _animation = 0;
|
||||
QPropertyAnimation *_animator = nullptr;
|
||||
|
||||
State _state = State::Normal;
|
||||
|
||||
std::map<QDockWidget *, int> _sizemap;
|
||||
bool _saving = false;
|
||||
|
||||
static OverlayDragFrame *_DragFrame;
|
||||
static QDockWidget *_DragFloating;
|
||||
static QWidget *_Dragging;
|
||||
static OverlayTabWidget *_LeftOverlay;
|
||||
static OverlayTabWidget *_RightOverlay;
|
||||
static OverlayTabWidget *_TopOverlay;
|
||||
static OverlayTabWidget *_BottomOverlay;
|
||||
};
|
||||
|
||||
/// A translucent frame as a visual indicator when dragging a dock widget
|
||||
class OverlayDragFrame: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlayDragFrame(QWidget * parent);
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
};
|
||||
|
||||
/// Title bar for OverlayTabWidget
|
||||
class OverlayTitleBar: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlayTitleBar(QWidget * parent);
|
||||
void setTitleItem(QLayoutItem *);
|
||||
void endDrag();
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
void paintEvent(QPaintEvent*);
|
||||
void keyPressEvent(QKeyEvent *ke);
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
private:
|
||||
QPoint dragOffset;
|
||||
QSize dragSize;
|
||||
QLayoutItem *titleItem = nullptr;
|
||||
QColor textcolor;
|
||||
int timerId = 0;
|
||||
bool blink = false;
|
||||
bool mouseMovePending = false;
|
||||
bool ignoreMouse = false;
|
||||
};
|
||||
|
||||
/// Size grip for title bar and split handler of OverlayTabWidget
|
||||
class OverlaySizeGrip: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlaySizeGrip(QWidget *parent, bool vertical);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dragMove(const QPoint &globalPos);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
const QPixmap &pixmap() const;
|
||||
|
||||
private:
|
||||
bool vertical;
|
||||
};
|
||||
|
||||
/// Splitter for OverlayTabWidget
|
||||
class OverlaySplitter : public QSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlaySplitter(QWidget *parent);
|
||||
void retranslate();
|
||||
|
||||
protected:
|
||||
virtual QSplitterHandle *createHandle();
|
||||
};
|
||||
|
||||
|
||||
/// Splitter handle for dragging the splitter
|
||||
class OverlaySplitterHandle : public QSplitterHandle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend class OverlaySplitter;
|
||||
|
||||
OverlaySplitterHandle(Qt::Orientation, QSplitter *parent);
|
||||
void setTitleItem(QLayoutItem *);
|
||||
void retranslate();
|
||||
void refreshIcons();
|
||||
QDockWidget * dockWidget();
|
||||
|
||||
void showTitle(bool enable);
|
||||
bool isShowing() const { return _showTitle; }
|
||||
void endDrag();
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent *);
|
||||
virtual void enterEvent(QEvent *);
|
||||
virtual void leaveEvent(QEvent *);
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
virtual void changeEvent(QEvent*);
|
||||
virtual void mouseMoveEvent(QMouseEvent *);
|
||||
virtual void mousePressEvent(QMouseEvent *);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *);
|
||||
virtual void keyPressEvent(QKeyEvent *);
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
protected:
|
||||
void onAction();
|
||||
void onTimer();
|
||||
|
||||
private:
|
||||
QLayoutItem * titleItem = nullptr;
|
||||
int idx = -1;
|
||||
QAction actFloat;
|
||||
bool _showTitle = true;
|
||||
int dragging = 0;
|
||||
QPoint dragOffset;
|
||||
QSize dragSize;
|
||||
QTimer timer;
|
||||
};
|
||||
|
||||
|
||||
/// Tool button for the title bar of the OverlayTabWidget
|
||||
class OverlayToolButton: public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlayToolButton(QWidget *parent);
|
||||
};
|
||||
|
||||
/** Class for handling visual hint for bringing back hidden overlay dock widget
|
||||
*
|
||||
* The proxy widget is transparent except a customizable rectangle area with a
|
||||
* selectable color shown as the visual hint. The hint is normally hidden, and
|
||||
* is shown only if the mouse hovers within the widget. When the hint area is
|
||||
* clicked, it will bring back hidden overlay dock panel. Note that the proxy
|
||||
* widget itself is mouse transparent as well, meaning that it will not receive
|
||||
* any mouse event. It is handled in the OverlayManager event filter.
|
||||
*/
|
||||
class OverlayProxyWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QBrush hintColor READ hintColor WRITE setHintColor) // clazy:exclude=qproperty-without-notify
|
||||
|
||||
public:
|
||||
OverlayProxyWidget(OverlayTabWidget *);
|
||||
|
||||
OverlayTabWidget *getOwner() const {return owner;}
|
||||
|
||||
/// For representing hit region
|
||||
enum class HitTest {
|
||||
/// Not hitting
|
||||
HitNone = 0,
|
||||
/// Hitting the proxy widget size but not within the visible hint area.
|
||||
HitOuter = 1,
|
||||
/// Hitting the visible hint area.
|
||||
HitInner = 2,
|
||||
};
|
||||
/** Mouse cursor hit test
|
||||
* @param pos: cursor position
|
||||
* @param delay: Whether to delay showing hint on mouse hit
|
||||
*/
|
||||
HitTest hitTest(const QPoint &pos, bool delay=true);
|
||||
|
||||
/// Check if the visual hint is showing
|
||||
bool isActivated() const;
|
||||
|
||||
QBrush hintColor() const;
|
||||
void setHintColor(const QBrush &);
|
||||
|
||||
QRect getRect() const;
|
||||
|
||||
void onMousePress();
|
||||
|
||||
protected:
|
||||
void enterEvent(QEvent*);
|
||||
void hideEvent(QHideEvent*);
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
protected:
|
||||
void onTimer();
|
||||
|
||||
private:
|
||||
OverlayTabWidget* owner;
|
||||
int drawLine = false;
|
||||
int dockArea;
|
||||
QTimer timer;
|
||||
QBrush _hintColor;
|
||||
};
|
||||
|
||||
/** Graphic effects for drawing shadow and outline of text on transparent background
|
||||
*
|
||||
* Modified from https://stackoverflow.com/a/23752747
|
||||
*/
|
||||
class OverlayGraphicsEffect: public QGraphicsEffect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OverlayGraphicsEffect(QObject *parent);
|
||||
|
||||
virtual void draw(QPainter* painter);
|
||||
virtual QRectF boundingRectFor(const QRectF& rect) const;
|
||||
|
||||
inline void setSize(const QSize &size)
|
||||
{ if(_size!=size){_size = size; updateBoundingRect(); } }
|
||||
|
||||
inline QSize size() const { return _size; }
|
||||
|
||||
inline void setOffset(const QPointF &offset)
|
||||
{ if(_offset!=offset) {_offset = offset; updateBoundingRect(); } }
|
||||
|
||||
inline QPointF offset() const { return _offset; }
|
||||
|
||||
inline void setBlurRadius(qreal blurRadius)
|
||||
{ if(_blurRadius!=blurRadius) {_blurRadius = blurRadius; updateBoundingRect();} }
|
||||
|
||||
inline qreal blurRadius() const { return _blurRadius; }
|
||||
|
||||
inline void setColor(const QColor& color) { _color = color; }
|
||||
inline QColor color() const { return _color; }
|
||||
|
||||
inline bool enabled() const {return _enabled;}
|
||||
inline void setEnabled(bool enabled)
|
||||
{ if(_enabled!=enabled) {_enabled = enabled; updateBoundingRect();} }
|
||||
|
||||
private:
|
||||
bool _enabled;
|
||||
QSize _size;
|
||||
qreal _blurRadius;
|
||||
QColor _color;
|
||||
QPointF _offset;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif // FC_OVERLAYWIDGETS_H
|
||||
@@ -10,6 +10,22 @@ SET(Stylesheets_Files
|
||||
"Light-modern.qss"
|
||||
)
|
||||
|
||||
SET(Overlay_Stylesheets_Files
|
||||
"overlay/Dark.qss"
|
||||
"overlay/Light.qss"
|
||||
"overlay/Dark-Outline.qss"
|
||||
"overlay/Light-Outline.qss"
|
||||
"overlay/close.svg"
|
||||
"overlay/overlay.svg"
|
||||
"overlay/float.svg"
|
||||
"overlay/autohide.svg"
|
||||
"overlay/editshow.svg"
|
||||
"overlay/taskshow.svg"
|
||||
"overlay/edithide.svg"
|
||||
"overlay/mode.svg"
|
||||
"overlay/transparent.svg"
|
||||
)
|
||||
|
||||
# Find all the image files
|
||||
FILE(GLOB Images_Files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/images_dark-light/*.svg")
|
||||
@@ -17,11 +33,13 @@ FILE(GLOB Images_Files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
SOURCE_GROUP("images_dark-light" FILES ${Images_Files})
|
||||
|
||||
ADD_CUSTOM_TARGET(Stylesheets_data ALL
|
||||
SOURCES ${Stylesheets_Files} ${Images_Files}
|
||||
SOURCES ${Stylesheets_Files} ${Images_Files} ${Overlay_Stylesheets_Files}
|
||||
)
|
||||
|
||||
fc_copy_sources(Stylesheets_data "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Gui/Stylesheets"
|
||||
${Stylesheets_Files} ${Images_Files})
|
||||
${Stylesheets_Files}
|
||||
${Images_Files}
|
||||
${Overlay_Stylesheets_Files})
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
@@ -29,6 +47,12 @@ INSTALL(
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/Stylesheets
|
||||
)
|
||||
INSTALL(
|
||||
FILES
|
||||
${Overlay_Stylesheets_Files}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/Stylesheets/overlay
|
||||
)
|
||||
INSTALL(
|
||||
FILES
|
||||
${Images_Files}
|
||||
|
||||
190
src/Gui/Stylesheets/overlay/Dark-Outline.qss
Normal file
@@ -0,0 +1,190 @@
|
||||
* {
|
||||
color: #f0f0f0;
|
||||
alternate-background-color: rgba(50,50,50,120);
|
||||
}
|
||||
|
||||
QComboBox,
|
||||
QComboBox:editable,
|
||||
QComboBox:!editable,
|
||||
QLineEdit,
|
||||
QTextEdit,
|
||||
QPlainTextEdit,
|
||||
QAbstractSpinBox,
|
||||
QDateEdit,
|
||||
QDateTimeEdit,
|
||||
Gui--PropertyEditor--PropertyEditor QLabel {
|
||||
background : #6e6e6e;
|
||||
}
|
||||
Gui--PropertyEditor--PropertyEditor {
|
||||
gridline-color: #20a0a0a0;
|
||||
}
|
||||
|
||||
QComboBox:disabled,
|
||||
QAbstractSpinBox:disabled,
|
||||
QLineEdit:disabled,
|
||||
QTextEdit:disabled,
|
||||
QPlainTextEdit:disabled,
|
||||
QTimeEdit:disabled,
|
||||
QDateEdit:disabled,
|
||||
QDateTimeEdit:disabled {
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
background-color: transparent;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
QTabBar {
|
||||
border : none;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
color: rgb(180,180,180);
|
||||
background-color: rgba(100,100,100,10);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
color: rgb(250,250,250);
|
||||
background-color: rgba(100,100,100,50);
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
color: rgb(250,250,250);
|
||||
background-color: rgba(150,150,150,150);
|
||||
}
|
||||
|
||||
/* The OverlayTabWidget is named as OverlayLeft, OverlayRight, OverlayTop, OverlayBottom.
|
||||
To customize for each overlay docking site, use the following selector
|
||||
|
||||
Gui--OverlayTabWidget#OverlayLeft {}
|
||||
*/
|
||||
|
||||
Gui--OverlayTabWidget {
|
||||
qproperty-effectColor: rgba(50, 50, 50, 200);
|
||||
qproperty-effectBlurRadius: 2.0;
|
||||
qproperty-effectOffsetX: 0.0;
|
||||
qproperty-effectOffsetY: 0.0;
|
||||
qproperty-effectWidth: 1;
|
||||
qproperty-effectHeight: 1;
|
||||
qproperty-enableEffect: 1;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::tab-bar:top,
|
||||
Gui--OverlayTabWidget::tab-bar:bottom {
|
||||
left: 10px;
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::tab-bar:left,
|
||||
Gui--OverlayTabWidget::tab-bar:right {
|
||||
top: 10px;
|
||||
alignment: top;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::pane {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QHeaderView { background:transparent }
|
||||
QHeaderView::section {
|
||||
color: rgb(200,200,200);
|
||||
background-color: rgba(50,50,50,10);
|
||||
padding: 2px;
|
||||
border: 1px solid rgb(150,150,150);
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: rgba(100,100,100,180);
|
||||
border: 1px solid darkgray;
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
Gui--OverlayProxyWidget {
|
||||
qproperty-hintColor: rgba(50, 50, 50, 0.6);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(150,150,150,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(150,150,150,155);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
QTreeView,
|
||||
QListView,
|
||||
QTableView {
|
||||
background: rgb(100,100,100);
|
||||
border: transparent;
|
||||
selection-background-color: rgba(94, 144, 250, 0.7);
|
||||
}
|
||||
|
||||
QListView::item:selected,
|
||||
QTreeView::item:selected {
|
||||
background-color: rgba(94, 144, 250, 0.7);
|
||||
}
|
||||
|
||||
Gui--PropertyEditor--PropertyEditor {
|
||||
qproperty-groupTextColor: rgb(50, 50, 50);
|
||||
qproperty-groupBackground: rgba(140, 140, 140, 0.6);
|
||||
qproperty-itemBackground: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item {
|
||||
background-color: rgba(100, 100, 100, 200);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item::selected {
|
||||
background-color: rgb(94, 144, 250);
|
||||
}
|
||||
|
||||
/* Use the following selector to customize title bar for each side */
|
||||
/*
|
||||
Gui--OverlayTabWidget#OverlayBottom Gui--OverlayTitleBar,
|
||||
Gui--OverlayTabWidget#OverlayBottom QSplitter Gui--OverlaySplitterHandle {
|
||||
background-color: qlineargradient(
|
||||
spread:pad, x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 #80202020, stop:1 #00202020);
|
||||
}
|
||||
*/
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(80, 80, 80, 150)
|
||||
}
|
||||
|
||||
QScrollArea#ClippingScrollArea,
|
||||
QWidget#ClippingScrollAreaContents {
|
||||
background-color: #808c8c8c;
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] {
|
||||
background-color: #a08c8c8c; /* Task Panel background color */
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] > QWidget {
|
||||
background-color: #808c8c8c; /* Task Panel background color */
|
||||
}
|
||||
34
src/Gui/Stylesheets/overlay/Dark-off.qss
Normal file
@@ -0,0 +1,34 @@
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(150,150,150,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(150,150,150,155);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(80, 80, 80, 150)
|
||||
}
|
||||
|
||||
158
src/Gui/Stylesheets/overlay/Dark.qss
Normal file
@@ -0,0 +1,158 @@
|
||||
* {
|
||||
color: #f0f0f0;
|
||||
alternate-background-color: rgba(50,50,50,120);
|
||||
}
|
||||
|
||||
QComboBox,
|
||||
QComboBox:editable,
|
||||
QComboBox:!editable,
|
||||
QLineEdit,
|
||||
QTextEdit,
|
||||
QPlainTextEdit,
|
||||
QAbstractSpinBox,
|
||||
QDateEdit,
|
||||
QDateTimeEdit,
|
||||
Gui--PropertyEditor--PropertyEditor QLabel {
|
||||
background : #6e6e6e;
|
||||
}
|
||||
|
||||
QComboBox:disabled,
|
||||
QAbstractSpinBox:disabled,
|
||||
QLineEdit:disabled,
|
||||
QTextEdit:disabled,
|
||||
QPlainTextEdit:disabled,
|
||||
QTimeEdit:disabled,
|
||||
QDateEdit:disabled,
|
||||
QDateTimeEdit:disabled {
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
background-color: transparent;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget {
|
||||
qproperty-enableEffect: 0;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::pane {
|
||||
background-color: rgba(100,100,100,150)
|
||||
}
|
||||
|
||||
QTabBar {
|
||||
border : none;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
color: #f0f0f0;
|
||||
background-color: rgba(100,100,100,50);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: rgba(100,100,100,150);
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
background-color: rgba(150,150,150,150);
|
||||
}
|
||||
|
||||
QHeaderView { background:transparent }
|
||||
QHeaderView::section {
|
||||
color: rgb(200,200,200);
|
||||
background-color: rgba(50,50,50,50);
|
||||
padding: 2px;
|
||||
border: 1px solid rgb(100,100,100);
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: rgba(100,100,100,180);
|
||||
border: 1px solid darkgray;
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(150,150,150,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(150,150,150,155);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset darkgray;
|
||||
}
|
||||
|
||||
QTreeView,
|
||||
QListView,
|
||||
QTableView {
|
||||
background: rgb(100,100,100);
|
||||
selection-background-color: rgba(94, 144, 250, 0.7);
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
QListView::item:selected,
|
||||
QTreeView::item:selected {
|
||||
background-color: rgba(94, 144, 250, 0.7);
|
||||
}
|
||||
|
||||
Gui--PropertyEditor--PropertyEditor {
|
||||
qproperty-groupTextColor: rgb(50, 50, 50);
|
||||
qproperty-groupBackground: rgba(140, 140, 140, 0.7);
|
||||
qproperty-itemBackground: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item {
|
||||
background-color: rgba(100, 100, 100, 200);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item::selected {
|
||||
background-color: rgb(94, 144, 250);
|
||||
}
|
||||
|
||||
/* Use the following selector to customize title bar for each side */
|
||||
/*
|
||||
Gui--OverlayTabWidget#OverlayBottom Gui--OverlayTitleBar,
|
||||
Gui--OverlayTabWidget#OverlayBottom QSplitter Gui--OverlaySplitterHandle {
|
||||
background-color: qlineargradient(
|
||||
spread:pad, x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 #80202020, stop:1 #00202020);
|
||||
}
|
||||
*/
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(80, 80, 80, 150)
|
||||
}
|
||||
|
||||
QScrollArea#ClippingScrollArea,
|
||||
QWidget#ClippingScrollAreaContents {
|
||||
background-color: #808c8c8c;
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] {
|
||||
background-color: #808c8c8c; /* Task Panel background color */
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] > QWidget {
|
||||
background-color: #808c8c8c; /* Task Panel background color */
|
||||
}
|
||||
|
||||
183
src/Gui/Stylesheets/overlay/Light-Outline.qss
Normal file
@@ -0,0 +1,183 @@
|
||||
* {
|
||||
color: #202020;
|
||||
alternate-background-color: rgba(250,250,250,120);
|
||||
}
|
||||
|
||||
QComboBox,
|
||||
QComboBox:editable,
|
||||
QComboBox:!editable,
|
||||
QLineEdit,
|
||||
QTextEdit,
|
||||
QPlainTextEdit,
|
||||
QAbstractSpinBox,
|
||||
QDateEdit,
|
||||
QDateTimeEdit,
|
||||
Gui--PropertyEditor--PropertyEditor QLabel {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
QComboBox:disabled,
|
||||
QAbstractSpinBox:disabled,
|
||||
QLineEdit:disabled,
|
||||
QTextEdit:disabled,
|
||||
QPlainTextEdit:disabled,
|
||||
QTimeEdit:disabled,
|
||||
QDateEdit:disabled,
|
||||
QDateTimeEdit:disabled {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
background-color: transparent;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
QTabBar {
|
||||
border : none;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
color: #202020;
|
||||
background-color: rgba(100,100,100,50);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: rgba(250,250,250,80);
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
background-color: rgba(250,250,250,200);
|
||||
}
|
||||
|
||||
/* The OverlayTabWidget is named as OverlayLeft, OverlayRight, OverlayTop, OverlayBottom.
|
||||
To customize for each overlay docking site, use the following selector
|
||||
|
||||
Gui--OverlayTabWidget#OverlayLeft {}
|
||||
*/
|
||||
|
||||
Gui--OverlayTabWidget {
|
||||
qproperty-effectColor: rgba(200, 200, 200, 100);
|
||||
qproperty-effectBlurRadius: 2.0;
|
||||
qproperty-effectOffsetX: 0.0;
|
||||
qproperty-effectOffsetY: 0.0;
|
||||
qproperty-effectWidth: 1;
|
||||
qproperty-effectHeight: 1;
|
||||
qproperty-enableEffect: 1;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::pane {
|
||||
background-color: transparent
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::tab-bar:top,
|
||||
Gui--OverlayTabWidget::tab-bar:bottom {
|
||||
left: 10px;
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::tab-bar:left,
|
||||
Gui--OverlayTabWidget::tab-bar:right {
|
||||
top: 10px;
|
||||
alignment: top;
|
||||
}
|
||||
|
||||
QHeaderView { background:transparent }
|
||||
QHeaderView::section {
|
||||
color: rgb(80, 80, 80);
|
||||
background-color: rgba(128,128,128,50);
|
||||
border: 1px solid rgb(100,100,100);
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: rgba(250,250,250,180);
|
||||
border: 1px solid rgb(80,80,80);
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
Gui--OverlayProxyWidget {
|
||||
qproperty-hintColor: rgba(250, 250, 250, 0.6);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(250,250,250,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(250,250,250,255);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed,
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(150,150,150,80);
|
||||
border: 1px inset #f5f5f5;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset #f5f5f5;
|
||||
}
|
||||
|
||||
QTreeView,
|
||||
QListView,
|
||||
QTableView {
|
||||
background: rgb(250,250,250);
|
||||
selection-background-color: rgba(94, 144, 250, 0.7);
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
QListView::item:selected,
|
||||
QTreeView::item:selected {
|
||||
background-color: rgba(94, 144, 250, 0.7);
|
||||
}
|
||||
|
||||
/* Property Editor QTreeView (FreeCAD custom widget) */
|
||||
Gui--PropertyEditor--PropertyEditor {
|
||||
gridline-color: #20d2d2de;
|
||||
qproperty-groupTextColor: rgb(100, 100, 100);
|
||||
qproperty-groupBackground: rgba(180, 180, 180, 0.7);
|
||||
qproperty-itemBackground: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item {
|
||||
background-color: rgba(200, 200, 200, 200);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item::selected {
|
||||
background-color: rgba(94, 144, 250);
|
||||
}
|
||||
|
||||
/* Use the following selector to customize title bar for each side */
|
||||
/*
|
||||
Gui--OverlayTabWidget#OverlayBottom Gui--OverlayTitleBar,
|
||||
Gui--OverlayTabWidget#OverlayBottom QSplitter Gui--OverlaySplitterHandle {
|
||||
background-color: qlineargradient(
|
||||
spread:pad, x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 #80202020, stop:1 #00202020);
|
||||
}
|
||||
*/
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(200, 200, 200, 150)
|
||||
}
|
||||
|
||||
QScrollArea#ClippingScrollArea,
|
||||
QWidget#ClippingScrollAreaContents {
|
||||
background-color: #80e6e6e6;
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] {
|
||||
background-color: #a0e6e6e6; /* Task Panel background color */
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] > QWidget {
|
||||
background-color: #80e6e6e6; /* Task Panel background color */
|
||||
}
|
||||
33
src/Gui/Stylesheets/overlay/Light-off.qss
Normal file
@@ -0,0 +1,33 @@
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(150,150,150,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(150,150,150,155);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(50,50,50,80);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset palette(dark);
|
||||
}
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(200, 200, 200, 150)
|
||||
}
|
||||
155
src/Gui/Stylesheets/overlay/Light.qss
Normal file
@@ -0,0 +1,155 @@
|
||||
* {
|
||||
color: #202020;
|
||||
alternate-background-color: rgba(250,250,250,120);
|
||||
}
|
||||
|
||||
QComboBox,
|
||||
QComboBox:editable,
|
||||
QComboBox:!editable,
|
||||
QLineEdit,
|
||||
QTextEdit,
|
||||
QPlainTextEdit,
|
||||
QAbstractSpinBox,
|
||||
QDateEdit,
|
||||
QDateTimeEdit,
|
||||
Gui--PropertyEditor--PropertyEditor QLabel {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
QComboBox:disabled,
|
||||
QAbstractSpinBox:disabled,
|
||||
QLineEdit:disabled,
|
||||
QTextEdit:disabled,
|
||||
QPlainTextEdit:disabled,
|
||||
QTimeEdit:disabled,
|
||||
QDateEdit:disabled,
|
||||
QDateTimeEdit:disabled {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
background-color: transparent;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget {
|
||||
qproperty-enableEffect: 0;
|
||||
}
|
||||
|
||||
Gui--OverlayTabWidget::pane {
|
||||
background-color: rgba(255,255,255,80)
|
||||
}
|
||||
|
||||
QTabBar {
|
||||
border : none;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
color: #202020;
|
||||
background-color: rgba(100,100,100,50);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: rgba(250,250,250,80);
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
background-color: rgba(250,250,250,200);
|
||||
}
|
||||
|
||||
QHeaderView { background:transparent }
|
||||
QHeaderView::section {
|
||||
color: rgb(80, 80, 80);
|
||||
background-color: rgba(128,128,128,50);
|
||||
border: 1px solid darkgray;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: rgba(250,250,250,180);
|
||||
border: 1px solid rgb(80,80,80);
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton {
|
||||
background: transparent;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::hover {
|
||||
background: rgba(250,250,250,200);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::focus {
|
||||
background: rgba(250,250,250,255);
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::pressed,
|
||||
Gui--OverlayToolButton::checked {
|
||||
background: rgba(150,150,150,80);
|
||||
border: 1px inset #f5f5f5;
|
||||
}
|
||||
|
||||
Gui--OverlayToolButton::checked:hover {
|
||||
background: rgba(150,150,150,200);
|
||||
border: 1px inset #f5f5f5;
|
||||
}
|
||||
|
||||
QTreeView,
|
||||
QListView,
|
||||
QTableView {
|
||||
background: rgb(250,250,250);
|
||||
selection-background-color: rgba(94, 144, 250, 0.7);
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
QListView::item:selected,
|
||||
QTreeView::item:selected {
|
||||
background-color: rgba(94, 144, 250, 0.7);
|
||||
}
|
||||
|
||||
/* Property Editor QTreeView (FreeCAD custom widget) */
|
||||
Gui--PropertyEditor--PropertyEditor {
|
||||
/* gridline-color: #6e6e6e; */
|
||||
qproperty-groupTextColor: rgb(100, 100, 100);
|
||||
qproperty-groupBackground: rgba(180, 180, 180, 0.7);
|
||||
qproperty-itemBackground: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item {
|
||||
background-color: rgba(200, 200, 200, 200);
|
||||
}
|
||||
|
||||
Gui--CallTipsList::item::selected {
|
||||
background-color: rgba(94, 144, 250);
|
||||
}
|
||||
|
||||
/* Use the following selector to customize title bar for each side */
|
||||
/*
|
||||
Gui--OverlayTabWidget#OverlayBottom Gui--OverlayTitleBar,
|
||||
Gui--OverlayTabWidget#OverlayBottom QSplitter Gui--OverlaySplitterHandle {
|
||||
background-color: qlineargradient(
|
||||
spread:pad, x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 #80202020, stop:1 #00202020);
|
||||
}
|
||||
*/
|
||||
|
||||
Gui--OverlayTitleBar,
|
||||
Gui--OverlaySplitterHandle {
|
||||
background-color: rgba(200, 200, 200, 150)
|
||||
}
|
||||
|
||||
QScrollArea#ClippingScrollArea,
|
||||
QWidget#ClippingScrollAreaContents {
|
||||
background-color: #80e6e6e6
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] {
|
||||
background-color: #80e6e6e6; /* Task Panel background color */
|
||||
}
|
||||
|
||||
QSint--ActionGroup QFrame[class="content"] > QWidget {
|
||||
background-color: #80e6e6e6; /* Task Panel background color */
|
||||
}
|
||||
86
src/Gui/Stylesheets/overlay/autohide.svg
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="12"
|
||||
height="12"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
viewBox="0 0 12 12"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="autohide.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1301"
|
||||
inkscape:window-height="744"
|
||||
id="namedview8"
|
||||
showgrid="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="4.6041743"
|
||||
inkscape:cy="2.6400142"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136"
|
||||
spacingx="0.5"
|
||||
spacingy="0.5"
|
||||
empspacing="2"
|
||||
units="px" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Pablo Gil</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>SVG</rdf:li>
|
||||
<rdf:li>template</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
id="path5607"
|
||||
d="m 5,1.5 5.501761,0.00796 L 10.5,10.5 5,10.5"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
id="path5609"
|
||||
d="m 8.5,6 -5,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
id="path5611"
|
||||
d="m 4.4999599,4 -3,2 3,2"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.50196078" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
47
src/Gui/Stylesheets/overlay/close.svg
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
44
src/Gui/Stylesheets/overlay/edithide.svg
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
69
src/Gui/Stylesheets/overlay/editshow.svg
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
53
src/Gui/Stylesheets/overlay/float.svg
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 12 12"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
height="12"
|
||||
width="12">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Pablo Gil</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>SVG</rdf:li>
|
||||
<rdf:li>template</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-1074.0663,-344.59799)"
|
||||
id="layer1">
|
||||
<rect
|
||||
y="349.09799"
|
||||
x="1075.5664"
|
||||
height="6.0000062"
|
||||
width="6.0000587"
|
||||
id="rect4200"
|
||||
style="opacity:1;fill:none;fill-opacity:0.50196078;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078" />
|
||||
<path
|
||||
id="rect4200-1"
|
||||
d="m 1078.5663,348.09799 0,-2 6,0 0,6 -2,0"
|
||||
style="opacity:1;fill:none;fill-opacity:0.50196078;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
430
src/Gui/Stylesheets/overlay/mode.svg
Normal file
|
After Width: | Height: | Size: 20 KiB |
82
src/Gui/Stylesheets/overlay/overlay.svg
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="12"
|
||||
height="12"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
viewBox="0 0 12 12"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="overlay.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1301"
|
||||
inkscape:window-height="744"
|
||||
id="namedview7252"
|
||||
showgrid="true"
|
||||
inkscape:zoom="39.333334"
|
||||
inkscape:cx="5.677245"
|
||||
inkscape:cy="7.37444"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid7794"
|
||||
units="px"
|
||||
spacingx="0.5"
|
||||
spacingy="0.5"
|
||||
originx="0"
|
||||
originy="0"
|
||||
empspacing="2" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Pablo Gil</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>SVG</rdf:li>
|
||||
<rdf:li>template</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="opacity:1;fill:none;fill-opacity:0.50196078;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078"
|
||||
d="m 1.5000553,1.4999919 8.9999447,0 0,9.0000081 -8.9999447,0 z"
|
||||
id="rect4200" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4207"
|
||||
d="m 2,4.5 8,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
89
src/Gui/Stylesheets/overlay/taskshow.svg
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg6528"
|
||||
height="12"
|
||||
width="12"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="taskshow.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1301"
|
||||
inkscape:window-height="744"
|
||||
id="namedview4692"
|
||||
showgrid="true"
|
||||
inkscape:zoom="11.313709"
|
||||
inkscape:cx="-3.3929586"
|
||||
inkscape:cy="-3.0838742"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6528">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5234"
|
||||
units="px"
|
||||
spacingx="0.5"
|
||||
spacingy="0.5"
|
||||
empspacing="2" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata6538">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs6536" />
|
||||
<path
|
||||
id="path7086"
|
||||
d="M 3,2 1.5,2 1.4996684,10.5 10.5,10.5 10.5,2 9,2"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078"
|
||||
id="rect4137"
|
||||
width="5"
|
||||
height="2"
|
||||
x="3.5"
|
||||
y="0.5" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
d="m 3,4.5 6,0"
|
||||
id="path4139"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
d="m 3,6.5 6,0"
|
||||
id="path4139-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50196078"
|
||||
d="m 3,8.5 6,0"
|
||||
id="path4139-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
52
src/Gui/Stylesheets/overlay/transparent.svg
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12"
|
||||
height="12"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
viewBox="0 0 12 12">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Pablo Gil</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>SVG</rdf:li>
|
||||
<rdf:li>template</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<ellipse
|
||||
ry="2.2648306"
|
||||
rx="2.2341104"
|
||||
cy="6"
|
||||
cx="6"
|
||||
id="path5584"
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.50196078;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078" />
|
||||
<ellipse
|
||||
ry="3.7245762"
|
||||
rx="4.7838984"
|
||||
cy="6"
|
||||
cx="6"
|
||||
id="path5586"
|
||||
style="opacity:1;fill:none;fill-opacity:0.50196078;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:63;stroke-opacity:0.50196078" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -41,6 +41,7 @@
|
||||
#include "TaskView.h"
|
||||
#include "TaskDialog.h"
|
||||
#include "TaskEditControl.h"
|
||||
#include <Gui/Control.h>
|
||||
|
||||
#include <Gui/QSint/actionpanel/taskgroup_p.h>
|
||||
#include <Gui/QSint/actionpanel/taskheader_p.h>
|
||||
@@ -299,6 +300,11 @@ TaskView::TaskView(QWidget *parent)
|
||||
App::GetApplication().signalRedoDocument.connect
|
||||
(std::bind(&Gui::TaskView::TaskView::slotRedoDocument, this, sp::_1));
|
||||
//NOLINTEND
|
||||
|
||||
this->timer = new QTimer(this);
|
||||
this->timer->setSingleShot(true);
|
||||
QObject::connect(this->timer, &QTimer::timeout, [this](){onUpdateWatcher();});
|
||||
updateWatcher();
|
||||
}
|
||||
|
||||
TaskView::~TaskView()
|
||||
@@ -310,6 +316,20 @@ TaskView::~TaskView()
|
||||
Gui::Selection().Detach(this);
|
||||
}
|
||||
|
||||
bool TaskView::isEmpty(bool includeWatcher) const
|
||||
{
|
||||
if (ActiveCtrl || ActiveDialog)
|
||||
return false;
|
||||
|
||||
if (includeWatcher) {
|
||||
for (auto * watcher : ActiveWatcher) {
|
||||
if (watcher->shouldShow())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskView::event(QEvent* event)
|
||||
{
|
||||
// Workaround for a limitation in Qt (#0003794)
|
||||
@@ -542,7 +562,10 @@ void TaskView::showDialog(TaskDialog *dlg)
|
||||
ActiveDialog->open();
|
||||
|
||||
getMainWindow()->updateActions();
|
||||
|
||||
triggerMinimumSizeHint();
|
||||
|
||||
Q_EMIT taskUpdate();
|
||||
}
|
||||
|
||||
void TaskView::removeDialog()
|
||||
@@ -585,8 +608,23 @@ void TaskView::removeDialog()
|
||||
triggerMinimumSizeHint();
|
||||
}
|
||||
|
||||
void TaskView::updateWatcher()
|
||||
void TaskView::updateWatcher(void)
|
||||
{
|
||||
this->timer->start(200);
|
||||
}
|
||||
|
||||
void TaskView::onUpdateWatcher(void)
|
||||
{
|
||||
if (ActiveCtrl || ActiveDialog)
|
||||
return;
|
||||
|
||||
if (ActiveWatcher.empty()) {
|
||||
auto panel = Gui::Control().taskPanel();
|
||||
if (panel && panel->ActiveWatcher.size())
|
||||
takeTaskWatcher(panel);
|
||||
}
|
||||
this->timer->stop();
|
||||
|
||||
// In case a child of the TaskView has the focus and get hidden we have
|
||||
// to make sure to set the focus on a widget that won't be hidden or
|
||||
// deleted because otherwise Qt may forward the focus via focusNextPrevChild()
|
||||
@@ -622,6 +660,8 @@ void TaskView::updateWatcher()
|
||||
fwp->setFocus();
|
||||
|
||||
triggerMinimumSizeHint();
|
||||
|
||||
Q_EMIT taskUpdate();
|
||||
}
|
||||
|
||||
void TaskView::addTaskWatcher(const std::vector<TaskWatcher*> &Watcher)
|
||||
@@ -631,7 +671,17 @@ void TaskView::addTaskWatcher(const std::vector<TaskWatcher*> &Watcher)
|
||||
delete tw;
|
||||
|
||||
ActiveWatcher = Watcher;
|
||||
addTaskWatcher();
|
||||
if (!ActiveCtrl && !ActiveDialog)
|
||||
addTaskWatcher();
|
||||
}
|
||||
|
||||
void TaskView::takeTaskWatcher(TaskView *other)
|
||||
{
|
||||
clearTaskWatcher();
|
||||
ActiveWatcher.swap(other->ActiveWatcher);
|
||||
other->clearTaskWatcher();
|
||||
if (isEmpty(false))
|
||||
addTaskWatcher();
|
||||
}
|
||||
|
||||
void TaskView::clearTaskWatcher()
|
||||
|
||||
@@ -154,17 +154,24 @@ public:
|
||||
|
||||
void addTaskWatcher(const std::vector<TaskWatcher*> &Watcher);
|
||||
void clearTaskWatcher();
|
||||
void takeTaskWatcher(TaskView *other);
|
||||
|
||||
bool isEmpty(bool includeWatcher = true) const;
|
||||
|
||||
void clearActionStyle();
|
||||
void restoreActionStyle();
|
||||
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void taskUpdate();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void accept();
|
||||
void reject();
|
||||
void helpRequested();
|
||||
void clicked (QAbstractButton * button);
|
||||
void onUpdateWatcher();
|
||||
|
||||
private:
|
||||
void triggerMinimumSizeHint();
|
||||
@@ -193,6 +200,7 @@ protected:
|
||||
QSint::ActionPanel* taskPanel;
|
||||
TaskDialog *ActiveDialog;
|
||||
TaskEditControl *ActiveCtrl;
|
||||
QTimer *timer;
|
||||
|
||||
Connection connectApplicationActiveDocument;
|
||||
Connection connectApplicationDeleteDocument;
|
||||
|
||||
168
src/Gui/Tree.cpp
@@ -32,6 +32,7 @@
|
||||
# include <QHeaderView>
|
||||
# include <QMenu>
|
||||
# include <QMessageBox>
|
||||
# include <QPainter>
|
||||
# include <QPixmap>
|
||||
# include <QThread>
|
||||
# include <QTimer>
|
||||
@@ -89,6 +90,7 @@ std::set<TreeWidget*> TreeWidget::Instances;
|
||||
static TreeWidget* _LastSelectedTreeWidget;
|
||||
const int TreeWidget::DocumentType = 1000;
|
||||
const int TreeWidget::ObjectType = 1001;
|
||||
static bool _DraggingActive;
|
||||
static bool _DragEventFilter;
|
||||
|
||||
void TreeParams::onItemBackgroundChanged()
|
||||
@@ -355,13 +357,95 @@ public:
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TreeWidgetEditDelegate::TreeWidgetEditDelegate(QObject* parent)
|
||||
namespace Gui {
|
||||
/**
|
||||
* TreeWidget item delegate for editing
|
||||
*/
|
||||
class TreeWidgetItemDelegate: public QStyledItemDelegate {
|
||||
typedef QStyledItemDelegate inherited;
|
||||
public:
|
||||
TreeWidgetItemDelegate(QObject* parent=0);
|
||||
|
||||
virtual QWidget* createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &, const QModelIndex &index) const;
|
||||
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const;
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
TreeWidgetItemDelegate::TreeWidgetItemDelegate(QObject* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget* TreeWidgetEditDelegate::createEditor(
|
||||
QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
|
||||
void TreeWidgetItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
TreeWidget * tree = static_cast<TreeWidget*>(parent());
|
||||
auto style = tree->style();
|
||||
|
||||
// If the second column is not shown, we'll trim the color background when
|
||||
// rendering as transparent overlay.
|
||||
bool trimBG = TreeParams::getHideColumn();
|
||||
QRect rect = opt.rect;
|
||||
|
||||
if (index.column() == 0) {
|
||||
if (tree->testAttribute(Qt::WA_NoSystemBackground)
|
||||
&& (trimBG || (opt.backgroundBrush.style() == Qt::NoBrush
|
||||
&& _TreeItemBackground.style() != Qt::NoBrush)))
|
||||
{
|
||||
const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, tree) + 1;
|
||||
// 2 margin for text, 2 margin for decoration (icon)
|
||||
int width = 4*margin + opt.fontMetrics.boundingRect(opt.text).width()
|
||||
+ opt.decorationSize.width() + TreeParams::getItemBackgroundPadding();
|
||||
if (TreeParams::getCheckBoxesSelection()) {
|
||||
// another 2 margin for checkbox
|
||||
width += 2*margin + style->pixelMetric(QStyle::PM_IndicatorWidth)
|
||||
+ style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
if (width < rect.width())
|
||||
rect.setWidth(width);
|
||||
if (trimBG) {
|
||||
rect.setWidth(rect.width() + 5);
|
||||
opt.rect = rect;
|
||||
if (opt.backgroundBrush.style() == Qt::NoBrush)
|
||||
painter->fillRect(rect, _TreeItemBackground);
|
||||
} else if (!opt.state.testFlag(QStyle::State_Selected))
|
||||
painter->fillRect(rect, _TreeItemBackground);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, tree);
|
||||
}
|
||||
|
||||
void TreeWidgetItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
inherited::initStyleOption(option, index);
|
||||
|
||||
TreeWidget * tree = static_cast<TreeWidget*>(parent());
|
||||
QTreeWidgetItem * item = tree->itemFromIndex(index);
|
||||
if (!item || item->type() != TreeWidget::ObjectType)
|
||||
return;
|
||||
|
||||
QSize size;
|
||||
size = option->icon.actualSize(QSize(0xffff, 0xffff));
|
||||
if (size.height())
|
||||
option->decorationSize = QSize(size.width()*TreeWidget::iconSize()/size.height(),
|
||||
TreeWidget::iconSize());
|
||||
}
|
||||
|
||||
QWidget* TreeWidgetItemDelegate::createEditor(
|
||||
QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
|
||||
{
|
||||
auto ti = static_cast<QTreeWidgetItem*>(index.internalPointer());
|
||||
if (ti->type() != TreeWidget::ObjectType || index.column() > 1)
|
||||
@@ -375,14 +459,27 @@ QWidget* TreeWidgetEditDelegate::createEditor(
|
||||
App::GetApplication().setActiveTransaction(str.str().c_str());
|
||||
FC_LOG("create editor transaction " << App::GetApplication().getActiveTransaction());
|
||||
|
||||
auto le = new ExpLineEdit(parent);
|
||||
le->setFrame(false);
|
||||
le->setReadOnly(prop.isReadOnly());
|
||||
le->bind(App::ObjectIdentifier(prop));
|
||||
le->setAutoApply(true);
|
||||
return le;
|
||||
QLineEdit *editor;
|
||||
if(TreeParams::getLabelExpression()) {
|
||||
ExpLineEdit *le = new ExpLineEdit(parent);
|
||||
le->setAutoApply(true);
|
||||
le->setFrame(false);
|
||||
le->bind(App::ObjectIdentifier(prop));
|
||||
editor = le;
|
||||
} else {
|
||||
editor = new QLineEdit(parent);
|
||||
}
|
||||
editor->setReadOnly(prop.isReadOnly());
|
||||
return editor;
|
||||
}
|
||||
|
||||
QSize TreeWidgetItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
int spacing = std::max(0, static_cast<int>(TreeParams::getItemSpacing()));
|
||||
size.setHeight(size.height() + spacing);
|
||||
return size;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TreeWidget::TreeWidget(const char* name, QWidget* parent)
|
||||
@@ -404,7 +501,7 @@ TreeWidget::TreeWidget(const char* name, QWidget* parent)
|
||||
this->setDropIndicatorShown(false);
|
||||
this->setDragDropMode(QTreeWidget::InternalMove);
|
||||
this->setColumnCount(2);
|
||||
this->setItemDelegate(new TreeWidgetEditDelegate(this));
|
||||
this->setItemDelegate(new TreeWidgetItemDelegate(this));
|
||||
|
||||
this->showHiddenAction = new QAction(this);
|
||||
this->showHiddenAction->setCheckable(true);
|
||||
@@ -1170,6 +1267,47 @@ void TreeWidget::selectAllInstances(const ViewProviderDocumentObject& vpd) {
|
||||
v.second->selectAllInstances(vpd);
|
||||
}
|
||||
|
||||
static int &treeIconSize()
|
||||
{
|
||||
static int _treeIconSize = -1;
|
||||
|
||||
if (_treeIconSize < 0)
|
||||
_treeIconSize = TreeParams::getIconSize();
|
||||
return _treeIconSize;
|
||||
}
|
||||
|
||||
int TreeWidget::iconHeight() const
|
||||
{
|
||||
return treeIconSize();
|
||||
}
|
||||
|
||||
void TreeWidget::setIconHeight(int height)
|
||||
{
|
||||
if (treeIconSize() == height)
|
||||
return;
|
||||
|
||||
treeIconSize() = height;
|
||||
if (treeIconSize() <= 0)
|
||||
treeIconSize() = std::max(10, iconSize());
|
||||
|
||||
for(auto tree : Instances)
|
||||
tree->setIconSize(QSize(treeIconSize(), treeIconSize()));
|
||||
}
|
||||
|
||||
int TreeWidget::iconSize() {
|
||||
static int defaultSize;
|
||||
if (defaultSize == 0) {
|
||||
auto tree = instance();
|
||||
if(tree)
|
||||
defaultSize = tree->viewOptions().decorationSize.width();
|
||||
else
|
||||
defaultSize = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
|
||||
}
|
||||
if (treeIconSize() > 0)
|
||||
return std::max(10, treeIconSize());
|
||||
return defaultSize;
|
||||
}
|
||||
|
||||
TreeWidget* TreeWidget::instance() {
|
||||
auto res = _LastSelectedTreeWidget;
|
||||
if (res && res->isVisible())
|
||||
@@ -1336,6 +1474,15 @@ bool TreeWidget::eventFilter(QObject*, QEvent* ev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace Gui {
|
||||
|
||||
bool isTreeViewDragging()
|
||||
{
|
||||
return _DraggingActive;
|
||||
}
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
void TreeWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->matches(QKeySequence::Find)) {
|
||||
@@ -1477,6 +1624,7 @@ void TreeWidget::startDragging() {
|
||||
|
||||
void TreeWidget::startDrag(Qt::DropActions supportedActions)
|
||||
{
|
||||
Base::StateLocker guard(_DraggingActive);
|
||||
QTreeWidget::startDrag(supportedActions);
|
||||
if (_DragEventFilter) {
|
||||
_DragEventFilter = false;
|
||||
|
||||
@@ -46,9 +46,12 @@ class ViewProviderDocumentObject;
|
||||
class DocumentObjectItem;
|
||||
class DocumentObjectData;
|
||||
using DocumentObjectDataPtr = std::shared_ptr<DocumentObjectData>;
|
||||
class TreeWidgetItemDelegate;
|
||||
|
||||
class DocumentItem;
|
||||
|
||||
GuiExport bool isTreeViewDragging();
|
||||
|
||||
/** Tree view that allows drag & drop of document objects.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
@@ -66,6 +69,13 @@ public:
|
||||
void selectLinkedObject(App::DocumentObject *linked);
|
||||
void selectAllLinks(App::DocumentObject *obj);
|
||||
void expandSelectedItems(TreeItemMode mode);
|
||||
static int iconSize();
|
||||
|
||||
int iconHeight() const;
|
||||
void setIconHeight(int height);
|
||||
|
||||
int itemSpacing() const;
|
||||
void setItemSpacing(int);
|
||||
|
||||
bool eventFilter(QObject *, QEvent *ev) override;
|
||||
|
||||
@@ -241,6 +251,7 @@ private:
|
||||
friend class DocumentItem;
|
||||
friend class DocumentObjectItem;
|
||||
friend class TreeParams;
|
||||
friend class TreeWidgetItemDelegate;
|
||||
|
||||
using Connection = boost::signals2::connection;
|
||||
Connection connectNewDocument;
|
||||
@@ -480,19 +491,6 @@ public:
|
||||
~TreeDockWidget() override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TreeWidget item delegate for editing
|
||||
*/
|
||||
class TreeWidgetEditDelegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TreeWidgetEditDelegate(QObject* parent=nullptr);
|
||||
QWidget* createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &, const QModelIndex &index) const override;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // GUI_TREE_H
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
funcs["ItemSpacing"] = &TreeParamsP::updateItemSpacing;
|
||||
ItemBackground = handle->GetUnsigned("ItemBackground", 0x00000000);
|
||||
funcs["ItemBackground"] = &TreeParamsP::updateItemBackground;
|
||||
ItemBackgroundPadding = handle->GetInt("ItemBackgroundPadding", 10);
|
||||
ItemBackgroundPadding = handle->GetInt("ItemBackgroundPadding", 0);
|
||||
funcs["ItemBackgroundPadding"] = &TreeParamsP::updateItemBackgroundPadding;
|
||||
HideColumn = handle->GetBool("HideColumn", true);
|
||||
funcs["HideColumn"] = &TreeParamsP::updateHideColumn;
|
||||
@@ -347,7 +347,7 @@ public:
|
||||
}
|
||||
// Auto generated code (Tools/params_utils.py:244)
|
||||
static void updateItemBackgroundPadding(TreeParamsP *self) {
|
||||
auto v = self->handle->GetInt("ItemBackgroundPadding", 10);
|
||||
auto v = self->handle->GetInt("ItemBackgroundPadding", 0);
|
||||
if (self->ItemBackgroundPadding != v) {
|
||||
self->ItemBackgroundPadding = v;
|
||||
TreeParams::onItemBackgroundPaddingChanged();
|
||||
@@ -1174,7 +1174,7 @@ const long & TreeParams::getItemBackgroundPadding() {
|
||||
|
||||
// Auto generated code (Tools/params_utils.py:300)
|
||||
const long & TreeParams::defaultItemBackgroundPadding() {
|
||||
const static long def = 10;
|
||||
const static long def = 0;
|
||||
return def;
|
||||
}
|
||||
|
||||
@@ -1403,10 +1403,9 @@ void TreeParams::onResizableColumnChanged() {
|
||||
}
|
||||
|
||||
void TreeParams::onIconSizeChanged() {
|
||||
// auto tree = TreeWidget::instance();
|
||||
// Commented out temporarily while merging PR #7888
|
||||
//if (tree)
|
||||
//tree->setIconHeight(TreeParams::getIconSize());
|
||||
auto tree = TreeWidget::instance();
|
||||
if (tree)
|
||||
tree->setIconHeight(TreeParams::getIconSize());
|
||||
}
|
||||
|
||||
void TreeParams::onFontSizeChanged() {
|
||||
|
||||
@@ -66,8 +66,8 @@ Params = [
|
||||
ParamInt('FontSize', 0, on_change=True),
|
||||
ParamInt('ItemSpacing', 0, on_change=True),
|
||||
ParamHex('ItemBackground', 0, on_change=True, title='Item background color', proxy=ParamColor(),
|
||||
doc = "Tree view item background. Only effective in overlay."),
|
||||
ParamInt('ItemBackgroundPadding', 10, on_change=True, title="Item background padding", proxy=ParamSpinBox(0, 100, 1),
|
||||
doc = "Tree view item background. Only effecitve in overlay."),
|
||||
ParamInt('ItemBackgroundPadding', 0, on_change=True, title="Item background padding", proxy=ParamSpinBox(0, 100, 1),
|
||||
doc = "Tree view item background padding."),
|
||||
ParamBool('HideColumn', True, on_change=True, title="Hide extra column",
|
||||
doc = "Hide extra tree view column for item description."),
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
# include <QToolTip>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Interpreter.h>
|
||||
@@ -1164,11 +1165,17 @@ void ToolTip::showText(const QPoint & pos, const QString & text, QWidget * w)
|
||||
tip->displayTime.start();
|
||||
}
|
||||
else {
|
||||
// do immediately
|
||||
QToolTip::showText(pos, text, w);
|
||||
hideText();
|
||||
}
|
||||
}
|
||||
|
||||
void ToolTip::hideText()
|
||||
{
|
||||
instance()->tooltipTimer.stop();
|
||||
instance()->hidden = true;
|
||||
QToolTip::hideText();
|
||||
}
|
||||
|
||||
void ToolTip::timerEvent(QTimerEvent *e)
|
||||
{
|
||||
if (e->timerId() == tooltipTimer.timerId()) {
|
||||
@@ -1180,25 +1187,45 @@ void ToolTip::timerEvent(QTimerEvent *e)
|
||||
|
||||
bool ToolTip::eventFilter(QObject* o, QEvent*e)
|
||||
{
|
||||
// This is a trick to circumvent that the tooltip gets hidden immediately
|
||||
// after it gets visible. We just filter out all timer events to keep the
|
||||
// label visible.
|
||||
if (o->inherits("QLabel")) {
|
||||
auto label = qobject_cast<QLabel*>(o);
|
||||
// Ignore the timer events to prevent from being closed
|
||||
if (label->windowFlags() & Qt::ToolTip) {
|
||||
if (e->type() == QEvent::Show) {
|
||||
this->hidden = false;
|
||||
}
|
||||
else if (e->type() == QEvent::Hide) {
|
||||
removeEventFilter();
|
||||
this->hidden = true;
|
||||
}
|
||||
else if (e->type() == QEvent::Timer &&
|
||||
!this->hidden && displayTime.elapsed() < 5000) {
|
||||
return true;
|
||||
if (!o->isWidgetType())
|
||||
return false;
|
||||
switch(e->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
hideText();
|
||||
break;
|
||||
case QEvent::KeyPress:
|
||||
if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape)
|
||||
hideText();
|
||||
break;
|
||||
case QEvent::Leave:
|
||||
hideText();
|
||||
break;
|
||||
case QEvent::Timer:
|
||||
case QEvent::Show:
|
||||
case QEvent::Hide:
|
||||
if (auto label = qobject_cast<QLabel*>(o)) {
|
||||
if (label->objectName() == QStringLiteral("qtooltip_label")) {
|
||||
// This is a trick to circumvent that the tooltip gets hidden immediately
|
||||
// after it gets visible. We just filter out all timer events to keep the
|
||||
// label visible.
|
||||
|
||||
// Ignore the timer events to prevent from being closed
|
||||
if (e->type() == QEvent::Show) {
|
||||
this->hidden = false;
|
||||
}
|
||||
else if (e->type() == QEvent::Hide) {
|
||||
// removeEventFilter();
|
||||
this->hidden = true;
|
||||
}
|
||||
else if (e->type() == QEvent::Timer &&
|
||||
!this->hidden && displayTime.elapsed() < 5000) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -449,6 +449,7 @@ class GuiExport ToolTip : public QObject
|
||||
{
|
||||
public:
|
||||
static void showText(const QPoint & pos, const QString & text, QWidget * w = nullptr);
|
||||
static void hideText();
|
||||
|
||||
protected:
|
||||
static ToolTip* instance();
|
||||
|
||||
@@ -699,7 +699,7 @@ MenuItem* StdWorkbench::setupMenuBar() const
|
||||
<< "Separator" << visu
|
||||
<< "Std_ToggleNavigation"
|
||||
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
||||
<< "Std_Workbench" << "Std_ToolBarMenu" << "Std_DockViewMenu" << "Separator"
|
||||
<< "Std_Workbench" << "Std_ToolBarMenu" << "Std_DockViewMenu" << "Std_DockOverlay" << "Separator"
|
||||
<< "Std_LinkSelectActions"
|
||||
<< "Std_TreeViewActions"
|
||||
<< "Std_ViewStatusBar";
|
||||
|
||||
@@ -83,6 +83,8 @@ PropertyEditor::PropertyEditor(QWidget *parent)
|
||||
this->background = opt.palette.dark();
|
||||
this->groupColor = opt.palette.color(QPalette::BrightText);
|
||||
|
||||
this->_itemBackground.setColor(QColor(0,0,0,0));
|
||||
|
||||
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
connect(this, &QTreeView::activated, this, &PropertyEditor::onItemActivated);
|
||||
@@ -154,6 +156,16 @@ void PropertyEditor::setGroupTextColor(const QColor& c)
|
||||
this->groupColor = c;
|
||||
}
|
||||
|
||||
QBrush PropertyEditor::itemBackground() const
|
||||
{
|
||||
return this->_itemBackground;
|
||||
}
|
||||
|
||||
void PropertyEditor::setItemBackground(const QBrush& c)
|
||||
{
|
||||
this->_itemBackground = c;
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
QStyleOptionViewItem PropertyEditor::viewOptions() const
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ class PropertyEditor : public QTreeView
|
||||
|
||||
Q_PROPERTY(QBrush groupBackground READ groupBackground WRITE setGroupBackground DESIGNABLE true SCRIPTABLE true) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(QColor groupTextColor READ groupTextColor WRITE setGroupTextColor DESIGNABLE true SCRIPTABLE true) // clazy:exclude=qproperty-without-notify
|
||||
Q_PROPERTY(QBrush itemBackground READ itemBackground WRITE setItemBackground DESIGNABLE true SCRIPTABLE true) // clazy:exclude=qproperty-without-notify
|
||||
|
||||
public:
|
||||
PropertyEditor(QWidget *parent = nullptr);
|
||||
@@ -84,6 +85,8 @@ public:
|
||||
void setGroupBackground(const QBrush& c);
|
||||
QColor groupTextColor() const;
|
||||
void setGroupTextColor(const QColor& c);
|
||||
QBrush itemBackground() const;
|
||||
void setItemBackground(const QBrush& c);
|
||||
|
||||
bool isBinding() const { return binding; }
|
||||
void openEditor(const QModelIndex &index);
|
||||
@@ -135,6 +138,7 @@ private:
|
||||
|
||||
QColor groupColor;
|
||||
QBrush background;
|
||||
QBrush _itemBackground;
|
||||
|
||||
QPointer<QWidget> activeEditor;
|
||||
QPersistentModelIndex editingIndex;
|
||||
|
||||