Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81c99745d4 | ||
|
|
d6831caea4 | ||
|
|
aa25e1fd56 | ||
|
|
0459aff34f | ||
|
|
aeb0a27401 | ||
|
|
50e3ef3dd8 | ||
|
|
9974256d71 | ||
|
|
8cf4134125 | ||
|
|
ef5b22c616 | ||
|
|
42161c807a | ||
|
|
acfc96f57c | ||
|
|
e6e83d5775 | ||
|
|
5b2bc2297b | ||
|
|
2de3e7e3be | ||
|
|
0d242297ff | ||
|
|
e2080b5cfc | ||
|
|
679fa81f6d | ||
|
|
6d0f14e1a5 | ||
|
|
281127c2c3 | ||
|
|
8e621f1f20 | ||
|
|
0948f73bf8 | ||
|
|
4bc1a18db2 | ||
|
|
80eb628ea3 | ||
|
|
d811915a0c | ||
|
|
0225563b46 | ||
|
|
da20405a6a | ||
|
|
ace6d69695 | ||
|
|
7baf0f90e8 | ||
|
|
2ad92ce958 | ||
|
|
50c4a8ed48 | ||
|
|
59d6a64098 | ||
|
|
3de877fe56 | ||
|
|
e2cebd9dcf | ||
|
|
58744408f0 | ||
|
|
e36655a7ab | ||
|
|
ffed6a9c5f | ||
|
|
38d8e6aa25 | ||
|
|
c109ef836a | ||
|
|
caa1a9f330 | ||
|
|
e71884b23d | ||
|
|
d04c386948 | ||
|
|
6a25de327c | ||
|
|
e63d1b1683 | ||
|
|
fa2ab356e1 | ||
|
|
80f92e5697 | ||
|
|
0c13402516 | ||
|
|
97e3d72566 | ||
|
|
682aaf66eb | ||
|
|
c939df73fa | ||
|
|
fdf169ce9a | ||
|
|
4b730a4949 | ||
|
|
788c357cc0 | ||
|
|
e3844b8d6c | ||
|
|
ff3fcdcacd | ||
|
|
a9268e6bf7 | ||
|
|
0227bd1786 | ||
|
|
227037e42a | ||
|
|
cd495a14ec | ||
|
|
312a8cf500 | ||
|
|
2fc8bbe9c9 | ||
|
|
f5c4b26aab | ||
|
|
c4d2d72e92 | ||
|
|
f90f0b0427 | ||
|
|
d360b4ced2 | ||
|
|
f074ea9d67 | ||
|
|
2e8137ad85 | ||
|
|
a65b1bdcaf | ||
|
|
4041aa72cc | ||
|
|
4d2de7bb2a | ||
|
|
bcb7118710 | ||
|
|
45390506dd | ||
|
|
f58a3d4401 | ||
|
|
a3e979a8ad | ||
|
|
adb72737e8 | ||
|
|
e626a7e302 | ||
|
|
8b6df4aaa5 | ||
|
|
ae999f132e | ||
|
|
9aa958e8b0 | ||
|
|
5652c8440e | ||
|
|
26f4c9b049 | ||
|
|
ce11fa9d10 | ||
|
|
333d2920db | ||
|
|
25eb02d07c | ||
|
|
3b2f940efa | ||
|
|
9dcbe91f02 | ||
|
|
4da810ba7c | ||
|
|
819f1effc5 | ||
|
|
ba94ef3493 | ||
|
|
0127fd89a3 | ||
|
|
79cb889d83 | ||
|
|
e760d3e967 | ||
|
|
c5333a2414 | ||
|
|
3a0c2a3113 | ||
|
|
789f78354a | ||
|
|
4c75168152 | ||
|
|
64a2024513 | ||
|
|
056e1ef947 | ||
|
|
f54869fbf7 | ||
|
|
835a20f03f | ||
|
|
067338ef23 |
47
README.md
@@ -7,26 +7,28 @@
|
||||
[What's new](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) •
|
||||
[Documentation](doc/user-guide.md)
|
||||
|
||||
Qt Advanced Docking System lets you create customizable layouts using a full
|
||||
featured window docking system similar to what is found in many popular
|
||||
integrated development environments (IDEs) such as Visual Studio.
|
||||
Qt Advanced Docking System lets you create customizable layouts using a full
|
||||
featured window docking system similar to what is found in many popular
|
||||
integrated development environments (IDEs) such as Visual Studio.
|
||||
|
||||
[](https://www.youtube.com/watch?v=7pdNfafg3Qc)
|
||||
|
||||
Everything is implemented with standard Qt functionality without any
|
||||
platform specific code. Basic usage of QWidgets and QLayouts and using basic
|
||||
styles as much as possible.
|
||||
## New and Noteworthy
|
||||
|
||||
This work is based on and inspired by the
|
||||
[Advanced Docking System for Qt](https://github.com/mfreiholz/Qt-Advanced-Docking-System)
|
||||
from Manuel Freiholz. I did an almost complete rewrite of his code to improve
|
||||
code quality, readibility and to fix all issues from the issue tracker
|
||||
of his docking system project.
|
||||
The [release 3.5.0](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.5.0)
|
||||
adds the new [focus highlighting](doc/user-guide.md#focushighlighting) feature.
|
||||
This optional feature enables highlighting of the focused dock widget like you
|
||||
know it from Visual Studio.
|
||||
|
||||

|
||||
|
||||
[learn more...](doc/user-guide.md#focushighlighting)
|
||||
|
||||
## Features
|
||||
|
||||
### Overview
|
||||
|
||||
- [New and Noteworthy](#new-and-noteworthy)
|
||||
- [Features](#features)
|
||||
- [Overview](#overview)
|
||||
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
|
||||
@@ -38,6 +40,7 @@ of his docking system project.
|
||||
- [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets)
|
||||
- [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets)
|
||||
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
|
||||
- [Python PyQt5 Bindings](#python-pyqt5-bindings)
|
||||
- [Tested Compatible Environments](#tested-compatible-environments)
|
||||
- [Windows](#windows)
|
||||
- [macOS](#macos)
|
||||
@@ -136,6 +139,20 @@ You can detach dock widgets and also dock areas in the following ways:
|
||||
|
||||
Normally clicking the close button of a dock widget will just hide the widget and the user can show it again using the toggleView() action of the dock widget. This is meant for user interfaces with a static amount of widgets. But the advanced docking system also supports dynamic dock widgets that will get deleted on close. If you set the dock widget flag `DockWidgetDeleteOnClose` for a certain dock widget, then it will be deleted as soon as you close this dock widget. This enables the implementation of user interfaces with dynamically created editors, like in word processing applications or source code development tools.
|
||||
|
||||
### Python PyQt5 Bindings
|
||||
|
||||

|
||||
|
||||
The Advanced Docking System comes with a complete Python integration based on
|
||||
PyQt5 bindings. The package is available via [conda-forge](https://github.com/conda-forge/pyqtads-feedstock). The python integration has been contributed to this project
|
||||
by the following people:
|
||||
|
||||
- [n-elie](https://github.com/n-elie)
|
||||
- [Hugo Slepicka](https://github.com/hhslepicka)
|
||||
- [K Lauer](https://github.com/klauer)
|
||||
|
||||
Latest working version: [3.5.1](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.5.1)
|
||||
|
||||
## Tested Compatible Environments
|
||||
|
||||
### Windows
|
||||
@@ -247,7 +264,13 @@ MainWindow::~MainWindow()
|
||||
## Developers
|
||||
|
||||
- Uwe Kindler, Project Maintainer
|
||||
- Manuel Freiholz
|
||||
- Manuel Freiholz
|
||||
|
||||
This work is based on and inspired by the
|
||||
[Advanced Docking System for Qt](https://github.com/mfreiholz/Qt-Advanced-Docking-System)
|
||||
from Manuel Freiholz. I did an almost complete rewrite of his code to improve
|
||||
code quality, readibility and to fix all issues from the issue tracker
|
||||
of his docking system project.
|
||||
|
||||
## License information
|
||||
|
||||
|
||||
@@ -78,35 +78,6 @@
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int LabelCount = 0;
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText(QString("Label %1 %2 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. "
|
||||
"Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque "
|
||||
"penatibus et magnis dis parturient montes, nascetur ridiculus mus. "
|
||||
"Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. "
|
||||
"Nulla consequat massa quis enim. Donec pede justo, fringilla vel, "
|
||||
"aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, "
|
||||
"imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede "
|
||||
"mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum "
|
||||
"semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, "
|
||||
"porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, "
|
||||
"dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla "
|
||||
"ut metus varius laoreet.")
|
||||
.arg(LabelCount)
|
||||
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
|
||||
DockWidget->setWidget(l);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function returns a features string with closable (c), movable (m) and floatable (f)
|
||||
* features. i.e. The following string is for a not closable but movable and floatable
|
||||
@@ -164,71 +135,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int CalendarCount = 0;
|
||||
QCalendarWidget* w = new QCalendarWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++));
|
||||
// The following lines are for testing the setWidget() and takeWidget()
|
||||
// functionality
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setWidget(w); // what happens if we set a widget if a widget is already set
|
||||
DockWidget->takeWidget(); // we remove the widget
|
||||
DockWidget->setWidget(w); // and set the widget again - there should be no error
|
||||
DockWidget->setToggleViewActionMode(ads::CDockWidget::ActionModeShow);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/date_range.svg"));
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int FileSystemCount = 0;
|
||||
QTreeView* w = new QTreeView();
|
||||
w->setFrameShape(QFrame::NoFrame);
|
||||
QFileSystemModel* m = new QFileSystemModel(w);
|
||||
m->setRootPath(QDir::currentPath());
|
||||
w->setModel(m);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
|
||||
.arg(FileSystemCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int EditorCount = 0;
|
||||
QPlainTextEdit* w = new QPlainTextEdit();
|
||||
w->setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||
"deleted. Enter your text here.");
|
||||
w->setStyleSheet("border: none");
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Editor %1").arg(EditorCount++));
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/edit.svg"));
|
||||
DockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
QMenu* OptionsMenu = new QMenu(DockWidget);
|
||||
OptionsMenu->setTitle(QObject::tr("Options"));
|
||||
OptionsMenu->setToolTip(OptionsMenu->title());
|
||||
OptionsMenu->setIcon(svgIcon(":/adsdemo/images/custom-menu-button.svg"));
|
||||
auto MenuAction = OptionsMenu->menuAction();
|
||||
// The object name of the action will be set for the QToolButton that
|
||||
// is created in the dock area title bar. You can use this name for CSS
|
||||
// styling
|
||||
MenuAction->setObjectName("optionsMenu");
|
||||
DockWidget->setTitleBarActions({OptionsMenu->menuAction()});
|
||||
auto a = OptionsMenu->addAction(QObject::tr("Clear Editor"));
|
||||
w->connect(a, SIGNAL(triggered()), SLOT(clear()));
|
||||
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
/**
|
||||
@@ -246,58 +152,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int TableCount = 0;
|
||||
auto w = new CMinSizeTableWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
|
||||
static int colCount = 5;
|
||||
static int rowCount = 30;
|
||||
w->setColumnCount(colCount);
|
||||
w->setRowCount(rowCount);
|
||||
for (int col = 0; col < colCount; ++col)
|
||||
{
|
||||
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
|
||||
for (int row = 0; row < rowCount; ++row)
|
||||
{
|
||||
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
|
||||
}
|
||||
}
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
||||
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
|
||||
auto ToolBar = DockWidget->createDefaultToolBar();
|
||||
auto Action = ToolBar->addAction(svgIcon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen");
|
||||
QObject::connect(Action, &QAction::triggered, [=]()
|
||||
{
|
||||
if (DockWidget->isFullScreen())
|
||||
{
|
||||
DockWidget->showNormal();
|
||||
}
|
||||
else
|
||||
{
|
||||
DockWidget->showFullScreen();
|
||||
}
|
||||
});
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createActiveXWidget(QMenu* ViewMenu, QWidget* parent = nullptr)
|
||||
{
|
||||
static int ActiveXCount = 0;
|
||||
QAxWidget* w = new QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Active X %1").arg(ActiveXCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
/**
|
||||
@@ -311,6 +165,7 @@ struct MainWindowPrivate
|
||||
QWidgetAction* PerspectiveListAction = nullptr;
|
||||
QComboBox* PerspectiveComboBox = nullptr;
|
||||
ads::CDockManager* DockManager = nullptr;
|
||||
ads::CDockWidget* WindowTitleTestDockWidget = nullptr;
|
||||
|
||||
MainWindowPrivate(CMainWindow* _public) : _this(_public) {}
|
||||
|
||||
@@ -343,14 +198,181 @@ struct MainWindowPrivate
|
||||
* Restore the perspective listo of the dock manager
|
||||
*/
|
||||
void restorePerspectives();
|
||||
|
||||
/**
|
||||
* Creates a dock widget with a file system tree view
|
||||
*/
|
||||
ads::CDockWidget* createFileSystemTreeDockWidget()
|
||||
{
|
||||
static int FileSystemCount = 0;
|
||||
QTreeView* w = new QTreeView();
|
||||
w->setFrameShape(QFrame::NoFrame);
|
||||
QFileSystemModel* m = new QFileSystemModel(w);
|
||||
m->setRootPath(QDir::currentPath());
|
||||
w->setModel(m);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
|
||||
.arg(FileSystemCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
// We disable focus to test focus highlighting if the dock widget content
|
||||
// does not support focus
|
||||
w->setFocusPolicy(Qt::NoFocus);
|
||||
auto ToolBar = DockWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dock widget with a QCalendarWidget
|
||||
*/
|
||||
ads::CDockWidget* createCalendarDockWidget()
|
||||
{
|
||||
static int CalendarCount = 0;
|
||||
QCalendarWidget* w = new QCalendarWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++));
|
||||
// The following lines are for testing the setWidget() and takeWidget()
|
||||
// functionality
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setWidget(w); // what happens if we set a widget if a widget is already set
|
||||
DockWidget->takeWidget(); // we remove the widget
|
||||
DockWidget->setWidget(w); // and set the widget again - there should be no error
|
||||
DockWidget->setToggleViewActionMode(ads::CDockWidget::ActionModeShow);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/date_range.svg"));
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
auto ToolBar = DockWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create dock widget with a text label
|
||||
*/
|
||||
ads::CDockWidget* createLongTextLabelDockWidget()
|
||||
{
|
||||
static int LabelCount = 0;
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText(QString("Label %1 %2 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. "
|
||||
"Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque "
|
||||
"penatibus et magnis dis parturient montes, nascetur ridiculus mus. "
|
||||
"Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. "
|
||||
"Nulla consequat massa quis enim. Donec pede justo, fringilla vel, "
|
||||
"aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, "
|
||||
"imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede "
|
||||
"mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum "
|
||||
"semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, "
|
||||
"porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, "
|
||||
"dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla "
|
||||
"ut metus varius laoreet.")
|
||||
.arg(LabelCount)
|
||||
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
|
||||
DockWidget->setWidget(l);
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates as imple editor widget
|
||||
*/
|
||||
ads::CDockWidget* createEditorWidget()
|
||||
{
|
||||
static int EditorCount = 0;
|
||||
QPlainTextEdit* w = new QPlainTextEdit();
|
||||
w->setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||
"deleted. Enter your text here.");
|
||||
w->setStyleSheet("border: none");
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Editor %1").arg(EditorCount++));
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/edit.svg"));
|
||||
DockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
QMenu* OptionsMenu = new QMenu(DockWidget);
|
||||
OptionsMenu->setTitle(QObject::tr("Options"));
|
||||
OptionsMenu->setToolTip(OptionsMenu->title());
|
||||
OptionsMenu->setIcon(svgIcon(":/adsdemo/images/custom-menu-button.svg"));
|
||||
auto MenuAction = OptionsMenu->menuAction();
|
||||
// The object name of the action will be set for the QToolButton that
|
||||
// is created in the dock area title bar. You can use this name for CSS
|
||||
// styling
|
||||
MenuAction->setObjectName("optionsMenu");
|
||||
DockWidget->setTitleBarActions({OptionsMenu->menuAction()});
|
||||
auto a = OptionsMenu->addAction(QObject::tr("Clear Editor"));
|
||||
w->connect(a, SIGNAL(triggered()), SLOT(clear()));
|
||||
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a table widget
|
||||
*/
|
||||
ads::CDockWidget* createTableWidget()
|
||||
{
|
||||
static int TableCount = 0;
|
||||
auto w = new CMinSizeTableWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
|
||||
static int colCount = 5;
|
||||
static int rowCount = 30;
|
||||
w->setColumnCount(colCount);
|
||||
w->setRowCount(rowCount);
|
||||
for (int col = 0; col < colCount; ++col)
|
||||
{
|
||||
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
|
||||
for (int row = 0; row < rowCount; ++row)
|
||||
{
|
||||
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
|
||||
}
|
||||
}
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
||||
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
|
||||
auto ToolBar = DockWidget->createDefaultToolBar();
|
||||
auto Action = ToolBar->addAction(svgIcon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen");
|
||||
QObject::connect(Action, &QAction::triggered, [=]()
|
||||
{
|
||||
if (DockWidget->isFullScreen())
|
||||
{
|
||||
DockWidget->showNormal();
|
||||
}
|
||||
else
|
||||
{
|
||||
DockWidget->showFullScreen();
|
||||
}
|
||||
});
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
/**
|
||||
* Creates an ActiveX widget on windows
|
||||
*/
|
||||
ads::CDockWidget* createActiveXWidget(QWidget* parent = nullptr)
|
||||
{
|
||||
static int ActiveXCount = 0;
|
||||
QAxWidget* w = new QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Active X %1").arg(ActiveXCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ui.menuView->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::createContent()
|
||||
{
|
||||
// Test container docking
|
||||
QMenu* ViewMenu = ui.menuView;
|
||||
auto DockWidget = createCalendarDockWidget(ViewMenu);
|
||||
auto DockWidget = createCalendarDockWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
||||
auto SpecialDockArea = DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
|
||||
|
||||
@@ -360,19 +382,16 @@ void MainWindowPrivate::createContent()
|
||||
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
|
||||
}
|
||||
|
||||
DockManager->addDockWidget(ads::LeftDockWidgetArea, createLongTextLabelDockWidget(ViewMenu));
|
||||
auto FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
||||
auto ToolBar = FileSystemWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
WindowTitleTestDockWidget = DockWidget;
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetFocusable, false);
|
||||
DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
|
||||
auto FileSystemWidget = createFileSystemTreeDockWidget();
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||
DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget);
|
||||
|
||||
FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
||||
ToolBar = FileSystemWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
FileSystemWidget = createFileSystemTreeDockWidget();
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||
@@ -384,7 +403,7 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// We create a calendar widget and clear all flags to prevent the dock area
|
||||
// from closing
|
||||
DockWidget = createCalendarDockWidget(ViewMenu);
|
||||
DockWidget = createCalendarDockWidget();
|
||||
DockWidget->setTabToolTip(QString("Tab ToolTip\nHodie est dies magna"));
|
||||
auto DockArea = DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, TopDockArea);
|
||||
|
||||
@@ -400,18 +419,18 @@ void MainWindowPrivate::createContent()
|
||||
TitleBar->insertWidget(Index + 1, CustomButton);
|
||||
QObject::connect(CustomButton, &QToolButton::clicked, [=]()
|
||||
{
|
||||
auto DockWidget = createEditorWidget(ui.menuView);
|
||||
auto DockWidget = createEditorWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
DockManager->addDockWidgetTabToArea(DockWidget, DockArea);
|
||||
_this->connect(DockWidget, SIGNAL(closeRequested()), SLOT(onEditorCloseRequested()));
|
||||
});
|
||||
|
||||
// Test dock area docking
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), BottomDockArea);
|
||||
|
||||
auto Action = ui.menuTests->addAction(QString("Set %1 Floating").arg(DockWidget->windowTitle()));
|
||||
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(setFloating()));
|
||||
@@ -421,9 +440,9 @@ void MainWindowPrivate::createContent()
|
||||
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(raise()));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (!DockManager->configFlags().testFlag(ads::CDockManager::OpaqueUndocking))
|
||||
if (!ads::CDockManager::testConfigFlag(ads::CDockManager::OpaqueUndocking))
|
||||
{
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -479,6 +498,9 @@ void MainWindowPrivate::createActions()
|
||||
ui.menuTests->addSeparator();
|
||||
a = ui.menuTests->addAction("Show Status Dialog");
|
||||
_this->connect(a, SIGNAL(triggered()), SLOT(showStatusDialog()));
|
||||
|
||||
a = ui.menuTests->addAction("Toggle Label 0 Window Title");
|
||||
_this->connect(a, SIGNAL(triggered()), SLOT(toggleDockWidgetWindowTitle()));
|
||||
ui.menuTests->addSeparator();
|
||||
}
|
||||
|
||||
@@ -571,6 +593,14 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
||||
// dock widget.
|
||||
// CDockManager::setConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar, true);
|
||||
|
||||
// uncomment the following line to enable focus highlighting of the dock
|
||||
// widget that has the focus
|
||||
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
|
||||
|
||||
// uncomment if you would like to enable an equal distribution of the
|
||||
// available size of a splitter to all contained dock widgets
|
||||
// CDockManager::setConfigFlag(CDockManager::EqualSplitOnInsertion, true);
|
||||
|
||||
// Now create the dock manager and its content
|
||||
d->DockManager = new CDockManager(this);
|
||||
|
||||
@@ -656,13 +686,14 @@ void CMainWindow::onViewToggled(bool Open)
|
||||
//============================================================================
|
||||
void CMainWindow::onViewVisibilityChanged(bool Visible)
|
||||
{
|
||||
Q_UNUSED(Visible);
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << DockWidget->objectName() << " visibilityChanged(" << Visible << ")";
|
||||
//qDebug() << DockWidget->objectName() << " visibilityChanged(" << Visible << ")";
|
||||
}
|
||||
|
||||
|
||||
@@ -672,7 +703,7 @@ void CMainWindow::createEditor()
|
||||
QObject* Sender = sender();
|
||||
QVariant vFloating = Sender->property("Floating");
|
||||
bool Floating = vFloating.isValid() ? vFloating.toBool() : true;
|
||||
auto DockWidget = createEditorWidget(d->ui.menuView);
|
||||
auto DockWidget = d->createEditorWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
connect(DockWidget, SIGNAL(closeRequested()), SLOT(onEditorCloseRequested()));
|
||||
|
||||
@@ -705,7 +736,7 @@ void CMainWindow::onEditorCloseRequested()
|
||||
//============================================================================
|
||||
void CMainWindow::createTable()
|
||||
{
|
||||
auto DockWidget = createTableWidget(d->ui.menuView);
|
||||
auto DockWidget = d->createTableWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
auto FloatingWidget = d->DockManager->addDockWidgetFloating(DockWidget);
|
||||
FloatingWidget->move(QPoint(40, 40));
|
||||
@@ -719,3 +750,20 @@ void CMainWindow::showStatusDialog()
|
||||
Dialog.exec();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::toggleDockWidgetWindowTitle()
|
||||
{
|
||||
QString Title = d->WindowTitleTestDockWidget->windowTitle();
|
||||
int i = Title.indexOf(" (Test)");
|
||||
if (-1 == i)
|
||||
{
|
||||
Title += " (Test)";
|
||||
}
|
||||
else
|
||||
{
|
||||
Title = Title.left(i);
|
||||
}
|
||||
d->WindowTitleTestDockWidget->setWindowTitle(Title);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ private slots:
|
||||
void createTable();
|
||||
void onEditorCloseRequested();
|
||||
void showStatusDialog();
|
||||
void toggleDockWidgetWindowTitle();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
313
demo/demo.py
@@ -10,11 +10,11 @@ from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
|
||||
QtCriticalMsg, QtFatalMsg, QSize)
|
||||
from PyQt5.QtGui import (QGuiApplication, QIcon, QCloseEvent)
|
||||
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
|
||||
QMenu, QTreeView, QAction, QWidgetAction,
|
||||
QComboBox, QStyle, QSizePolicy, QInputDialog, QMenu,
|
||||
QToolButton, QWidget, QPlainTextEdit,
|
||||
QTableWidget, QTableWidgetItem, QApplication,
|
||||
QMessageBox)
|
||||
QMenu, QTreeView, QAction, QWidgetAction,
|
||||
QComboBox, QStyle, QSizePolicy, QInputDialog, QMenu,
|
||||
QToolButton, QWidget, QPlainTextEdit,
|
||||
QTableWidget, QTableWidgetItem, QApplication,
|
||||
QMessageBox)
|
||||
try:
|
||||
from PyQt5.QAxContainer import QAxWidget
|
||||
except ImportError:
|
||||
@@ -48,7 +48,7 @@ def features_string(dock_widget: QtAds.CDockWidget) -> str:
|
||||
f = dock_widget.features()
|
||||
closable = f & QtAds.CDockWidget.DockWidgetClosable
|
||||
movable = f & QtAds.CDockWidget.DockWidgetMovable
|
||||
floatable = f &QtAds.CDockWidget.DockWidgetFloatable
|
||||
floatable = f & QtAds.CDockWidget.DockWidgetFloatable
|
||||
|
||||
return "c{} m{} f{}".format("+" if closable else "-",
|
||||
"+" if movable else "-",
|
||||
@@ -69,91 +69,7 @@ def svg_icon(filename: str):
|
||||
icon = QIcon(filename)
|
||||
icon.addPixmap(icon.pixmap(92))
|
||||
return icon
|
||||
|
||||
|
||||
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
label = QLabel()
|
||||
label.setWordWrap(True)
|
||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||
label.setText('''\
|
||||
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
||||
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
||||
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
||||
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
||||
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
||||
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
||||
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
||||
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
||||
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
||||
'''.format(_State.label_count, datetime.datetime.now().strftime("%H:%M:%S:%f")))
|
||||
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
||||
_State.label_count += 1
|
||||
dock_widget.setWidget(label)
|
||||
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
widget = QCalendarWidget()
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
||||
_State.calendar_count += 1
|
||||
# The following lines are for testing the setWidget() and takeWidget()
|
||||
# functionality
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setWidget(widget) # what happens if we set a widget if a widget is already set
|
||||
dock_widget.takeWidget() # we remove the widget
|
||||
dock_widget.setWidget(widget) # and set the widget again - there should be no error
|
||||
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/date_range.svg"))
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
widget = QTreeView()
|
||||
widget.setFrameShape(QFrame.NoFrame)
|
||||
|
||||
m = QFileSystemModel(widget)
|
||||
m.setRootPath(QDir.currentPath())
|
||||
widget.setModel(m)
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
||||
_State.file_system_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_editor_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
widget = QPlainTextEdit()
|
||||
widget.setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||
"deleted. Enter your text here.")
|
||||
widget.setStyleSheet("border: none")
|
||||
dock_widget = QtAds.CDockWidget("Editor {}".format(_State.editor_count))
|
||||
_State.editor_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/edit.svg"))
|
||||
dock_widget.setFeature(QtAds.CDockWidget.CustomCloseHandling, True)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
|
||||
options_menu = QMenu(dock_widget)
|
||||
options_menu.setTitle("Options")
|
||||
options_menu.setToolTip(options_menu.title())
|
||||
options_menu.setIcon(svg_icon(":/adsdemo/images/custom-menu-button.svg"))
|
||||
menu_action = options_menu.menuAction()
|
||||
# The object name of the action will be set for the QToolButton that
|
||||
# is created in the dock area title bar. You can use this name for CSS
|
||||
# styling
|
||||
menu_action.setObjectName("options_menu")
|
||||
dock_widget.setTitleBarActions([options_menu.menuAction()])
|
||||
a = options_menu.addAction("Clear Editor")
|
||||
a.triggered.connect(widget.clear)
|
||||
|
||||
return dock_widget
|
||||
|
||||
class CMinSizeTableWidget(QTableWidget):
|
||||
"""Custom QTableWidget with a minimum size hint to test CDockWidget
|
||||
@@ -162,43 +78,6 @@ class CMinSizeTableWidget(QTableWidget):
|
||||
def minimumSizeHint(self) -> QSize:
|
||||
return QSize(300, 100)
|
||||
|
||||
def create_table_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
widget = CMinSizeTableWidget()
|
||||
dock_widget = QtAds.CDockWidget("Table {}".format(_State.table_count))
|
||||
_State.table_count += 1
|
||||
COLCOUNT = 5
|
||||
ROWCOUNT = 30
|
||||
widget.setColumnCount(COLCOUNT)
|
||||
widget.setRowCount(ROWCOUNT)
|
||||
for col in range(ROWCOUNT):
|
||||
widget.setHorizontalHeaderItem(col, QTableWidgetItem("Col {}".format(col+1)))
|
||||
for row in range(ROWCOUNT):
|
||||
widget.setItem(row, col, QTableWidgetItem("T {:}-{:}".format(row+1, col+1)))
|
||||
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
||||
dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromContent)
|
||||
toolbar = dock_widget.createDefaultToolBar()
|
||||
action = toolbar.addAction(svg_icon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen")
|
||||
def on_toggle_fullscreen():
|
||||
if dock_widget.isFullScreen():
|
||||
dock_widget.showNormal()
|
||||
else:
|
||||
dock_widget.showFullScreen()
|
||||
action.triggered.connect(on_toggle_fullscreen)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
if ACTIVEX_AVAILABLE:
|
||||
def create_activex_widget(view_menu: QMenu, parent: QWidget = None) -> QtAds.CDockWidget:
|
||||
widget = QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent)
|
||||
dock_widget = QtAds.CDockWidget("Active X {}".format(_State.activex_count))
|
||||
_State.activex_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
class CCustomComponentsFactory(QtAds.CDockComponentsFactory):
|
||||
|
||||
@@ -235,37 +114,45 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
|
||||
# uncomment the following line if you want to use opaque undocking and
|
||||
# opaque splitter resizing
|
||||
#QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DefaultOpaqueConfig);
|
||||
#QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DefaultOpaqueConfig)
|
||||
|
||||
# uncomment the following line if you want a fixed tab width that does
|
||||
# not change if the visibility of the close button changes
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.RetainTabSizeWhenCloseButtonHidden, True)
|
||||
|
||||
# uncomment the following line if you don't want close button on DockArea's title bar
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasCloseButton, false);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasCloseButton, False)
|
||||
|
||||
# uncomment the following line if you don't want undock button on DockArea's title bar
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasUndockButton, false);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasUndockButton, False)
|
||||
|
||||
# uncomment the following line if you don't want tabs menu button on DockArea's title bar
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasTabsMenuButton, false);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHasTabsMenuButton, False)
|
||||
|
||||
# uncomment the following line if you don't want disabled buttons to appear on DockArea's title bar
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHideDisabledButtons, true);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaHideDisabledButtons, True)
|
||||
|
||||
# uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaDynamicTabsMenuButtonVisibility, true);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.DockAreaDynamicTabsMenuButtonVisibility, True)
|
||||
|
||||
# uncomment the following line if you want floating container to always show application title instead of active dock widget's title
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FloatingContainerHasWidgetTitle, false);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FloatingContainerHasWidgetTitle, False)
|
||||
|
||||
# uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FloatingContainerHasWidgetIcon, true);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FloatingContainerHasWidgetIcon, True)
|
||||
|
||||
# uncomment the following line if you want a central widget in the main dock container (the dock manager) without a titlebar
|
||||
# If you enable this code, you can test it in the demo with the Calendar 0
|
||||
# dock widget.
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.HideSingleCentralWidgetTitleBar, true);
|
||||
#QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.HideSingleCentralWidgetTitleBar, True)
|
||||
|
||||
# uncomment the following line to enable focus highlighting of the dock
|
||||
# widget that has the focus
|
||||
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FocusHighlighting, True)
|
||||
|
||||
# uncomment if you would like to enable an equal distribution of the
|
||||
# available size of a splitter to all contained dock widgets
|
||||
# QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.EqualSplitOnInsertion, True)
|
||||
|
||||
# Now create the dock manager and its content
|
||||
self.dock_manager = QtAds.CDockManager(self)
|
||||
@@ -288,8 +175,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
|
||||
def create_content(self):
|
||||
# Test container docking
|
||||
view_menu = self.menuView
|
||||
dock_widget = create_calendar_dock_widget(view_menu)
|
||||
dock_widget = self.create_calendar_dock_widget()
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
||||
special_dock_area = self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
||||
|
||||
@@ -297,8 +183,10 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
special_dock_area.setAllowedAreas(QtAds.OuterDockAreas)
|
||||
# special_dock_area.setAllowedAreas(QtAds.LeftDockWidgetArea | QtAds.RightDockWidgetArea) # just for testing
|
||||
|
||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
|
||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||
dock_widget = self.create_long_text_label_dock_widget()
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetFocusable, False)
|
||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
||||
file_system_widget = self.create_file_system_tree_dock_widget()
|
||||
tool_bar = file_system_widget.createDefaultToolBar()
|
||||
tool_bar.addAction(self.actionSaveState)
|
||||
tool_bar.addAction(self.actionRestoreState)
|
||||
@@ -306,10 +194,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
append_feature_string_to_window_title(file_system_widget)
|
||||
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
|
||||
|
||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||
tool_bar = file_system_widget.createDefaultToolBar()
|
||||
tool_bar.addAction(self.actionSaveState)
|
||||
tool_bar.addAction(self.actionRestoreState)
|
||||
file_system_widget = self.create_file_system_tree_dock_widget()
|
||||
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
||||
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
||||
append_feature_string_to_window_title(file_system_widget)
|
||||
@@ -321,7 +206,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
|
||||
# We create a calendar widget and clear all flags to prevent the dock area
|
||||
# from closing
|
||||
dock_widget = create_calendar_dock_widget(view_menu)
|
||||
dock_widget = self.create_calendar_dock_widget()
|
||||
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
|
||||
dock_area = self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
|
||||
|
||||
@@ -336,7 +221,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
index = title_bar.indexOf(title_bar.tabBar())
|
||||
title_bar.insertWidget(index + 1, custom_button)
|
||||
def on_button_clicked():
|
||||
dock_widget = create_editor_widget(self.menuView)
|
||||
dock_widget = self.create_editor_widget()
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||
self.dock_manager.addDockWidgetTabToArea(dock_widget, dock_area)
|
||||
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
||||
@@ -345,21 +230,21 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
# Test dock area docking
|
||||
right_dock_area = self.dock_manager.addDockWidget(
|
||||
QtAds.RightDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), top_dock_area)
|
||||
self.create_long_text_label_dock_widget(), top_dock_area)
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.TopDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
self.create_long_text_label_dock_widget(), right_dock_area)
|
||||
|
||||
bottom_dock_area = self.dock_manager.addDockWidget(
|
||||
QtAds.BottomDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
self.create_long_text_label_dock_widget(), right_dock_area)
|
||||
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.CenterDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
self.create_long_text_label_dock_widget(), right_dock_area)
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.CenterDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
|
||||
self.create_long_text_label_dock_widget(), bottom_dock_area)
|
||||
|
||||
|
||||
action = self.menuTests.addAction("Set {} Floating".format(dock_widget.windowTitle()))
|
||||
@@ -373,7 +258,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
flags = self.dock_manager.configFlags()
|
||||
if flags & QtAds.CDockManager.OpaqueUndocking:
|
||||
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea,
|
||||
create_activex_widget(view_menu), right_dock_area)
|
||||
self.create_activex_widget(), right_dock_area)
|
||||
|
||||
for dock_widget in self.dock_manager.dockWidgetsMap().values():
|
||||
dock_widget.viewToggled.connect(self.on_view_toggled)
|
||||
@@ -460,13 +345,13 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
if dock_widget is None:
|
||||
return
|
||||
|
||||
qDebug("{} visibility_changed({})".format(dock_widget.objectName(), visible))
|
||||
# qDebug("{} visibility_changed({})".format(dock_widget.objectName(), visible))
|
||||
|
||||
def create_editor(self):
|
||||
sender = self.sender()
|
||||
floating = sender.property("Floating")
|
||||
print("Floating:", floating)
|
||||
dock_widget = create_editor_widget(self.menuView)
|
||||
dock_widget = self.create_editor_widget()
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
||||
|
||||
@@ -484,7 +369,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
dock_widget.closeDockWidget()
|
||||
|
||||
def create_table(self):
|
||||
dock_widget = create_table_widget(self.menuView)
|
||||
dock_widget = self.create_table_widget()
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||
floating_widget = self.dock_manager.addDockWidgetFloating(dock_widget)
|
||||
floating_widget.move(QPoint(40, 40))
|
||||
@@ -545,6 +430,124 @@ class MainWindow(MainWindowUI, MainWindowBase):
|
||||
self.perspective_combo_box.setCurrentText(perspective_name)
|
||||
self.save_perspectives()
|
||||
|
||||
def create_long_text_label_dock_widget(self) -> QtAds.CDockWidget:
|
||||
label = QLabel()
|
||||
label.setWordWrap(True)
|
||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||
label.setText('''Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
||||
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
||||
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
||||
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
||||
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
||||
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
||||
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
||||
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
||||
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
||||
'''.format(_State.label_count, datetime.datetime.now().strftime("%H:%M:%S:%f")))
|
||||
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
||||
_State.label_count += 1
|
||||
dock_widget.setWidget(label)
|
||||
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
def create_calendar_dock_widget(self) -> QtAds.CDockWidget:
|
||||
widget = QCalendarWidget()
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
||||
_State.calendar_count += 1
|
||||
# The following lines are for testing the setWidget() and takeWidget()
|
||||
# functionality
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setWidget(widget) # what happens if we set a widget if a widget is already set
|
||||
dock_widget.takeWidget() # we remove the widget
|
||||
dock_widget.setWidget(widget) # and set the widget again - there should be no error
|
||||
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/date_range.svg"))
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
def create_file_system_tree_dock_widget(self) -> QtAds.CDockWidget:
|
||||
widget = QTreeView()
|
||||
widget.setFrameShape(QFrame.NoFrame)
|
||||
|
||||
m = QFileSystemModel(widget)
|
||||
m.setRootPath(QDir.currentPath())
|
||||
widget.setModel(m)
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
||||
_State.file_system_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
def create_editor_widget(self) -> QtAds.CDockWidget:
|
||||
widget = QPlainTextEdit()
|
||||
widget.setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||
"deleted. Enter your text here.")
|
||||
widget.setStyleSheet("border: none")
|
||||
dock_widget = QtAds.CDockWidget("Editor {}".format(_State.editor_count))
|
||||
_State.editor_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/edit.svg"))
|
||||
dock_widget.setFeature(QtAds.CDockWidget.CustomCloseHandling, True)
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
|
||||
options_menu = QMenu(dock_widget)
|
||||
options_menu.setTitle("Options")
|
||||
options_menu.setToolTip(options_menu.title())
|
||||
options_menu.setIcon(svg_icon(":/adsdemo/images/custom-menu-button.svg"))
|
||||
menu_action = options_menu.menuAction()
|
||||
# The object name of the action will be set for the QToolButton that
|
||||
# is created in the dock area title bar. You can use this name for CSS
|
||||
# styling
|
||||
menu_action.setObjectName("options_menu")
|
||||
dock_widget.setTitleBarActions([options_menu.menuAction()])
|
||||
a = options_menu.addAction("Clear Editor")
|
||||
a.triggered.connect(widget.clear)
|
||||
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_table_widget(self) -> QtAds.CDockWidget:
|
||||
widget = CMinSizeTableWidget()
|
||||
dock_widget = QtAds.CDockWidget("Table {}".format(_State.table_count))
|
||||
_State.table_count += 1
|
||||
COLCOUNT = 5
|
||||
ROWCOUNT = 30
|
||||
widget.setColumnCount(COLCOUNT)
|
||||
widget.setRowCount(ROWCOUNT)
|
||||
for col in range(ROWCOUNT):
|
||||
widget.setHorizontalHeaderItem(col, QTableWidgetItem("Col {}".format(col + 1)))
|
||||
for row in range(ROWCOUNT):
|
||||
widget.setItem(row, col, QTableWidgetItem("T {:}-{:}".format(row + 1, col + 1)))
|
||||
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
||||
dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromContent)
|
||||
toolbar = dock_widget.createDefaultToolBar()
|
||||
action = toolbar.addAction(svg_icon(":/adsdemo/images/fullscreen.svg"), "Toggle Fullscreen")
|
||||
|
||||
def on_toggle_fullscreen():
|
||||
if dock_widget.isFullScreen():
|
||||
dock_widget.showNormal()
|
||||
else:
|
||||
dock_widget.showFullScreen()
|
||||
|
||||
action.triggered.connect(on_toggle_fullscreen)
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
def create_activex_widget(self, parent: QWidget = None) -> QtAds.CDockWidget:
|
||||
widget = QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent)
|
||||
dock_widget = QtAds.CDockWidget("Active X {}".format(_State.activex_count))
|
||||
_State.activex_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def my_message_output(type, context, msg):
|
||||
if type == QtDebugMsg:
|
||||
|
||||
BIN
doc/cfg_flag_FocusHighlighting.gif
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
doc/python_logo.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
@@ -23,13 +23,14 @@
|
||||
- [`FloatingContainerHasWidgetTitle`](#floatingcontainerhaswidgettitle)
|
||||
- [`FloatingContainerHasWidgetIcon`](#floatingcontainerhaswidgeticon)
|
||||
- [`HideSingleCentralWidgetTitleBar`](#hidesinglecentralwidgettitlebar)
|
||||
- [`FocusHighlighting`](#focushighlighting)
|
||||
- [Styling](#styling)
|
||||
- [Disabling the Internal Style Sheet](#disabling-the-internal-style-sheet)
|
||||
|
||||
## Configuration Flags
|
||||
|
||||
The Advanced Docking System has a number of global configuration options to
|
||||
configure the design and the functionality of the docking system. Each
|
||||
configure the design and the functionality of the docking system. Eachs
|
||||
configuration will be explained in detail in the following sections.
|
||||
|
||||
### Setting Configuration Flags
|
||||
@@ -284,7 +285,8 @@ otherwise (default setting) it displays application icon.
|
||||
|
||||
### `HideSingleCentralWidgetTitleBar`
|
||||
|
||||
If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden.
|
||||
If there is only one single visible dock widget in the main dock container (the dock manager)
|
||||
and if this flag is set, then the titlebar of this dock widget will be hidden.
|
||||
This only makes sense for non draggable and non floatable dock widgets and enables
|
||||
the creation of some kind of "central" static widget. Because the titlebar is
|
||||
hidden, it is not possible to drag out the central widget to make it floating
|
||||
@@ -299,6 +301,114 @@ still has a titlebar to drag it out of the main window.
|
||||
|
||||

|
||||
|
||||
### `FocusHighlighting`
|
||||
|
||||
If this is enabled, the docking system is able to highlight the tab and the
|
||||
components of a dock area with a different style (i.e. a different color).
|
||||
This option is disabled by default and needs to be enabled explicitely
|
||||
because it adds some overhead. The dock manager needs to react on focus
|
||||
changes and dock widget dragging to highlight the right dock widget. You should
|
||||
enable it only, if you really need it for your application.
|
||||
|
||||
If the feature is enabled, you can also connect to the new dock manager
|
||||
signal `focusedDockWidgetChanged(CDockWidget* old, CDockWidget* now)` to
|
||||
react on focus changes and to prepare the content of the focused dock
|
||||
widget.
|
||||
|
||||
You can click into the tab, the titlebar or the content of a dock widget
|
||||
to focus it.
|
||||
|
||||

|
||||
|
||||
For the focused dock widget and dock widget tab, the property `focused` will
|
||||
be set to true and you can use this property to style the focused dock
|
||||
widget differently. The picture above uses the following styling:
|
||||
|
||||
```css
|
||||
/* Color the tab with the nhighlight color */
|
||||
ads--CDockWidgetTab[focused="true"]
|
||||
{
|
||||
background: palette(highlight);
|
||||
border-color: palette(highlight);
|
||||
}
|
||||
|
||||
/* Use a different colored close button icon to match the test color */
|
||||
ads--CDockWidgetTab[focused="true"] > #tabCloseButton
|
||||
{
|
||||
qproperty-icon: url(:/ads/images/close-button-focused.svg)
|
||||
}
|
||||
|
||||
/* Make a hovered focused close button a little bit lighter */
|
||||
ads--CDockWidgetTab[focused="true"] > #tabCloseButton:hover
|
||||
{
|
||||
background: rgba(255, 255, 255, 48);
|
||||
}
|
||||
|
||||
/* Make a pressed focused close button even more lighter */
|
||||
ads--CDockWidgetTab[focused="true"] > #tabCloseButton:pressed
|
||||
{
|
||||
background: rgba(255, 255, 255, 92);
|
||||
}
|
||||
|
||||
/* Use a different color for the tab label */
|
||||
ads--CDockWidgetTab[focused="true"] QLabel
|
||||
{
|
||||
color: palette(light);
|
||||
}
|
||||
|
||||
/* Paint a nice solid line for the whole title bar to create the illusion
|
||||
of an active tab */
|
||||
ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar
|
||||
{
|
||||
background: transparent;
|
||||
border-bottom: 2px solid palette(highlight);
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
```
|
||||
|
||||
If you have a content widget that does not support focussing for some reason
|
||||
(like `QVTKOpenGLStereoWidget` from the [VTK library](https://github.com/Kitware/VTK)),
|
||||
then you can manually switch the focus by reacting on mouse events. The
|
||||
following code shows, how to install en event filter on the `QVTKOpenGLStereoWidget`
|
||||
to properly switch the focus on `QEvent::MouseButtonPress`:
|
||||
|
||||
```c++
|
||||
static ads::CDockWidget* createVTK2DWindow(QMenu* ViewMenu, QObject* EventFilter)
|
||||
{
|
||||
QVTKOpenGLStereoWidget* qvtkOpenGLStereoWidget = new QVTKOpenGLStereoWidget;
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget("2D Window");
|
||||
DockWidget->setWidget(qvtkOpenGLStereoWidget);
|
||||
qvtkOpenGLStereoWidget->installEventFilter(EventFilter);
|
||||
qvtkOpenGLStereoWidget->setProperty("DockWidget", QVariant::fromValue(DockWidget));
|
||||
return DockWidget;
|
||||
}
|
||||
```
|
||||
|
||||
Now we can use the event filter function to react on mouse events and then
|
||||
use the dock manager function `setDockWidgetFocused()` to switch the focus:
|
||||
|
||||
```c++
|
||||
bool CMainWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QVTKOpenGLStereoWidget* vtkWidget = qobject_cast<QVTKOpenGLStereoWidget*>(watched);
|
||||
auto vDockWidget = vtkWidget->property("DockWidget");
|
||||
ads::CDockWidget* DockWidget = nullptr;
|
||||
if (vDockWidget.isValid())
|
||||
{
|
||||
DockWidget = qvariant_cast<ads::CDockWidget*>(vDockWidget);
|
||||
}
|
||||
|
||||
if (DockWidget)
|
||||
{
|
||||
d->DockManager->setDockWidgetFocused(DockWidget);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
The Advanced Docking System supports styling via [Qt Style Sheets](https://doc.qt.io/qt-5/stylesheet.html). All components like splitters, tabs, buttons, titlebar and
|
||||
|
||||
@@ -10,7 +10,14 @@ int main(int argc, char *argv[])
|
||||
QApplication a(argc, argv);
|
||||
QMainWindow w;
|
||||
|
||||
ads::CDockManager::setConfigFlag(ads::CDockManager::FocusHighlighting, true);
|
||||
ads::CDockManager::setConfigFlag(ads::CDockManager::AllTabsHaveCloseButton, true);
|
||||
auto dockManager = new ads::CDockManager(&w);
|
||||
QObject::connect(dockManager, &ads::CDockManager::focusedDockWidgetChanged, [] (ads::CDockWidget* old, ads::CDockWidget* now) {
|
||||
static int Count = 0;
|
||||
qDebug() << Count++ << " CDockManager::focusedDockWidgetChanged old: " << (old ? old->objectName() : "-") << " now: " << now->objectName() << " visible: " << now->isVisible();
|
||||
now->widget()->setFocus();
|
||||
});
|
||||
|
||||
QAction *action = new QAction("New Delete On Close", &w);
|
||||
w.menuBar()->addAction(action);
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
/*ui->setupUi(this);
|
||||
|
||||
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||
// the dock manager registers itself as the central widget.
|
||||
@@ -31,7 +32,67 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->menuView->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
// Add the dock widget to the top dock widget area
|
||||
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);*/
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||
// the dock manager registers itself as the central widget.
|
||||
m_DockManager1 = new ads::CDockManager(this);
|
||||
|
||||
// Create example content label - this can be any application specific
|
||||
// widget
|
||||
ads::CDockWidget* DockWidget;
|
||||
{
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
// Create a dock widget with the title Label 1 and set the created label
|
||||
// as the dock widget content
|
||||
DockWidget = new ads::CDockWidget("Label 1");
|
||||
DockWidget->setWidget(l);
|
||||
}
|
||||
|
||||
ads::CDockWidget* DockWidget2;
|
||||
{
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
// Create a dock widget with the title Label 1 and set the created label
|
||||
// as the dock widget content
|
||||
DockWidget2 = new ads::CDockWidget("Label 2");
|
||||
DockWidget2->setWidget(l);
|
||||
}
|
||||
|
||||
|
||||
// Add the toggleViewAction of the dock widget to the menu to give
|
||||
// the user the possibility to show the dock widget if it has been closed
|
||||
ui->menuView->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
// Add the dock widget to the top dock widget area
|
||||
m_DockManager1->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||
|
||||
|
||||
auto funcRemoveFirstManager = [=]()
|
||||
{
|
||||
m_DockManager1->removeDockWidget(DockWidget);
|
||||
|
||||
delete m_DockManager1;
|
||||
m_DockManager1 = nullptr;
|
||||
};
|
||||
QTimer::singleShot(3000, funcRemoveFirstManager);
|
||||
|
||||
auto funcAddSecondManager = [=]()
|
||||
{
|
||||
m_DockManager2 = new ads::CDockManager(this);
|
||||
|
||||
m_DockManager2->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||
};
|
||||
QTimer::singleShot(5000, funcAddSecondManager);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
||||
@@ -20,7 +20,8 @@ public:
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
ads::CDockManager* m_DockManager;
|
||||
ads::CDockManager* m_DockManager1;
|
||||
ads::CDockManager* m_DockManager2;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
61
setup.py
@@ -159,8 +159,20 @@ class build_ext(sipdistutils.build_ext):
|
||||
return sip_bin
|
||||
|
||||
raise SystemExit('Could not find PyQt SIP binary.')
|
||||
|
||||
def _sip_sipfiles_dir(self):
|
||||
sip_dir = super()._sip_sipfiles_dir()
|
||||
if os.path.exists(sip_dir):
|
||||
return sip_dir
|
||||
|
||||
return os.path.join(sys.prefix, 'sip', 'PyQt5')
|
||||
|
||||
def _sip_compile(self, sip_bin, source, sbf):
|
||||
target_dir = os.path.dirname(__file__) if self.inplace else self.build_lib
|
||||
pyi = os.path.join(target_dir, "PyQtAds", "QtAds", "ads.pyi")
|
||||
if not os.path.exists(os.path.dirname(pyi)):
|
||||
os.makedirs(os.path.dirname(pyi))
|
||||
|
||||
cmd = [sip_bin]
|
||||
if hasattr(self, 'sip_opts'):
|
||||
cmd += self.sip_opts
|
||||
@@ -173,11 +185,20 @@ class build_ext(sipdistutils.build_ext):
|
||||
"-I", self.inc_dir,
|
||||
"-c", self._sip_output_dir(),
|
||||
"-b", sbf,
|
||||
"-y", pyi,
|
||||
"-w", "-o"]
|
||||
|
||||
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
|
||||
cmd.append(source)
|
||||
self.spawn(cmd)
|
||||
|
||||
if os.path.exists(pyi):
|
||||
with open(pyi) as f:
|
||||
content = f.readlines()
|
||||
with open(pyi, "w") as f:
|
||||
for line in content:
|
||||
if not line.startswith("class ads"):
|
||||
f.write(line)
|
||||
|
||||
def swig_sources (self, sources, extension=None):
|
||||
if not self.extensions:
|
||||
@@ -210,10 +231,9 @@ class build_ext(sipdistutils.build_ext):
|
||||
|
||||
return super().swig_sources(sources, extension)
|
||||
|
||||
def build_extension(self, ext):
|
||||
# /usr/bin/rcc -name ads ../../Qt-Advanced-Docking-System/src/ads.qrc -o release/qrc_ads.cpp
|
||||
|
||||
def build_extension(self, ext):
|
||||
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
|
||||
headersources = ['src/DockAreaTitleBar_p.h']
|
||||
|
||||
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
|
||||
|
||||
@@ -247,6 +267,30 @@ class build_ext(sipdistutils.build_ext):
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
# Run moc on all orphan header files.
|
||||
for source in headersources:
|
||||
# *.cpp -> *.moc
|
||||
moc_file = os.path.basename(source).replace(".h", ".moc")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(source, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, source),
|
||||
dry_run=self.dry_run)
|
||||
|
||||
header = source
|
||||
if os.path.exists(header):
|
||||
# *.h -> moc_*.cpp
|
||||
moc_file = "moc_" + os.path.basename(header).replace(
|
||||
".h", ".cpp")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(header, out_file) or self.force:
|
||||
spawn.spawn(get_moc_args(out_file, header),
|
||||
dry_run=self.dry_run)
|
||||
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
# Add the temp build directory to include path, for compiler to find
|
||||
# the created .moc files
|
||||
ext.include_dirs += [self._sip_output_dir()]
|
||||
@@ -263,6 +307,17 @@ class build_ext(sipdistutils.build_ext):
|
||||
ext.sources.append(out_file)
|
||||
|
||||
sipdistutils.build_ext.build_extension(self, ext)
|
||||
|
||||
import inspect
|
||||
sys.path.append(os.path.join(self.build_lib, 'PyQtAds', 'QtAds'))
|
||||
import ads
|
||||
|
||||
with open(os.path.join(self.build_lib, 'PyQtAds', 'QtAds', '__init__.py'), 'w') as f:
|
||||
f.write('from .._version import *\n')
|
||||
f.write('from .ads import ads\n')
|
||||
for name, member in sorted(inspect.getmembers(ads.ads)):
|
||||
if not name.startswith('_'):
|
||||
f.write('{0} = ads.{0}\n'.format(name))
|
||||
|
||||
|
||||
class ProcessResourceCommand(cmd.Command):
|
||||
|
||||
37
sip/DockAreaTitleBar_p.sip
Normal file
@@ -0,0 +1,37 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CTitleBarButton : QToolButton
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockAreaTitleBar_p.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
bool event(QEvent *ev);
|
||||
|
||||
public:
|
||||
CTitleBarButton(bool visible = true, QWidget* parent /TransferThis/ = Q_NULLPTR );
|
||||
virtual void setVisible(bool visible);
|
||||
};
|
||||
|
||||
|
||||
class CSpacerWidget : QWidget
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockAreaTitleBar_p.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
CSpacerWidget(QWidget* Parent /TransferThis/ = 0 );
|
||||
virtual QSize sizeHint() const;
|
||||
virtual QSize minimumSizeHint() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
|
||||
class CDockAreaWidget : QFrame
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
virtual ~CDockAreaWidget();
|
||||
ads::CDockManager* dockManager() const;
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
virtual QSize minimumSizeHint() const;
|
||||
QRect titleBarGeometry() const;
|
||||
QRect contentAreaGeometry() const;
|
||||
int dockWidgetsCount() const;
|
||||
|
||||
31
sip/DockFocusController.sip
Normal file
@@ -0,0 +1,31 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
/**
|
||||
* Manages focus styling of dock widgets and handling of focus changes
|
||||
*/
|
||||
class CDockFocusController : QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockFocusController.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
CDockFocusController(ads::CDockManager* DockManager);
|
||||
virtual ~CDockFocusController();
|
||||
|
||||
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
|
||||
void notifyFloatingWidgetDrop(ads::CFloatingDockContainer* FloatingWidget);
|
||||
|
||||
public slots:
|
||||
void setDockWidgetFocused(ads::CDockWidget* focusedNow);
|
||||
|
||||
}; // class DockFocusController
|
||||
};
|
||||
// namespace ads
|
||||
|
||||
%End
|
||||
@@ -133,6 +133,8 @@ protected:
|
||||
void removeDockContainer(ads::CDockContainerWidget* DockContainer /TransferBack/);
|
||||
ads::CDockOverlay* containerOverlay() const;
|
||||
ads::CDockOverlay* dockAreaOverlay() const;
|
||||
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
|
||||
void notifyFloatingWidgetDrop(ads::CFloatingDockContainer* FloatingWidget);
|
||||
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
|
||||
@@ -166,6 +168,8 @@ public:
|
||||
FloatingContainerHasWidgetTitle,
|
||||
FloatingContainerHasWidgetIcon,
|
||||
HideSingleCentralWidgetTitleBar,
|
||||
FocusHighlighting,
|
||||
EqualSplitOnInsertion,
|
||||
DefaultDockAreaButtons,
|
||||
DefaultBaseConfig,
|
||||
DefaultOpaqueConfig,
|
||||
@@ -194,8 +198,8 @@ public:
|
||||
const QList<ads::CDockContainerWidget*> dockContainers() const;
|
||||
const QList<ads::CFloatingDockContainer*> floatingWidgets() const;
|
||||
unsigned int zOrderIndex() const;
|
||||
QByteArray saveState(int version = 1) const;
|
||||
bool restoreState(const QByteArray &state, int version = 1);
|
||||
QByteArray saveState(int version = 0) const;
|
||||
bool restoreState(const QByteArray &state, int version = 0);
|
||||
void addPerspective(const QString& UniquePrespectiveName);
|
||||
void removePerspective(const QString& Name);
|
||||
void removePerspectives(const QStringList& Names);
|
||||
@@ -211,6 +215,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void openPerspective(const QString& PerspectiveName);
|
||||
void setDockWidgetFocused(ads::CDockWidget* DockWidget);
|
||||
|
||||
signals:
|
||||
void perspectiveListChanged();
|
||||
@@ -223,6 +228,7 @@ signals:
|
||||
void dockAreaCreated(ads::CDockAreaWidget* DockArea);
|
||||
void dockWidgetAboutToBeRemoved(ads::CDockWidget* DockWidget);
|
||||
void dockWidgetRemoved(ads::CDockWidget* DockWidget);
|
||||
void focusedDockWidgetChanged(ads::CDockWidget* old, ads::CDockWidget* now);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
DockWidgetFloatable,
|
||||
DockWidgetDeleteOnClose,
|
||||
CustomCloseHandling,
|
||||
DockWidgetFocusable,
|
||||
DefaultDockWidgetFeatures,
|
||||
AllDockWidgetFeatures,
|
||||
NoDockWidgetFeatures
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
bool isClosable() const;
|
||||
virtual bool event(QEvent *e);
|
||||
void setElideMode(Qt::TextElideMode mode);
|
||||
void updateStyle();
|
||||
|
||||
public slots:
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
|
||||
virtual void moveFloating() = 0;
|
||||
virtual void finishDragging() = 0;
|
||||
virtual ~IFloatingWidget();
|
||||
};
|
||||
|
||||
|
||||
@@ -56,6 +57,10 @@ protected:
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
virtual void hideEvent(QHideEvent *event);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
%If (WS_WIN)
|
||||
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
||||
%End
|
||||
|
||||
|
||||
public:
|
||||
CFloatingDockContainer(ads::CDockManager* DockManager /TransferThis/);
|
||||
|
||||
@@ -13,7 +13,6 @@ class CFloatingDragPreview : QWidget, ads::IFloatingWidget
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void moveEvent(QMoveEvent *event);
|
||||
virtual void paintEvent(QPaintEvent *e);
|
||||
CFloatingDragPreview(QWidget* Content /TransferThis/, QWidget* parent /TransferThis/);
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
%Include ads_globals.sip
|
||||
%Include DockWidget.sip
|
||||
%Include DockAreaTabBar.sip
|
||||
%Include DockAreaTitleBar_p.sip
|
||||
%Include DockAreaTitleBar.sip
|
||||
%Include DockAreaWidget.sip
|
||||
%Include DockComponentsFactory.sip
|
||||
%Include DockContainerWidget.sip
|
||||
%Include DockingStateReader.sip
|
||||
%Include DockFocusController.sip
|
||||
%Include DockManager.sip
|
||||
%Include DockOverlay.sip
|
||||
%Include DockSplitter.sip
|
||||
|
||||
@@ -8,13 +8,6 @@ namespace ads
|
||||
#include <ads_globals.h>
|
||||
%End
|
||||
|
||||
enum eStateFileVersion
|
||||
{
|
||||
InitialVersion,
|
||||
Version1,
|
||||
CurrentVersion
|
||||
};
|
||||
|
||||
enum DockWidgetArea
|
||||
{
|
||||
NoDockWidgetArea,
|
||||
|
||||
@@ -17,6 +17,7 @@ set(ads_SRCS
|
||||
DockWidget.cpp
|
||||
DockWidgetTab.cpp
|
||||
DockingStateReader.cpp
|
||||
DockFocusController.cpp
|
||||
ElidingLabel.cpp
|
||||
FloatingDockContainer.cpp
|
||||
FloatingDragPreview.cpp
|
||||
@@ -24,7 +25,7 @@ set(ads_SRCS
|
||||
DockComponentsFactory.cpp
|
||||
ads.qrc
|
||||
)
|
||||
set(ads_INSTALL_INCLUDE
|
||||
set(ads_HEADERS
|
||||
ads_globals.h
|
||||
DockAreaTabBar.h
|
||||
DockAreaTitleBar.h
|
||||
@@ -37,6 +38,7 @@ set(ads_INSTALL_INCLUDE
|
||||
DockWidget.h
|
||||
DockWidgetTab.h
|
||||
DockingStateReader.h
|
||||
DockFocusController.h
|
||||
ElidingLabel.h
|
||||
FloatingDockContainer.h
|
||||
FloatingDragPreview.h
|
||||
@@ -45,13 +47,13 @@ set(ads_INSTALL_INCLUDE
|
||||
)
|
||||
if (UNIX)
|
||||
set(ads_SRCS linux/FloatingWidgetTitleBar.cpp ${ads_SRCS})
|
||||
set(ads_INSTALL_INCLUDE linux/FloatingWidgetTitleBar.h ${ads_INSTALL_INCLUDE})
|
||||
set(ads_HEADERS linux/FloatingWidgetTitleBar.h ${ads_HEADERS})
|
||||
endif()
|
||||
if(BUILD_STATIC)
|
||||
add_library(qtadvanceddocking STATIC ${ads_SRCS})
|
||||
add_library(qtadvanceddocking STATIC ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions(qtadvanceddocking PUBLIC ADS_STATIC)
|
||||
else()
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS})
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions(qtadvanceddocking PRIVATE ADS_SHARED_EXPORT)
|
||||
endif()
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
@@ -73,7 +75,7 @@ write_basic_package_version_file(
|
||||
VERSION ${VERSION_SHORT}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(FILES ${ads_INSTALL_INCLUDE}
|
||||
install(FILES ${ads_HEADERS}
|
||||
DESTINATION include
|
||||
COMPONENT headers
|
||||
)
|
||||
@@ -102,5 +104,5 @@ install(FILES qtadvanceddockingConfig.cmake "${CMAKE_CURRENT_BINARY_DIR}/qtadvan
|
||||
|
||||
target_include_directories(qtadvanceddocking PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
|
||||
@@ -138,6 +138,8 @@ CDockAreaTabBar::CDockAreaTabBar(CDockAreaWidget* parent) :
|
||||
d->TabsLayout->addStretch(1);
|
||||
d->TabsContainerWidget->setLayout(d->TabsLayout);
|
||||
setWidget(d->TabsContainerWidget);
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
|
||||
@@ -456,6 +458,11 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
|
||||
updateGeometry();
|
||||
break;
|
||||
|
||||
// Setting the text of a tab will cause a LayoutRequest event
|
||||
case QEvent::LayoutRequest:
|
||||
updateGeometry();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -103,10 +103,11 @@ struct DockAreaTitleBarPrivate
|
||||
|
||||
/**
|
||||
* Returns true if the given config flag is set
|
||||
* Convenience function to ease config flag testing
|
||||
*/
|
||||
static bool testConfigFlag(CDockManager::eConfigFlag Flag)
|
||||
{
|
||||
return CDockManager::configFlags().testFlag(Flag);
|
||||
return CDockManager::testConfigFlag(Flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +163,7 @@ void DockAreaTitleBarPrivate::createButtons()
|
||||
|
||||
// Undock button
|
||||
UndockButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasUndockButton));
|
||||
UndockButton->setObjectName("undockButton");
|
||||
UndockButton->setObjectName("detachGroupButton");
|
||||
UndockButton->setAutoRaise(true);
|
||||
internal::setToolTip(UndockButton, QObject::tr("Detach Group"));
|
||||
internal::setButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton, ads::DockAreaUndockIcon);
|
||||
@@ -172,7 +173,7 @@ void DockAreaTitleBarPrivate::createButtons()
|
||||
|
||||
// Close button
|
||||
CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton));
|
||||
CloseButton->setObjectName("closeButton");
|
||||
CloseButton->setObjectName("dockAreaCloseButton");
|
||||
CloseButton->setAutoRaise(true);
|
||||
internal::setButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, ads::DockAreaCloseIcon);
|
||||
if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
|
||||
@@ -212,7 +213,7 @@ IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset,
|
||||
{
|
||||
QSize Size = DockArea->size();
|
||||
this->DragState = DragState;
|
||||
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
|
||||
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
|
||||
(DraggingFloatingWidget != DragState);
|
||||
CFloatingDockContainer* FloatingDockContainer = nullptr;
|
||||
IFloatingWidget* FloatingWidget;
|
||||
@@ -268,6 +269,8 @@ CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
|
||||
d->createTabBar();
|
||||
d->Layout->addWidget(new CSpacerWidget(this));
|
||||
d->createButtons();
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
|
||||
@@ -465,6 +468,11 @@ void CDockAreaTitleBar::mousePressEvent(QMouseEvent* ev)
|
||||
ev->accept();
|
||||
d->DragStartMousePos = ev->pos();
|
||||
d->DragState = DraggingMousePressed;
|
||||
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
d->TabBar->currentTab()->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Super::mousePressEvent(ev);
|
||||
@@ -485,6 +493,7 @@ void CDockAreaTitleBar::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
d->FloatingWidget->finishDragging();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Super::mouseReleaseEvent(ev);
|
||||
@@ -570,12 +579,12 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
||||
}
|
||||
|
||||
QMenu Menu(this);
|
||||
auto Action = Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
|
||||
auto Action = Menu.addAction(tr("Detach Group"), this, SLOT(onUndockButtonClicked()));
|
||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
|
||||
Menu.addSeparator();
|
||||
Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
|
||||
Action = Menu.addAction(tr("Close Group"), this, SLOT(onCloseButtonClicked()));
|
||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||
Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas()));
|
||||
Menu.addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
|
||||
Menu.exec(ev->globalPos());
|
||||
}
|
||||
|
||||
@@ -594,11 +603,12 @@ int CDockAreaTitleBar::indexOf(QWidget *widget) const
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CTitleBarButton::CTitleBarButton(bool visible /*= true*/, QWidget* parent /*= nullptr*/) : tTitleBarButton(parent),
|
||||
Visible(visible),
|
||||
HideWhenDisabled(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
|
||||
CTitleBarButton::CTitleBarButton(bool visible, QWidget* parent)
|
||||
: tTitleBarButton(parent),
|
||||
Visible(visible),
|
||||
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
|
||||
{
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -136,6 +136,10 @@ public:
|
||||
m_CurrentWidget = nullptr;
|
||||
m_CurrentIndex = -1;
|
||||
}
|
||||
else if (indexOf(Widget) < m_CurrentIndex)
|
||||
{
|
||||
--m_CurrentIndex;
|
||||
}
|
||||
m_Widgets.removeOne(Widget);
|
||||
}
|
||||
|
||||
@@ -413,6 +417,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
bool Activate)
|
||||
{
|
||||
d->ContentsLayout->insertWidget(index, DockWidget);
|
||||
DockWidget->setDockArea(this);
|
||||
DockWidget->tabWidget()->setDockAreaWidget(this);
|
||||
auto TabWidget = DockWidget->tabWidget();
|
||||
// Inserting the tab will change the current index which in turn will
|
||||
@@ -428,7 +433,6 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
{
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
DockWidget->setDockArea(this);
|
||||
// If this dock area is hidden, then we need to make it visible again
|
||||
// by calling DockWidget->toggleViewInternal(true);
|
||||
if (!this->isVisible() && d->ContentsLayout->count() > 1 && !dockManager()->isRestoringState())
|
||||
@@ -443,12 +447,15 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
ADS_PRINT("CDockAreaWidget::removeDockWidget");
|
||||
auto NextOpenDockWidget = nextOpenDockWidget(DockWidget);
|
||||
auto CurrentDockWidget = currentDockWidget();
|
||||
auto NextOpenDockWidget = (DockWidget == CurrentDockWidget) ? nextOpenDockWidget(DockWidget) : nullptr;
|
||||
|
||||
d->ContentsLayout->removeWidget(DockWidget);
|
||||
auto TabWidget = DockWidget->tabWidget();
|
||||
TabWidget->hide();
|
||||
d->tabBar()->removeTab(TabWidget);
|
||||
TabWidget->setParent(DockWidget);
|
||||
DockWidget->setDockArea(nullptr);
|
||||
CDockContainerWidget* DockContainer = dockContainer();
|
||||
if (NextOpenDockWidget)
|
||||
{
|
||||
@@ -460,7 +467,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
DockContainer->removeDockArea(this);
|
||||
this->deleteLater();
|
||||
}
|
||||
else
|
||||
else if (DockWidget == CurrentDockWidget)
|
||||
{
|
||||
// if contents layout is not empty but there are no more open dock
|
||||
// widgets, then we need to hide the dock area because it does not
|
||||
@@ -731,7 +738,7 @@ void CDockAreaWidget::updateTitleBarVisibility()
|
||||
return;
|
||||
}
|
||||
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::AlwaysShowTabs))
|
||||
if (CDockManager::testConfigFlag(CDockManager::AlwaysShowTabs))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -739,7 +746,7 @@ void CDockAreaWidget::updateTitleBarVisibility()
|
||||
if (d->TitleBar)
|
||||
{
|
||||
bool Hidden = Container->hasTopLevelDockWidget() && (Container->isFloating()
|
||||
|| CDockManager::configFlags().testFlag(CDockManager::HideSingleCentralWidgetTitleBar));
|
||||
|| CDockManager::testConfigFlag(CDockManager::HideSingleCentralWidgetTitleBar));
|
||||
d->TitleBar->setVisible(!Hidden);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,12 +147,12 @@ public:
|
||||
* Adds dock widget to container and returns the dock area that contains
|
||||
* the inserted dock widget
|
||||
*/
|
||||
CDockAreaWidget* dockWidgetIntoContainer(DockWidgetArea area, CDockWidget* Dockwidget);
|
||||
CDockAreaWidget* addDockWidgetToContainer(DockWidgetArea area, CDockWidget* Dockwidget);
|
||||
|
||||
/**
|
||||
* Adds dock widget to a existing DockWidgetArea
|
||||
*/
|
||||
CDockAreaWidget* dockWidgetIntoDockArea(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* addDockWidgetToDockArea(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* TargetDockArea);
|
||||
|
||||
/**
|
||||
@@ -299,11 +299,29 @@ public:
|
||||
CDockSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = nullptr)
|
||||
{
|
||||
CDockSplitter* s = new CDockSplitter(orientation, parent);
|
||||
s->setOpaqueResize(CDockManager::configFlags().testFlag(CDockManager::OpaqueSplitterResize));
|
||||
s->setOpaqueResize(CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize));
|
||||
s->setChildrenCollapsible(false);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures equal distribution of the sizes of a splitter if an dock widget
|
||||
* is inserted from code
|
||||
*/
|
||||
void adjustSplitterSizesOnInsertion(QSplitter* Splitter, qreal LastRatio = 1.0)
|
||||
{
|
||||
int AreaSize = (Splitter->orientation() == Qt::Horizontal) ? Splitter->width() : Splitter->height();
|
||||
auto SplitterSizes = Splitter->sizes();
|
||||
|
||||
qreal TotRatio = SplitterSizes.size() - 1.0 + LastRatio;
|
||||
for(int i = 0; i < SplitterSizes.size() -1; i++)
|
||||
{
|
||||
SplitterSizes[i] = AreaSize / TotRatio;
|
||||
}
|
||||
SplitterSizes.back() = AreaSize * LastRatio / TotRatio;
|
||||
Splitter->setSizes(SplitterSizes);
|
||||
}
|
||||
|
||||
|
||||
// private slots: ------------------------------------------------------------
|
||||
void onDockAreaViewToggled(bool Visible)
|
||||
@@ -1013,7 +1031,7 @@ bool DockContainerWidgetPrivate::restoreChildNodes(CDockingStateReader& s,
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetArea area,
|
||||
CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToContainer(DockWidgetArea area,
|
||||
CDockWidget* Dockwidget)
|
||||
{
|
||||
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
||||
@@ -1126,7 +1144,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetArea area,
|
||||
CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetArea area,
|
||||
CDockWidget* Dockwidget, CDockAreaWidget* TargetDockArea)
|
||||
{
|
||||
if (CenterDockWidgetArea == area)
|
||||
@@ -1144,16 +1162,29 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
||||
int index = TargetAreaSplitter ->indexOf(TargetDockArea);
|
||||
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
||||
{
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
|
||||
TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea);
|
||||
// do nothing, if flag is not enabled
|
||||
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
|
||||
{
|
||||
adjustSplitterSizesOnInsertion(TargetAreaSplitter);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()");
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()");
|
||||
auto TargetAreaSizes = TargetAreaSplitter->sizes();
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
NewSplitter->addWidget(TargetDockArea);
|
||||
|
||||
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||
TargetAreaSplitter->insertWidget(index, NewSplitter);
|
||||
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
|
||||
{
|
||||
TargetAreaSplitter->setSizes(TargetAreaSizes);
|
||||
adjustSplitterSizesOnInsertion(NewSplitter);
|
||||
}
|
||||
}
|
||||
|
||||
appendDockAreas({NewDockArea});
|
||||
@@ -1211,11 +1242,11 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW
|
||||
Dockwidget->setDockManager(d->DockManager);
|
||||
if (DockAreaWidget)
|
||||
{
|
||||
return d->dockWidgetIntoDockArea(area, Dockwidget, DockAreaWidget);
|
||||
return d->addDockWidgetToDockArea(area, Dockwidget, DockAreaWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
return d->dockWidgetIntoContainer(area, Dockwidget);
|
||||
return d->addDockWidgetToContainer(area, Dockwidget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,9 +1319,9 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
internal::hideEmptyParentSplitters(Splitter);
|
||||
|
||||
// Remove this area from cached areas
|
||||
const auto& cache = d->LastAddedAreaCache;
|
||||
if (auto p = std::find(cache, cache+sizeof(cache)/sizeof(cache[0]), area)) {
|
||||
d->LastAddedAreaCache[std::distance(cache, p)] = nullptr;
|
||||
auto p = std::find(std::begin(d->LastAddedAreaCache), std::end(d->LastAddedAreaCache), area);
|
||||
if (p != std::end(d->LastAddedAreaCache)) {
|
||||
*p = nullptr;
|
||||
}
|
||||
|
||||
// If splitter has more than 1 widgets, we are finished and can leave
|
||||
@@ -1459,6 +1490,13 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
// level widget anymore
|
||||
CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
|
||||
}
|
||||
|
||||
window()->activateWindow();
|
||||
if (SingleDroppedDockWidget)
|
||||
{
|
||||
d->DockManager->notifyWidgetOrAreaRelocation(SingleDroppedDockWidget);
|
||||
}
|
||||
d->DockManager->notifyFloatingWidgetDrop(FloatingWidget);
|
||||
}
|
||||
|
||||
|
||||
@@ -1478,6 +1516,9 @@ void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea,
|
||||
// If there was a top level widget before the drop, then it is not top
|
||||
// level widget anymore
|
||||
CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
|
||||
|
||||
window()->activateWindow();
|
||||
d->DockManager->notifyWidgetOrAreaRelocation(Widget);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
bool isInFrontOf(CDockContainerWidget* Other) const;
|
||||
|
||||
/**
|
||||
* Returns the dock area at teh given global position or 0 if there is no
|
||||
* Returns the dock area at the given global position or 0 if there is no
|
||||
* dock area at this position
|
||||
*/
|
||||
CDockAreaWidget* dockAreaAt(const QPoint& GlobalPos) const;
|
||||
|
||||
383
src/DockFocusController.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
//============================================================================
|
||||
/// \file DockFocusController.cpp
|
||||
/// \author Uwe Kindler
|
||||
/// \date 05.06.2020
|
||||
/// \brief Implementation of CDockFocusController class
|
||||
//============================================================================
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include "DockFocusController.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QApplication>
|
||||
#include <QAbstractButton>
|
||||
|
||||
#include "DockWidget.h"
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockWidgetTab.h"
|
||||
#include "DockContainerWidget.h"
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#endif
|
||||
|
||||
namespace ads
|
||||
{
|
||||
/**
|
||||
* Private data class of CDockFocusController class (pimpl)
|
||||
*/
|
||||
struct DockFocusControllerPrivate
|
||||
{
|
||||
CDockFocusController *_this;
|
||||
QPointer<CDockWidget> FocusedDockWidget = nullptr;
|
||||
QPointer<CDockAreaWidget> FocusedArea = nullptr;
|
||||
CDockWidget* OldFocusedDockWidget = nullptr;
|
||||
#ifdef Q_OS_LINUX
|
||||
QPointer<CFloatingDockContainer> FloatingWidget = nullptr;
|
||||
#endif
|
||||
CDockManager* DockManager;
|
||||
bool ForceFocusChangedSignal = false;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
DockFocusControllerPrivate(CDockFocusController *_public);
|
||||
|
||||
/**
|
||||
* This function updates the focus style of the given dock widget and
|
||||
* the dock area that it belongs to
|
||||
*/
|
||||
void updateDockWidgetFocus(CDockWidget* DockWidget);
|
||||
};
|
||||
// struct DockFocusControllerPrivate
|
||||
|
||||
|
||||
//===========================================================================
|
||||
static void updateDockWidgetFocusStyle(CDockWidget* DockWidget, bool Focused)
|
||||
{
|
||||
DockWidget->setProperty("focused", Focused);
|
||||
DockWidget->tabWidget()->setProperty("focused", Focused);
|
||||
DockWidget->tabWidget()->updateStyle();
|
||||
internal::repolishStyle(DockWidget);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
|
||||
{
|
||||
DockArea->setProperty("focused", Focused);
|
||||
internal::repolishStyle(DockArea);
|
||||
internal::repolishStyle(DockArea->titleBar());
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
#ifdef Q_OS_LINUX
|
||||
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
|
||||
{
|
||||
auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget());
|
||||
if (!TitleBar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TitleBar->setProperty("focused", Focused);
|
||||
TitleBar->updateStyle();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockFocusControllerPrivate::DockFocusControllerPrivate(
|
||||
CDockFocusController *_public) :
|
||||
_this(_public)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
|
||||
{
|
||||
if (!DockWidget->features().testFlag(CDockWidget::DockWidgetFocusable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CDockAreaWidget* NewFocusedDockArea = nullptr;
|
||||
if (FocusedDockWidget)
|
||||
{
|
||||
updateDockWidgetFocusStyle(FocusedDockWidget, false);
|
||||
}
|
||||
|
||||
CDockWidget* old = FocusedDockWidget;
|
||||
FocusedDockWidget = DockWidget;
|
||||
updateDockWidgetFocusStyle(FocusedDockWidget, true);
|
||||
NewFocusedDockArea = FocusedDockWidget->dockAreaWidget();
|
||||
if (NewFocusedDockArea && (FocusedArea != NewFocusedDockArea))
|
||||
{
|
||||
if (FocusedArea)
|
||||
{
|
||||
QObject::disconnect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
|
||||
updateDockAreaFocusStyle(FocusedArea, false);
|
||||
}
|
||||
|
||||
FocusedArea = NewFocusedDockArea;
|
||||
updateDockAreaFocusStyle(FocusedArea, true);
|
||||
QObject::connect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
|
||||
}
|
||||
|
||||
|
||||
auto NewFloatingWidget = FocusedDockWidget->dockContainer()->floatingWidget();
|
||||
if (NewFloatingWidget)
|
||||
{
|
||||
NewFloatingWidget->setProperty("FocusedDockWidget", QVariant::fromValue(DockWidget));
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// This code is required for styling the floating widget titlebar for linux
|
||||
// depending on the current focus state
|
||||
if (FloatingWidget == NewFloatingWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FloatingWidget)
|
||||
{
|
||||
updateFloatingWidgetFocusStyle(FloatingWidget, false);
|
||||
}
|
||||
FloatingWidget = NewFloatingWidget;
|
||||
|
||||
if (FloatingWidget)
|
||||
{
|
||||
updateFloatingWidgetFocusStyle(FloatingWidget, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (old == DockWidget && !ForceFocusChangedSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ForceFocusChangedSignal = false;
|
||||
if (DockWidget->isVisible())
|
||||
{
|
||||
emit DockManager->focusedDockWidgetChanged(old, DockWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
OldFocusedDockWidget = old;
|
||||
QObject::connect(DockWidget, SIGNAL(visibilityChanged(bool)), _this, SLOT(onDockWidgetVisibilityChanged(bool)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockFocusController::onDockWidgetVisibilityChanged(bool Visible)
|
||||
{
|
||||
auto Sender = sender();
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(Sender);
|
||||
disconnect(Sender, SIGNAL(visibilityChanged(bool)), this, SLOT(onDockWidgetVisibilityChanged(bool)));
|
||||
if (DockWidget && Visible)
|
||||
{
|
||||
emit d->DockManager->focusedDockWidgetChanged(d->OldFocusedDockWidget, DockWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockFocusController::CDockFocusController(CDockManager* DockManager) :
|
||||
Super(DockManager),
|
||||
d(new DockFocusControllerPrivate(this))
|
||||
{
|
||||
d->DockManager = DockManager;
|
||||
connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)),
|
||||
this, SLOT(onApplicationFocusChanged(QWidget*, QWidget*)));
|
||||
connect(d->DockManager, SIGNAL(stateRestored()), SLOT(onStateRestored()));
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CDockFocusController::~CDockFocusController()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidget* focusedNow)
|
||||
{
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ADS_PRINT("CDockFocusController::onApplicationFocusChanged "
|
||||
<< " old: " << focusedOld << " new: " << focusedNow);
|
||||
if (!focusedNow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the close button in another tab steals the focus from the current
|
||||
// active dock widget content, i.e. if the user clicks its close button,
|
||||
// then we immediately give the focus back to the previous focused widget
|
||||
// focusedOld
|
||||
if (CDockManager::testConfigFlag(CDockManager::AllTabsHaveCloseButton))
|
||||
{
|
||||
auto OtherDockWidgetTab = internal::findParent<CDockWidgetTab*>(focusedNow);
|
||||
if (OtherDockWidgetTab && focusedOld)
|
||||
{
|
||||
focusedOld->setFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDockWidget* DockWidget = nullptr;
|
||||
auto DockWidgetTab = qobject_cast<CDockWidgetTab*>(focusedNow);
|
||||
if (DockWidgetTab)
|
||||
{
|
||||
DockWidget = DockWidgetTab->dockWidget();
|
||||
// If the DockWidgetTab "steals" the focus from a widget in the same
|
||||
// DockWidget, then we immediately give the focus back to the previous
|
||||
// focused widget focusedOld
|
||||
if (focusedOld)
|
||||
{
|
||||
auto OldFocusedDockWidget = internal::findParent<CDockWidget*>(focusedOld);
|
||||
if (OldFocusedDockWidget && OldFocusedDockWidget == DockWidget)
|
||||
{
|
||||
focusedOld->setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DockWidget)
|
||||
{
|
||||
DockWidget = qobject_cast<CDockWidget*>(focusedNow);
|
||||
}
|
||||
|
||||
if (!DockWidget)
|
||||
{
|
||||
DockWidget = internal::findParent<CDockWidget*>(focusedNow);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!DockWidget || DockWidget->tabWidget()->isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
d->updateDockWidgetFocus(DockWidget);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockFocusController::setDockWidgetFocused(CDockWidget* focusedNow)
|
||||
{
|
||||
d->updateDockWidgetFocus(focusedNow);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockFocusController::onFocusedDockAreaViewToggled(bool Open)
|
||||
{
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(sender());
|
||||
if (!DockArea || Open)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto Container = DockArea->dockContainer();
|
||||
auto OpenedDockAreas = Container->openedDockAreas();
|
||||
if (OpenedDockAreas.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CDockManager::setWidgetFocus(OpenedDockAreas[0]->currentDockWidget()->tabWidget());
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockFocusController::notifyWidgetOrAreaRelocation(QWidget* DroppedWidget)
|
||||
{
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(DroppedWidget);
|
||||
if (!DockWidget)
|
||||
{
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(DroppedWidget);
|
||||
if (DockArea)
|
||||
{
|
||||
DockWidget = DockArea->currentDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->ForceFocusChangedSignal = true;
|
||||
CDockManager::setWidgetFocus(DockWidget->tabWidget());
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockFocusController::notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget)
|
||||
{
|
||||
if (!FloatingWidget || d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto vDockWidget = FloatingWidget->property("FocusedDockWidget");
|
||||
if (!vDockWidget.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockWidget = vDockWidget.value<CDockWidget*>();
|
||||
if (DockWidget)
|
||||
{
|
||||
d->FocusedDockWidget = nullptr;
|
||||
DockWidget->dockAreaWidget()->setCurrentDockWidget(DockWidget);
|
||||
CDockManager::setWidgetFocus(DockWidget->tabWidget());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
void CDockFocusController::onStateRestored()
|
||||
{
|
||||
if (d->FocusedDockWidget)
|
||||
{
|
||||
updateDockWidgetFocusStyle(d->FocusedDockWidget, false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// EOF DockFocusController.cpp
|
||||
90
src/DockFocusController.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef DockFocusControllerH
|
||||
#define DockFocusControllerH
|
||||
//============================================================================
|
||||
/// \file DockFocusController.h
|
||||
/// \author Uwe Kindler
|
||||
/// \date 05.06.2020
|
||||
/// \brief Declaration of CDockFocusController class
|
||||
//============================================================================
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QObject>
|
||||
#include "ads_globals.h"
|
||||
#include "DockManager.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
struct DockFocusControllerPrivate;
|
||||
class CDockManager;
|
||||
class CFloatingDockContainer;
|
||||
|
||||
/**
|
||||
* Manages focus styling of dock widgets and handling of focus changes
|
||||
*/
|
||||
class ADS_EXPORT CDockFocusController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
DockFocusControllerPrivate* d; ///< private data (pimpl)
|
||||
friend struct DockFocusControllerPrivate;
|
||||
|
||||
private slots:
|
||||
void onApplicationFocusChanged(QWidget *old, QWidget *now);
|
||||
void onFocusedDockAreaViewToggled(bool Open);
|
||||
void onStateRestored();
|
||||
void onDockWidgetVisibilityChanged(bool Visible);
|
||||
|
||||
public:
|
||||
using Super = QObject;
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
CDockFocusController(CDockManager* DockManager);
|
||||
|
||||
/**
|
||||
* Virtual Destructor
|
||||
*/
|
||||
virtual ~CDockFocusController();
|
||||
|
||||
/**
|
||||
* Helper function to set focus depending on the configuration of the
|
||||
* FocusStyling flag
|
||||
*/
|
||||
template <class QWidgetPtr>
|
||||
static void setWidgetFocus(QWidgetPtr widget)
|
||||
{
|
||||
if (!CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
widget->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* A container needs to call this function if a widget has been dropped
|
||||
* into it
|
||||
*/
|
||||
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if a floating widget has been dropped into
|
||||
* an new position.
|
||||
* When this function is called, all dock widgets of the FloatingWidget
|
||||
* are already inserted into its new position
|
||||
*/
|
||||
void notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Request a focus change to the given dock widget
|
||||
*/
|
||||
void setDockWidgetFocused(CDockWidget* focusedNow);
|
||||
}; // class DockFocusController
|
||||
}
|
||||
// namespace ads
|
||||
//-----------------------------------------------------------------------------
|
||||
#endif // DockFocusControllerH
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
#include "DockAreaWidget.h"
|
||||
#include "IconProvider.h"
|
||||
#include "DockingStateReader.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
#include "DockFocusController.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@@ -60,7 +66,7 @@
|
||||
* name. Normally, when resources are built as part of the application, the
|
||||
* resources are loaded automatically at startup. The Q_INIT_RESOURCE() macro
|
||||
* is necessary on some platforms for resources stored in a static library.
|
||||
* Because GCC caues a linker error if we put Q_INIT_RESOURCE into the
|
||||
* Because GCC causes a linker error if we put Q_INIT_RESOURCE into the
|
||||
* loadStyleSheet() function, we place it into a function outside of the ads
|
||||
* namespace
|
||||
*/
|
||||
@@ -72,6 +78,16 @@ static void initResource()
|
||||
|
||||
namespace ads
|
||||
{
|
||||
/**
|
||||
* Internal file version in case the structure changes internally
|
||||
*/
|
||||
enum eStateFileVersion
|
||||
{
|
||||
InitialVersion = 0, //!< InitialVersion
|
||||
Version1 = 1, //!< Version1
|
||||
CurrentVersion = Version1//!< CurrentVersion
|
||||
};
|
||||
|
||||
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
|
||||
|
||||
/**
|
||||
@@ -91,6 +107,7 @@ struct DockManagerPrivate
|
||||
CDockManager::eViewMenuInsertionOrder MenuInsertionOrder = CDockManager::MenuAlphabeticallySorted;
|
||||
bool RestoringState = false;
|
||||
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
|
||||
CDockFocusController* FocusController = nullptr;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -164,11 +181,14 @@ void DockManagerPrivate::loadStylesheet()
|
||||
{
|
||||
initResource();
|
||||
QString Result;
|
||||
QString FileName = ":ads/stylesheets/";
|
||||
FileName += CDockManager::testConfigFlag(CDockManager::FocusHighlighting)
|
||||
? "focus_highlighting" : "default";
|
||||
#ifdef Q_OS_LINUX
|
||||
QFile StyleSheetFile(":ads/stylesheets/default_linux.css");
|
||||
#else
|
||||
QFile StyleSheetFile(":ads/stylesheets/default.css");
|
||||
FileName += "_linux";
|
||||
#endif
|
||||
FileName += ".css";
|
||||
QFile StyleSheetFile(FileName);
|
||||
StyleSheetFile.open(QIODevice::ReadOnly);
|
||||
QTextStream StyleSheetStream(&StyleSheetFile);
|
||||
Result = StyleSheetStream.readAll();
|
||||
@@ -239,8 +259,20 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s.setFileVersion(v);
|
||||
|
||||
ADS_PRINT(s.attributes().value("UserVersion"));
|
||||
// Older files do not support UserVersion but we still want to load them so
|
||||
// we first test if the attribute exists
|
||||
if (!s.attributes().value("UserVersion").isEmpty())
|
||||
{
|
||||
v = s.attributes().value("UserVersion").toInt(&ok);
|
||||
if (!ok || v != version)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Result = true;
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
int DockContainers = s.attributes().value("Containers").toInt();
|
||||
@@ -437,6 +469,11 @@ CDockManager::CDockManager(QWidget *parent) :
|
||||
d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay);
|
||||
d->Containers.append(this);
|
||||
d->loadStylesheet();
|
||||
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
d->FocusController = new CDockFocusController(this);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -528,7 +565,8 @@ QByteArray CDockManager::saveState(int version) const
|
||||
s.setAutoFormatting(ConfigFlags.testFlag(XmlAutoFormattingEnabled));
|
||||
s.writeStartDocument();
|
||||
s.writeStartElement("QtAdvancedDockingSystem");
|
||||
s.writeAttribute("Version", QString::number(version));
|
||||
s.writeAttribute("Version", QString::number(CurrentVersion));
|
||||
s.writeAttribute("UserVersion", QString::number(version));
|
||||
s.writeAttribute("Containers", QString::number(d->Containers.count()));
|
||||
for (auto Container : d->Containers)
|
||||
{
|
||||
@@ -570,12 +608,11 @@ bool CDockManager::restoreState(const QByteArray &state, int version)
|
||||
emit restoringState();
|
||||
bool Result = d->restoreState(state, version);
|
||||
d->RestoringState = false;
|
||||
emit stateRestored();
|
||||
if (!IsHidden)
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
emit stateRestored();
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -671,6 +708,7 @@ void CDockManager::removeDockWidget(CDockWidget* Dockwidget)
|
||||
emit dockWidgetAboutToBeRemoved(Dockwidget);
|
||||
d->DockWidgetsMap.remove(Dockwidget->objectName());
|
||||
CDockContainerWidget::removeDockWidget(Dockwidget);
|
||||
Dockwidget->setDockManager(nullptr);
|
||||
emit dockWidgetRemoved(Dockwidget);
|
||||
}
|
||||
|
||||
@@ -872,6 +910,36 @@ CIconProvider& CDockManager::iconProvider()
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockManager::notifyWidgetOrAreaRelocation(QWidget* DroppedWidget)
|
||||
{
|
||||
if (d->FocusController)
|
||||
{
|
||||
d->FocusController->notifyWidgetOrAreaRelocation(DroppedWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockManager::notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget)
|
||||
{
|
||||
if (d->FocusController)
|
||||
{
|
||||
d->FocusController->notifyFloatingWidgetDrop(FloatingWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockManager::setDockWidgetFocused(CDockWidget* DockWidget)
|
||||
{
|
||||
if (d->FocusController)
|
||||
{
|
||||
d->FocusController->setDockWidgetFocused(DockWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
friend struct FloatingDragPreviewPrivate;
|
||||
friend class CDockAreaTitleBar;
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Registers the given floating widget in the internal list of
|
||||
@@ -118,6 +119,22 @@ protected:
|
||||
*/
|
||||
CDockOverlay* dockAreaOverlay() const;
|
||||
|
||||
|
||||
/**
|
||||
* A container needs to call this function if a widget has been dropped
|
||||
* into it
|
||||
*/
|
||||
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if a floating widget has been dropped into
|
||||
* an new position.
|
||||
* When this function is called, all dock widgets of the FloatingWidget
|
||||
* are already inserted into its new position
|
||||
*/
|
||||
void notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget);
|
||||
|
||||
|
||||
/**
|
||||
* Show the floating widgets that has been created floating
|
||||
*/
|
||||
@@ -161,7 +178,8 @@ public:
|
||||
FloatingContainerHasWidgetIcon = 0x80000, //!< If set, the Floating Widget icon reflects the icon of the current dock widget otherwise it displays application icon
|
||||
HideSingleCentralWidgetTitleBar = 0x100000, //!< If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden
|
||||
//!< this only makes sense for non draggable and non floatable widgets and enables the creation of some kind of "central" widget
|
||||
|
||||
FocusHighlighting = 0x200000, //!< enables styling of focused dock widget tabs or floating widget titlebar
|
||||
EqualSplitOnInsertion = 0x400000, ///!< if enabled, the space is equally distributed to all widgets in a splitter
|
||||
|
||||
DefaultDockAreaButtons = DockAreaHasCloseButton
|
||||
| DockAreaHasUndockButton
|
||||
@@ -308,8 +326,12 @@ public:
|
||||
* If auto formatting is enabled, the output is intended and line wrapped.
|
||||
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
||||
* a more compact XML output - i.e. for storage in ini files.
|
||||
* The version number is stored as part of the data.
|
||||
* To restore the saved state, pass the return value and version number
|
||||
* to restoreState().
|
||||
* \see restoreState()
|
||||
*/
|
||||
QByteArray saveState(int version = Version1) const;
|
||||
QByteArray saveState(int version = 0) const;
|
||||
|
||||
/**
|
||||
* Restores the state of this dockmanagers dockwidgets.
|
||||
@@ -317,8 +339,9 @@ public:
|
||||
* not match, the dockmanager's state is left unchanged, and this function
|
||||
* returns false; otherwise, the state is restored, and this function
|
||||
* returns true.
|
||||
* \see saveState()
|
||||
*/
|
||||
bool restoreState(const QByteArray &state, int version = Version1);
|
||||
bool restoreState(const QByteArray &state, int version = 0);
|
||||
|
||||
/**
|
||||
* Saves the current perspective to the internal list of perspectives.
|
||||
@@ -405,12 +428,34 @@ public:
|
||||
*/
|
||||
static int startDragDistance();
|
||||
|
||||
/**
|
||||
* Helper function to set focus depending on the configuration of the
|
||||
* FocusStyling flag
|
||||
*/
|
||||
template <class QWidgetPtr>
|
||||
static void setWidgetFocus(QWidgetPtr widget)
|
||||
{
|
||||
if (!CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
widget->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Opens the perspective with the given name.
|
||||
*/
|
||||
void openPerspective(const QString& PerspectiveName);
|
||||
|
||||
/**
|
||||
* Request a focus change to the given dock widget.
|
||||
* This function only has an effect, if the flag CDockManager::FocusStyling
|
||||
* is enabled
|
||||
*/
|
||||
void setDockWidgetFocused(CDockWidget* DockWidget);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted if the list of perspectives changed
|
||||
@@ -479,6 +524,13 @@ signals:
|
||||
* docking system but it is not deleted yet.
|
||||
*/
|
||||
void dockWidgetRemoved(CDockWidget* DockWidget);
|
||||
|
||||
/**
|
||||
* This signal is emitted if the focused dock widget changed.
|
||||
* Both old and now can be nullptr.
|
||||
* The focused dock widget is the one that is highlighted in the GUI
|
||||
*/
|
||||
void focusedDockWidgetChanged(CDockWidget* old, CDockWidget* now);
|
||||
}; // class DockManager
|
||||
} // namespace ads
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -134,6 +134,7 @@ void DockWidgetPrivate::showDockWidget()
|
||||
{
|
||||
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
|
||||
FloatingWidget->resize(_this->size());
|
||||
TabWidget->show();
|
||||
FloatingWidget->show();
|
||||
}
|
||||
else
|
||||
@@ -235,6 +236,11 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
||||
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
||||
SLOT(toggleView(bool)));
|
||||
setToolbarFloatingStyle(false);
|
||||
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -152,7 +152,8 @@ public:
|
||||
DockWidgetFloatable = 0x04,
|
||||
DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed
|
||||
CustomCloseHandling = 0x10,
|
||||
DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable,
|
||||
DockWidgetFocusable = 0x20,
|
||||
DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable,
|
||||
AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
|
||||
NoDockWidgetFeatures = 0x00
|
||||
};
|
||||
|
||||
@@ -114,7 +114,7 @@ struct DockWidgetTabPrivate
|
||||
*/
|
||||
bool testConfigFlag(CDockManager::eConfigFlag Flag) const
|
||||
{
|
||||
return CDockManager::configFlags().testFlag(Flag);
|
||||
return CDockManager::testConfigFlag(Flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,6 +160,7 @@ struct DockWidgetTabPrivate
|
||||
GlobalDragStartMousePosition = GlobalPos;
|
||||
DragStartMousePosition = _this->mapFromGlobal(GlobalPos);
|
||||
}
|
||||
|
||||
};
|
||||
// struct DockWidgetTabPrivate
|
||||
|
||||
@@ -242,7 +243,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
ADS_PRINT("startFloating");
|
||||
DragState = DraggingState;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
|
||||
bool OpaqueUndocking = CDockManager::testConfigFlag(CDockManager::OpaqueUndocking) ||
|
||||
(DraggingFloatingWidget != DraggingState);
|
||||
|
||||
// If section widget has multiple tabs, we take only one tab
|
||||
@@ -284,6 +285,10 @@ CDockWidgetTab::CDockWidgetTab(CDockWidget* DockWidget, QWidget *parent) :
|
||||
setAttribute(Qt::WA_NoMousePropagation, true);
|
||||
d->DockWidget = DockWidget;
|
||||
d->createLayout();
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -394,7 +399,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
// If we undock, we need to restore the initial position of this
|
||||
// tab because it looks strange if it remains on its dragged position
|
||||
if (d->isDraggingState(DraggingTab) && !CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking))
|
||||
if (d->isDraggingState(DraggingTab) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking))
|
||||
{
|
||||
parentWidget()->layout()->update();
|
||||
}
|
||||
@@ -461,16 +466,33 @@ void CDockWidgetTab::setActiveTab(bool active)
|
||||
bool AllTabsHaveCloseButton = d->testConfigFlag(CDockManager::AllTabsHaveCloseButton);
|
||||
bool TabHasCloseButton = (ActiveTabHasCloseButton && active) | AllTabsHaveCloseButton;
|
||||
d->CloseButton->setVisible(DockWidgetClosable && TabHasCloseButton);
|
||||
if (d->IsActiveTab == active)
|
||||
|
||||
// Focus related stuff
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting) && !d->DockWidget->dockManager()->isRestoringState())
|
||||
{
|
||||
bool UpdateFocusStyle = false;
|
||||
if (active && !hasFocus())
|
||||
{
|
||||
setFocus(Qt::OtherFocusReason);
|
||||
UpdateFocusStyle = true;
|
||||
}
|
||||
|
||||
if (d->IsActiveTab == active)
|
||||
{
|
||||
if (UpdateFocusStyle)
|
||||
{
|
||||
updateStyle();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (d->IsActiveTab == active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->IsActiveTab = active;
|
||||
style()->unpolish(this);
|
||||
style()->polish(this);
|
||||
d->TitleLabel->style()->unpolish(d->TitleLabel);
|
||||
d->TitleLabel->style()->polish(d->TitleLabel);
|
||||
updateStyle();
|
||||
update();
|
||||
updateGeometry();
|
||||
|
||||
@@ -641,6 +663,13 @@ void CDockWidgetTab::setElideMode(Qt::TextElideMode mode)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidgetTab::updateStyle()
|
||||
{
|
||||
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace ads
|
||||
class CDockWidget;
|
||||
class CDockAreaWidget;
|
||||
struct DockWidgetTabPrivate;
|
||||
class CDockManager;
|
||||
|
||||
/**
|
||||
* A dock widget tab that shows a title and an icon.
|
||||
@@ -54,6 +55,7 @@ private:
|
||||
DockWidgetTabPrivate* d; ///< private data (pimpl)
|
||||
friend struct DockWidgetTabPrivate;
|
||||
friend class CDockWidget;
|
||||
friend class CDockManager;
|
||||
void onDockWidgetFeaturesChanged();
|
||||
|
||||
private slots:
|
||||
@@ -152,6 +154,10 @@ public:
|
||||
*/
|
||||
void setElideMode(Qt::TextElideMode mode);
|
||||
|
||||
/**
|
||||
* Update stylesheet style if a property changes
|
||||
*/
|
||||
void updateStyle();
|
||||
|
||||
public slots:
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
@@ -391,7 +391,7 @@ struct FloatingDockContainerPrivate
|
||||
*/
|
||||
static bool testConfigFlag(CDockManager::eConfigFlag Flag)
|
||||
{
|
||||
return CDockManager::configFlags().testFlag(Flag);
|
||||
return CDockManager::testConfigFlag(Flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -637,6 +637,8 @@ CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget *DockArea) :
|
||||
{
|
||||
TopLevelDockWidget->emitTopLevelChanged(true);
|
||||
}
|
||||
|
||||
d->DockManager->notifyWidgetOrAreaRelocation(DockArea);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -652,6 +654,8 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
|
||||
{
|
||||
TopLevelDockWidget->emitTopLevelChanged(true);
|
||||
}
|
||||
|
||||
d->DockManager->notifyWidgetOrAreaRelocation(DockWidget);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -800,10 +804,17 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
d->Hiding = false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::showEvent(QShowEvent *event)
|
||||
{
|
||||
Super::showEvent(event);
|
||||
#ifdef Q_OS_LINUX
|
||||
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
|
||||
{
|
||||
this->window()->activateWindow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -978,6 +989,109 @@ void CFloatingDockContainer::finishDragging()
|
||||
d->titleMouseReleaseEvent();
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::event(QEvent *e)
|
||||
{
|
||||
switch (d->DraggingState)
|
||||
{
|
||||
case DraggingInactive:
|
||||
{
|
||||
// Normally we would check here, if the left mouse button is pressed.
|
||||
// But from QT version 5.12.2 on the mouse events from
|
||||
// QEvent::NonClientAreaMouseButtonPress return the wrong mouse button
|
||||
// The event always returns Qt::RightButton even if the left button
|
||||
// is clicked.
|
||||
// It is really great to work around the whole NonClientMouseArea
|
||||
// bugs
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
||||
#else
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
||||
#endif
|
||||
{
|
||||
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
||||
d->DragStartPos = pos();
|
||||
d->setState(DraggingMousePressed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DraggingMousePressed:
|
||||
switch (e->type())
|
||||
{
|
||||
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||
ADS_PRINT("FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick");
|
||||
d->setState(DraggingInactive);
|
||||
break;
|
||||
|
||||
case QEvent::Resize:
|
||||
// If the first event after the mouse press is a resize event, then
|
||||
// the user resizes the window instead of dragging it around.
|
||||
// But there is one exception. If the window is maximized,
|
||||
// then dragging the window via title bar will cause the widget to
|
||||
// leave the maximized state. This in turn will trigger a resize event.
|
||||
// To know, if the resize event was triggered by user via moving a
|
||||
// corner of the window frame or if it was caused by a windows state
|
||||
// change, we check, if we are not in maximized state.
|
||||
if (!isMaximized())
|
||||
{
|
||||
d->setState(DraggingInactive);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||
{
|
||||
ADS_PRINT("FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease");
|
||||
d->titleMouseReleaseEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if (ADS_DEBUG_LEVEL > 0)
|
||||
qDebug() << QTime::currentTime() << "CFloatingDockContainer::event " << e->type();
|
||||
#endif
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
QWidget::moveEvent(event);
|
||||
switch (d->DraggingState)
|
||||
{
|
||||
case DraggingMousePressed:
|
||||
d->setState(DraggingFloatingWidget);
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
// In OSX when hiding the DockAreaOverlay the application would set
|
||||
// the main window as the active window for some reason. This fixes
|
||||
// that by resetting the active window to the floating widget after
|
||||
// updating the overlays.
|
||||
QApplication::setActiveWindow(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -172,8 +172,7 @@ protected:
|
||||
/**
|
||||
* Call this function to update the window title
|
||||
*/
|
||||
void updateWindowTitle();
|
||||
|
||||
void updateWindowTitle();
|
||||
|
||||
protected: // reimplements QWidget
|
||||
virtual void changeEvent(QEvent *event) override;
|
||||
@@ -181,6 +180,11 @@ protected: // reimplements QWidget
|
||||
virtual void hideEvent(QHideEvent *event) override;
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
virtual bool event(QEvent *e) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
/**
|
||||
* Native event filter for handling WM_MOVING messages on Windows
|
||||
|
||||
@@ -112,7 +112,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
DockAreaOverlay->hideOverlay();
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewIsDynamic))
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewIsDynamic))
|
||||
{
|
||||
setHidden(false);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
// If there is only one single visible dock area in a container, then
|
||||
// it does not make sense to show a dock overlay because the dock area
|
||||
// would be removed and inserted at the same position
|
||||
if (VisibleDockAreas <= 1)
|
||||
if (VisibleDockAreas == 1)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
}
|
||||
@@ -167,7 +167,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
}
|
||||
}
|
||||
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewIsDynamic))
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewIsDynamic))
|
||||
{
|
||||
setHidden(DockDropArea != InvalidDockWidgetArea || ContainerDropArea != InvalidDockWidgetArea);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ void FloatingDragPreviewPrivate::createFloatingWidget()
|
||||
{
|
||||
FloatingWidget->setGeometry(_this->geometry());
|
||||
FloatingWidget->show();
|
||||
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
if (!CDockManager::testConfigFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
{
|
||||
QApplication::processEvents();
|
||||
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
|
||||
@@ -222,7 +222,7 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
{
|
||||
d->Content = Content;
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
{
|
||||
setWindowFlags(
|
||||
Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
@@ -245,7 +245,7 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
// Create a static image of the widget that should get undocked
|
||||
// This is like some kind preview image like it is uses in drag and drop
|
||||
// operations
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
{
|
||||
d->ContentPreviewPixmap = QPixmap(Content->size());
|
||||
Content->render(&d->ContentPreviewPixmap);
|
||||
@@ -363,14 +363,14 @@ void CFloatingDragPreview::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
{
|
||||
painter.drawPixmap(QPoint(0, 0), d->ContentPreviewPixmap);
|
||||
}
|
||||
|
||||
// If we do not have a window frame then we paint a QRubberBand like
|
||||
// frameless window
|
||||
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
if (!CDockManager::testConfigFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
{
|
||||
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
QPen Pen = painter.pen();
|
||||
|
||||
@@ -4,5 +4,11 @@
|
||||
<file>images/close-button.svg</file>
|
||||
<file>images/close-button-disabled.svg</file>
|
||||
<file>stylesheets/default_linux.css</file>
|
||||
<file>images/close-button-focused.svg</file>
|
||||
<file>stylesheets/focus_highlighting.css</file>
|
||||
<file>stylesheets/focus_highlighting_linux.css</file>
|
||||
<file>images/tabs-menu-button.svg</file>
|
||||
<file>images/detach-button.svg</file>
|
||||
<file>images/detach-button-disabled.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QVariant>
|
||||
#include <QPainter>
|
||||
#include <QAbstractButton>
|
||||
#include <QStyle>
|
||||
|
||||
#include "DockSplitter.h"
|
||||
#include "DockManager.h"
|
||||
@@ -118,6 +119,31 @@ void setButtonIcon(QAbstractButton* Button, QStyle::StandardPixmap StandarPixmap
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void repolishStyle(QWidget* w, eRepolishChildOptions Options)
|
||||
{
|
||||
if (!w)
|
||||
{
|
||||
return;
|
||||
}
|
||||
w->style()->unpolish(w);
|
||||
w->style()->polish(w);
|
||||
|
||||
if (RepolishIgnoreChildren == Options)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QWidget*> Children = w->findChildren<QWidget*>(QString(),
|
||||
(RepolishDirectChildren == Options) ? Qt::FindDirectChildrenOnly: Qt::FindChildrenRecursively);
|
||||
for (auto Widget : Children)
|
||||
{
|
||||
Widget->style()->unpolish(Widget);
|
||||
Widget->style()->polish(Widget);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ads
|
||||
|
||||
|
||||
@@ -64,13 +64,6 @@ QT_FORWARD_DECLARE_CLASS(QSplitter)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
enum eStateFileVersion
|
||||
{
|
||||
InitialVersion = 0,
|
||||
Version1 = 1,
|
||||
CurrentVersion = Version1
|
||||
};
|
||||
|
||||
class CDockSplitter;
|
||||
|
||||
enum DockWidgetArea
|
||||
@@ -251,6 +244,21 @@ void setToolTip(QObjectPtr obj, const QString &tip)
|
||||
void setButtonIcon(QAbstractButton* Button, QStyle::StandardPixmap StandarPixmap,
|
||||
ads::eIcon CustomIconId);
|
||||
|
||||
|
||||
enum eRepolishChildOptions
|
||||
{
|
||||
RepolishIgnoreChildren,
|
||||
RepolishDirectChildren,
|
||||
RepolishChildrenRecursively
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls unpolish() / polish for the style of the given widget to update
|
||||
* stylesheet if a property changes
|
||||
*/
|
||||
void repolishStyle(QWidget* w, eRepolishChildOptions Options = RepolishIgnoreChildren);
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ads
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
@@ -9,114 +7,133 @@
|
||||
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"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="close-button-disabled.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata897"><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="defs895" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview893"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="0.85862966"
|
||||
inkscape:cx="345.29142"
|
||||
inkscape:cy="32.731258"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
<g
|
||||
id="g860"
|
||||
transform="matrix(0.71708683,0,0,0.71708683,128,128)"
|
||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081">
|
||||
<g
|
||||
id="close"
|
||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081">
|
||||
<polygon
|
||||
points="357,321.3 214.2,178.5 357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 "
|
||||
id="polygon857"
|
||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g862"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g864"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g866"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g868"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g870"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g872"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g874"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g876"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g878"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g880"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g882"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g884"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g886"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g888"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g890"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
</svg>
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
viewBox="0 0 16 16"
|
||||
height="16px"
|
||||
width="16px">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
id="EMFhbasepattern"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-4"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-3"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-8"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:guide-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-width="1920"
|
||||
units="px"
|
||||
showgrid="true"
|
||||
inkscape:current-layer="g5228"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.17691"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base">
|
||||
<inkscape:grid
|
||||
id="grid3336"
|
||||
type="xygrid" />
|
||||
<sodipodi:guide
|
||||
id="guide883"
|
||||
orientation="1,0"
|
||||
position="4,10" />
|
||||
<sodipodi:guide
|
||||
id="guide885"
|
||||
orientation="0,-1"
|
||||
position="10,12" />
|
||||
<sodipodi:guide
|
||||
id="guide887"
|
||||
orientation="1,0"
|
||||
position="12,2" />
|
||||
<sodipodi:guide
|
||||
id="guide889"
|
||||
orientation="0,-1"
|
||||
position="14,4" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
transform="translate(0,-1036.3622)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
id="g5228"
|
||||
transform="translate(628,-140.49998)">
|
||||
<path
|
||||
id="path846"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#a0a0a0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1;opacity:1"
|
||||
d="M 4.4765625 4.0019531 A 0.5 0.5 0 0 0 4.1464844 4.1464844 A 0.5 0.5 0 0 0 4.1464844 4.8535156 L 7.2929688 8 L 4.1464844 11.146484 A 0.5 0.5 0 0 0 4.1464844 11.853516 A 0.5 0.5 0 0 0 4.8535156 11.853516 L 8 8.7070312 L 11.146484 11.853516 A 0.5 0.5 0 0 0 11.853516 11.853516 A 0.5 0.5 0 0 0 11.853516 11.146484 L 8.7070312 8 L 11.853516 4.8535156 A 0.5 0.5 0 0 0 11.853516 4.1464844 A 0.5 0.5 0 0 0 11.476562 4.0019531 A 0.5 0.5 0 0 0 11.146484 4.1464844 L 8 7.2929688 L 4.8535156 4.1464844 A 0.5 0.5 0 0 0 4.4765625 4.0019531 z "
|
||||
transform="translate(-628,1176.8622)" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
dc:language="en"
|
||||
dc:format="image/svg+xml"
|
||||
dc:date="2016-12-14"
|
||||
dc:publisher="Iconscout"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
about="https://iconscout.com/legal#licenses">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 5.4 KiB |
139
src/images/close-button-focused.svg
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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"
|
||||
sodipodi:docname="close-button-focused.svg"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
viewBox="0 0 16 16"
|
||||
height="16px"
|
||||
width="16px">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
id="EMFhbasepattern"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-4"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-3"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-8"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:guide-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-width="1920"
|
||||
units="px"
|
||||
showgrid="true"
|
||||
inkscape:current-layer="g5228"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.17691"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base">
|
||||
<inkscape:grid
|
||||
id="grid3336"
|
||||
type="xygrid" />
|
||||
<sodipodi:guide
|
||||
id="guide883"
|
||||
orientation="1,0"
|
||||
position="4,10" />
|
||||
<sodipodi:guide
|
||||
id="guide885"
|
||||
orientation="0,-1"
|
||||
position="10,12" />
|
||||
<sodipodi:guide
|
||||
id="guide887"
|
||||
orientation="1,0"
|
||||
position="12,2" />
|
||||
<sodipodi:guide
|
||||
id="guide889"
|
||||
orientation="0,-1"
|
||||
position="14,4" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
transform="translate(0,-1036.3622)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
id="g5228"
|
||||
transform="translate(628,-140.49998)">
|
||||
<path
|
||||
id="path846"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1;opacity:1"
|
||||
d="M 4.4765625 4.0019531 A 0.5 0.5 0 0 0 4.1464844 4.1464844 A 0.5 0.5 0 0 0 4.1464844 4.8535156 L 7.2929688 8 L 4.1464844 11.146484 A 0.5 0.5 0 0 0 4.1464844 11.853516 A 0.5 0.5 0 0 0 4.8535156 11.853516 L 8 8.7070312 L 11.146484 11.853516 A 0.5 0.5 0 0 0 11.853516 11.853516 A 0.5 0.5 0 0 0 11.853516 11.146484 L 8.7070312 8 L 11.853516 4.8535156 A 0.5 0.5 0 0 0 11.853516 4.1464844 A 0.5 0.5 0 0 0 11.476562 4.0019531 A 0.5 0.5 0 0 0 11.146484 4.1464844 L 8 7.2929688 L 4.8535156 4.1464844 A 0.5 0.5 0 0 0 4.4765625 4.0019531 z "
|
||||
transform="translate(-628,1176.8622)" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
dc:language="en"
|
||||
dc:format="image/svg+xml"
|
||||
dc:date="2016-12-14"
|
||||
dc:publisher="Iconscout"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
about="https://iconscout.com/legal#licenses">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
@@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
@@ -9,111 +7,133 @@
|
||||
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="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="close-button.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata897"><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="defs895" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview893"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="0.85862966"
|
||||
inkscape:cx="345.29142"
|
||||
inkscape:cy="32.731258"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
<g
|
||||
id="g860"
|
||||
transform="matrix(0.71708683,0,0,0.71708683,128,128)">
|
||||
<g
|
||||
id="close">
|
||||
<polygon
|
||||
points="357,321.3 214.2,178.5 357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 "
|
||||
id="polygon857" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g862"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g864"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g866"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g868"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g870"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g872"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g874"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g876"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g878"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g880"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g882"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g884"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g886"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g888"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
<g
|
||||
id="g890"
|
||||
transform="translate(0,155)">
|
||||
</g>
|
||||
</svg>
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
sodipodi:docname="close-button2.svg">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:cy="13.17691"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5228"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:document-rotation="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3336" />
|
||||
<sodipodi:guide
|
||||
position="4,10"
|
||||
orientation="1,0"
|
||||
id="guide883" />
|
||||
<sodipodi:guide
|
||||
position="10,12"
|
||||
orientation="0,-1"
|
||||
id="guide885" />
|
||||
<sodipodi:guide
|
||||
position="12,2"
|
||||
orientation="1,0"
|
||||
id="guide887" />
|
||||
<sodipodi:guide
|
||||
position="14,4"
|
||||
orientation="0,-1"
|
||||
id="guide889" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
transform="translate(628,-140.49998)"
|
||||
id="g5228">
|
||||
<path
|
||||
transform="translate(-628,1176.8622)"
|
||||
d="M 4.4765625 4.0019531 A 0.5 0.5 0 0 0 4.1464844 4.1464844 A 0.5 0.5 0 0 0 4.1464844 4.8535156 L 7.2929688 8 L 4.1464844 11.146484 A 0.5 0.5 0 0 0 4.1464844 11.853516 A 0.5 0.5 0 0 0 4.8535156 11.853516 L 8 8.7070312 L 11.146484 11.853516 A 0.5 0.5 0 0 0 11.853516 11.853516 A 0.5 0.5 0 0 0 11.853516 11.146484 L 8.7070312 8 L 11.853516 4.8535156 A 0.5 0.5 0 0 0 11.853516 4.1464844 A 0.5 0.5 0 0 0 11.476562 4.0019531 A 0.5 0.5 0 0 0 11.146484 4.1464844 L 8 7.2929688 L 4.8535156 4.1464844 A 0.5 0.5 0 0 0 4.4765625 4.0019531 z "
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1;opacity:1"
|
||||
id="path846" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
about="https://iconscout.com/legal#licenses"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:publisher="Iconscout"
|
||||
dc:date="2016-12-14"
|
||||
dc:format="image/svg+xml"
|
||||
dc:language="en">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 5.4 KiB |
205
src/images/detach-button-disabled.svg
Normal file
@@ -0,0 +1,205 @@
|
||||
<?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="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
sodipodi:docname="detach-button-disabled.svg">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-2" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-9" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4-8" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3-7" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8-0" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-41" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4-5" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3-0" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8-2" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:cy="12.734968"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5228"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:document-rotation="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3336" />
|
||||
<sodipodi:guide
|
||||
position="4,10"
|
||||
orientation="1,0"
|
||||
id="guide883" />
|
||||
<sodipodi:guide
|
||||
position="10,12"
|
||||
orientation="0,-1"
|
||||
id="guide885" />
|
||||
<sodipodi:guide
|
||||
position="12,2"
|
||||
orientation="1,0"
|
||||
id="guide887" />
|
||||
<sodipodi:guide
|
||||
position="14,4"
|
||||
orientation="0,-1"
|
||||
id="guide889" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
transform="translate(628,-140.49998)"
|
||||
id="g5228">
|
||||
<path
|
||||
id="path893"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#a0a0a0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:9.2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="m -622,1179.8622 v 0.5 1.5 1 h -2 v 0.5 1.5 4 h 6 v -3 h 2 v -4 -2 z m 1,2 h 4 v 3 h -1 v -2 h -3 z m -2,3 h 4 v 3 h -4 z" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
about="https://iconscout.com/legal#licenses"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:publisher="Iconscout"
|
||||
dc:date="2016-12-14"
|
||||
dc:format="image/svg+xml"
|
||||
dc:language="en">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
<style
|
||||
id="style2-3" />
|
||||
<style
|
||||
id="style2-1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
175
src/images/detach-button.svg
Normal file
@@ -0,0 +1,175 @@
|
||||
<?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="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
sodipodi:docname="detach-button.svg">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-2" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-9" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4-8" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3-7" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8-0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:cy="12.734968"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5228"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:document-rotation="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3336" />
|
||||
<sodipodi:guide
|
||||
position="4,10"
|
||||
orientation="1,0"
|
||||
id="guide883" />
|
||||
<sodipodi:guide
|
||||
position="10,12"
|
||||
orientation="0,-1"
|
||||
id="guide885" />
|
||||
<sodipodi:guide
|
||||
position="12,2"
|
||||
orientation="1,0"
|
||||
id="guide887" />
|
||||
<sodipodi:guide
|
||||
position="14,4"
|
||||
orientation="0,-1"
|
||||
id="guide889" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
transform="translate(628,-140.49998)"
|
||||
id="g5228">
|
||||
<path
|
||||
id="path893"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:9.2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="m -622,1179.8622 v 0.5 1.5 1 h -2 v 0.5 1.5 4 h 6 v -3 h 2 v -4 -2 z m 1,2 h 4 v 3 h -1 v -2 h -3 z m -2,3 h 4 v 3 h -4 z" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
about="https://iconscout.com/legal#licenses"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:publisher="Iconscout"
|
||||
dc:date="2016-12-14"
|
||||
dc:format="image/svg+xml"
|
||||
dc:language="en">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
<style
|
||||
id="style2-3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
138
src/images/tabs-menu-button.svg
Normal file
@@ -0,0 +1,138 @@
|
||||
<?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"
|
||||
sodipodi:docname="tabs-menu-button.svg"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
viewBox="0 0 16 16"
|
||||
height="16px"
|
||||
width="16px">
|
||||
<style
|
||||
id="style2"></style>
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
id="EMFhbasepattern"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-4"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-3"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
<pattern
|
||||
id="EMFhbasepattern-8"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:guide-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-width="1920"
|
||||
units="px"
|
||||
showgrid="true"
|
||||
inkscape:current-layer="g5228"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="13.17691"
|
||||
inkscape:cx="6.2316889"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base">
|
||||
<inkscape:grid
|
||||
id="grid3336"
|
||||
type="xygrid" />
|
||||
<sodipodi:guide
|
||||
id="guide883"
|
||||
orientation="1,0"
|
||||
position="4,10" />
|
||||
<sodipodi:guide
|
||||
id="guide885"
|
||||
orientation="0,-1"
|
||||
position="10,12" />
|
||||
<sodipodi:guide
|
||||
id="guide887"
|
||||
orientation="1,0"
|
||||
position="12,2" />
|
||||
<sodipodi:guide
|
||||
id="guide889"
|
||||
orientation="0,-1"
|
||||
position="14,4" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
transform="translate(0,-1036.3622)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
id="g5228"
|
||||
transform="translate(628,-140.49998)">
|
||||
<path
|
||||
id="path842"
|
||||
d="m -624,1182.8622 4,4 4,-4 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
dc:language="en"
|
||||
dc:format="image/svg+xml"
|
||||
dc:date="2016-12-14"
|
||||
dc:publisher="Iconscout"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
about="https://iconscout.com/legal#licenses">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -45,7 +45,7 @@ namespace ads
|
||||
{
|
||||
|
||||
using tTabLabel = CElidingLabel;
|
||||
using tCloseButton = QPushButton;
|
||||
using tCloseButton = QToolButton;
|
||||
|
||||
/**
|
||||
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
||||
@@ -81,7 +81,7 @@ void FloatingWidgetTitleBarPrivate::createLayout()
|
||||
|
||||
CloseButton = new tCloseButton();
|
||||
CloseButton->setObjectName("floatingTitleCloseButton");
|
||||
CloseButton->setFlat(true);
|
||||
CloseButton->setAutoRaise(true);
|
||||
|
||||
// The standard icons do does not look good on high DPI screens
|
||||
QIcon CloseIcon;
|
||||
@@ -115,7 +115,7 @@ void FloatingWidgetTitleBarPrivate::createLayout()
|
||||
|
||||
//============================================================================
|
||||
CFloatingWidgetTitleBar::CFloatingWidgetTitleBar(CFloatingDockContainer *parent) :
|
||||
QWidget(parent),
|
||||
QFrame(parent),
|
||||
d(new FloatingWidgetTitleBarPrivate(this))
|
||||
{
|
||||
d->FloatingWidget = parent;
|
||||
@@ -172,16 +172,25 @@ void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
|
||||
Super::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::enableCloseButton(bool Enable)
|
||||
{
|
||||
d->CloseButton->setEnabled(Enable);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::setTitle(const QString &Text)
|
||||
{
|
||||
d->TitleLabel->setText(Text);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::updateStyle()
|
||||
{
|
||||
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@@ -45,7 +45,7 @@ struct FloatingWidgetTitleBarPrivate;
|
||||
* for the docking system to work properly, we use our own titlebar here to
|
||||
* capture the required mouse events.
|
||||
*/
|
||||
class CFloatingWidgetTitleBar : public QWidget
|
||||
class CFloatingWidgetTitleBar : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
@@ -75,6 +75,11 @@ public:
|
||||
*/
|
||||
void setTitle(const QString &Text);
|
||||
|
||||
/**
|
||||
* Update stylesheet style if a property changes
|
||||
*/
|
||||
void updateStyle();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted, if the close button is clicked.
|
||||
|
||||
@@ -45,7 +45,8 @@ HEADERS += \
|
||||
DockAreaTitleBar.h \
|
||||
ElidingLabel.h \
|
||||
IconProvider.h \
|
||||
DockComponentsFactory.h
|
||||
DockComponentsFactory.h \
|
||||
DockFocusController.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
@@ -64,7 +65,8 @@ SOURCES += \
|
||||
DockAreaTitleBar.cpp \
|
||||
ElidingLabel.cpp \
|
||||
IconProvider.cpp \
|
||||
DockComponentsFactory.cpp
|
||||
DockComponentsFactory.cpp \
|
||||
DockFocusController.cpp
|
||||
|
||||
|
||||
unix {
|
||||
|
||||
@@ -1,94 +1,93 @@
|
||||
|
||||
/*
|
||||
* Default style sheet on Windows Platforms
|
||||
* Note: Always use CSS-classes with and without "ads--" namespace to support Qt4 & Qt5
|
||||
*/
|
||||
|
||||
ads--CDockContainerWidget
|
||||
{
|
||||
background: palette(dark);
|
||||
ads--CDockContainerWidget {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget QSplitter::handle
|
||||
{
|
||||
background: palette(dark);
|
||||
ads--CDockContainerWidget QSplitter::handle {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget
|
||||
{
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
ads--CDockAreaWidget {
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget #tabsMenuButton::menu-indicator
|
||||
{
|
||||
image: none;
|
||||
ads--CDockWidgetTab {
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
}
|
||||
|
||||
|
||||
ads--CDockWidgetTab
|
||||
{
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
ads--CDockWidgetTab[activeTab="true"] {
|
||||
background: qlineargradient(spread : pad, x1 : 0, y1 : 0, x2 : 0, y2 : 0.5, stop : 0
|
||||
palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"]
|
||||
{
|
||||
background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:0.5, stop:0 palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
ads--CDockWidgetTab QLabel {
|
||||
color: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab QLabel
|
||||
{
|
||||
color: palette(dark);
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel {
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel
|
||||
{
|
||||
color: palette(foreground);
|
||||
ads--CDockWidget {
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
ads--CDockWidget
|
||||
{
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
ads--CTitleBarButton
|
||||
{
|
||||
ads--CTitleBarButton {
|
||||
padding: 0px 0px;
|
||||
}
|
||||
|
||||
|
||||
QScrollArea#dockWidgetScrollArea
|
||||
{
|
||||
QScrollArea#dockWidgetScrollArea {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
#tabCloseButton
|
||||
{
|
||||
#tabCloseButton {
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#tabCloseButton:hover
|
||||
{
|
||||
#tabCloseButton:hover {
|
||||
border: 1px solid rgba(0, 0, 0, 32);
|
||||
background: rgba(0, 0, 0, 16);
|
||||
}
|
||||
|
||||
#tabCloseButton:pressed
|
||||
{
|
||||
#tabCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 32);
|
||||
}
|
||||
|
||||
#tabsMenuButton::menu-indicator {
|
||||
image: none;
|
||||
}
|
||||
|
||||
#tabsMenuButton {
|
||||
qproperty-icon: url(:/ads/images/tabs-menu-button.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#dockAreaCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#detachGroupButton {
|
||||
qproperty-icon: url(:/ads/images/detach-button.svg),
|
||||
url(:/ads/images/detach-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
@@ -1,96 +1,109 @@
|
||||
|
||||
/*
|
||||
* Default style sheet on Windows Platforms
|
||||
* Note: Always use CSS-classes with and without "ads--" namespace to support Qt4 & Qt5
|
||||
* Default style sheet on Linux Platforms
|
||||
*/
|
||||
|
||||
ads--CDockContainerWidget
|
||||
{
|
||||
background: palette(dark);
|
||||
ads--CDockContainerWidget {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget QSplitter::handle
|
||||
{
|
||||
background: palette(dark);
|
||||
ads--CDockContainerWidget QSplitter::handle {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget
|
||||
{
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
ads--CDockAreaWidget {
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget #tabsMenuButton::menu-indicator
|
||||
{
|
||||
image: none;
|
||||
ads--CDockAreaWidget #tabsMenuButton::menu-indicator {
|
||||
image: none;
|
||||
}
|
||||
|
||||
|
||||
ads--CDockWidgetTab
|
||||
{
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
ads--CDockWidgetTab {
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"]
|
||||
{
|
||||
background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:0.5, stop:0 palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
ads--CDockWidgetTab[activeTab="true"] {
|
||||
background: qlineargradient(spread : pad, x1 : 0, y1 : 0, x2 : 0, y2 : 0.5, stop : 0
|
||||
palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab QLabel
|
||||
{
|
||||
color: palette(dark);
|
||||
ads--CDockWidgetTab QLabel {
|
||||
color: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel
|
||||
{
|
||||
color: palette(foreground);
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel {
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
ads--CDockWidget
|
||||
{
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
ads--CDockWidget {
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
|
||||
ads--CTitleBarButton
|
||||
{
|
||||
ads--CTitleBarButton {
|
||||
padding: 0px 0px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QScrollArea#dockWidgetScrollArea
|
||||
{
|
||||
QScrollArea#dockWidgetScrollArea {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
#tabCloseButton
|
||||
{
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
#tabCloseButton {
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#tabCloseButton:hover
|
||||
{
|
||||
border: 1px solid rgba(0, 0, 0, 32);
|
||||
background: rgba(0, 0, 0, 16);
|
||||
#tabCloseButton:hover {
|
||||
border: 1px solid rgba(0, 0, 0, 32);
|
||||
background: rgba(0, 0, 0, 16);
|
||||
}
|
||||
|
||||
#tabCloseButton:pressed
|
||||
{
|
||||
background: rgba(0, 0, 0, 32);
|
||||
#tabCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 32);
|
||||
}
|
||||
|
||||
#tabsMenuButton {
|
||||
qproperty-icon: url(:/ads/images/tabs-menu-button.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#dockAreaCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#detachGroupButton {
|
||||
qproperty-icon: url(:/ads/images/detach-button.svg),
|
||||
url(:/ads/images/detach-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
border: none;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton:hover {
|
||||
background: rgba(0, 0, 0, 24);
|
||||
border: none;
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 48);
|
||||
}
|
||||
|
||||
125
src/stylesheets/focus_highlighting.css
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Default style sheet on Windows Platforms with focus highlighting flag enabled
|
||||
*/
|
||||
ads--CDockContainerWidget {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget {
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab {
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] {
|
||||
background: qlineargradient(spread : pad, x1 : 0, y1 : 0, x2 : 0, y2 : 0.5, stop : 0
|
||||
palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab QLabel {
|
||||
color: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel {
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
ads--CDockWidget {
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
ads--CTitleBarButton {
|
||||
padding: 0px 0px;
|
||||
}
|
||||
|
||||
QScrollArea#dockWidgetScrollArea {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#tabsMenuButton::menu-indicator {
|
||||
image: none;
|
||||
}
|
||||
|
||||
#tabCloseButton {
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#tabCloseButton:hover {
|
||||
/*border: 1px solid rgba(0, 0, 0, 32);*/
|
||||
background: rgba(0, 0, 0, 24);
|
||||
}
|
||||
|
||||
#tabCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 48);
|
||||
}
|
||||
|
||||
#dockAreaCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#detachGroupButton {
|
||||
qproperty-icon: url(:/ads/images/detach-button.svg),
|
||||
url(:/ads/images/detach-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
ads--CDockSplitter::handle {
|
||||
background-color: palette(dark);
|
||||
/* uncomment the following line if you would like to change the size of
|
||||
the splitter handles */
|
||||
/* height: 1px; */
|
||||
}
|
||||
|
||||
/* Focus related styling */
|
||||
ads--CDockWidgetTab[focused="true"] {
|
||||
background: palette(highlight);
|
||||
border-color: palette(highlight);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button-focused.svg)
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton:hover {
|
||||
background: rgba(255, 255, 255, 48);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton:pressed {
|
||||
background: rgba(255, 255, 255, 92);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"] QLabel {
|
||||
color: palette(light);
|
||||
}
|
||||
|
||||
ads--CDockAreaTitleBar {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid palette(light);
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid palette(highlight);
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
170
src/stylesheets/focus_highlighting_linux.css
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Default style sheet on Linux Platforms with focus highlighting flag enabled
|
||||
*/
|
||||
ads--CDockContainerWidget {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget QSplitter::handle {
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget {
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget #tabsMenuButton::menu-indicator {
|
||||
image: none;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab {
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] {
|
||||
background: qlineargradient(spread : pad, x1 : 0, y1 : 0, x2 : 0, y2 : 0.5, stop : 0
|
||||
palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab QLabel {
|
||||
color: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel {
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
ads--CDockWidget {
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
ads--CTitleBarButton {
|
||||
padding: 0px 0px;
|
||||
}
|
||||
|
||||
QScrollArea#dockWidgetScrollArea {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#dockAreaCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#detachGroupButton {
|
||||
qproperty-icon: url(:/ads/images/detach-button.svg),
|
||||
url(:/ads/images/detach-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#tabCloseButton {
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
qproperty-icon: url(:/ads/images/close-button.svg),
|
||||
url(:/ads/images/close-button-disabled.svg) disabled;
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
#tabCloseButton:hover {
|
||||
/*border: 1px solid rgba(0, 0, 0, 32);*/
|
||||
background: rgba(0, 0, 0, 24);
|
||||
}
|
||||
|
||||
#tabCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 48);
|
||||
}
|
||||
|
||||
|
||||
#tabsMenuButton {
|
||||
qproperty-icon: url(:/ads/images/tabs-menu-button.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* Focus related styling */
|
||||
ads--CDockWidgetTab[focused="true"] {
|
||||
background: palette(highlight);
|
||||
border-color: palette(highlight);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button-focused.svg)
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton:hover {
|
||||
background: rgba(255, 255, 255, 48);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"]>#tabCloseButton:pressed {
|
||||
background: rgba(255, 255, 255, 92);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[focused="true"] QLabel {
|
||||
color: palette(light);
|
||||
}
|
||||
|
||||
ads--CDockAreaTitleBar {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid palette(light);
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid palette(highlight);
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ads--CFloatingDockContainer[isActiveWindow="true"] ads--CFloatingWidgetTitleBar {
|
||||
background: palette(highlight);
|
||||
}
|
||||
|
||||
ads--CFloatingDockContainer[isActiveWindow="true"] #floatingTitleLabel {
|
||||
color: palette(light);
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
border: none;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton:hover {
|
||||
background: rgba(0, 0, 0, 24);
|
||||
border: none;
|
||||
}
|
||||
|
||||
#floatingTitleCloseButton:pressed {
|
||||
background: rgba(0, 0, 0, 48);
|
||||
}
|
||||
|
||||
|
||||
ads--CFloatingDockContainer[isActiveWindow="true"] #floatingTitleCloseButton {
|
||||
qproperty-icon: url(:/ads/images/close-button-focused.svg);
|
||||
qproperty-iconSize: 16px;
|
||||
}
|
||||
|
||||
ads--CFloatingDockContainer[isActiveWindow="true"] #floatingTitleCloseButton:hover {
|
||||
background: rgba(255, 255, 255, 48);
|
||||
}
|
||||
|
||||
|
||||
ads--CFloatingDockContainer[isActiveWindow="true"] #floatingTitleCloseButton:pressed {
|
||||
background: rgba(255, 255, 255, 92);
|
||||
}
|
||||