Compare commits

...

55 Commits
3.4.2 ... 3.5.0

Author SHA1 Message Date
Uwe Kindler
0c13402516 Added documentation for FocusHighlighting flag 2020-06-10 07:16:35 +02:00
Uwe Kindler
97e3d72566 Disabled focus highliighting in demo application 2020-06-09 22:00:46 +02:00
Uwe Kindler
682aaf66eb Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-06-09 21:58:12 +02:00
Uwe Kindler
c939df73fa Merge branch 'focused_dockwidget' 2020-06-09 21:57:23 +02:00
Uwe Kindler
fdf169ce9a Fixed docking of floating widgets for MacOS 2020-06-09 20:29:19 +02:00
githubuser0xFFFF
4b730a4949 Update README.md 2020-06-09 15:39:16 +02:00
Uwe Kindler
788c357cc0 Added missing README.md changes 2020-06-09 15:35:02 +02:00
Uwe Kindler
e3844b8d6c Added Python section to README.md 2020-06-09 15:32:00 +02:00
Uwe Kindler
ff3fcdcacd Removed debug output 2020-06-09 14:40:13 +02:00
Uwe Kindler
a9268e6bf7 Fixed build issues and improved styling
Improved styling of close buttons and focused close buttons
2020-06-07 17:28:23 +02:00
Uwe Kindler
0227bd1786 Added icon for proper styling of focused close icon 2020-06-07 17:19:07 +02:00
Uwe Kindler
227037e42a Added new close button SVG icon 2020-06-07 15:20:24 +02:00
Uwe Kindler
cd495a14ec Fixed MSVC compiler warning 2020-06-07 15:20:08 +02:00
Uwe Kindler
312a8cf500 Enabled ClickFocus for CDockWidget to support focussing in case the content does not support it
Renamed FocusStyling to FocusHighlighting
2020-06-06 14:59:03 +02:00
Uwe Kindler
2fc8bbe9c9 Added mising DockFocusController files 2020-06-05 21:03:47 +02:00
Uwe Kindler
f5c4b26aab Moved focus related functionality into CDockFocusController class to keep the dock manager code clean 2020-06-05 20:42:43 +02:00
Uwe Kindler
c4d2d72e92 Added activateWindow() call in CFloatingDockCiontainer::showEvent
This is required to properly style the floating widget that contains the currently focused widget
2020-06-05 13:40:36 +02:00
Uwe Kindler
f90f0b0427 Properly implemented focusedDockWidgetChanged() signal 2020-06-05 12:14:26 +02:00
Uwe Kindler
d360b4ced2 Merge branch 'master' into focused_dockwidget 2020-06-05 07:40:39 +02:00
Uwe Kindler
f074ea9d67 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-06-05 07:40:10 +02:00
Uwe Kindler
2e8137ad85 Fixed setting of CDockingStateReader file version - use internal file version instead of user file version 2020-06-05 07:39:51 +02:00
Uwe Kindler
a65b1bdcaf Removed new dropped signals 2020-06-05 07:27:44 +02:00
Uwe Kindler
4041aa72cc Implemented proper support for setting floating widget focused widget 2020-06-05 06:55:43 +02:00
Hugo Slepicka
4d2de7bb2a FIX: Update Python bindings for 3.4.2 and current master. (#193)
* FIX: Update python bindings for 3.4.2.

* FIX: Try to fix windows build.

* FIX: Add const at nativeEvent argument.

* FIX: Adjusting sip bindings for changes from 8b6df4aaa5.
2020-06-04 23:55:02 +02:00
Uwe Kindler
bcb7118710 Fixed typos 2020-06-04 20:48:59 +02:00
Uwe Kindler
45390506dd Continued implementation 2020-06-04 20:40:23 +02:00
Uwe Kindler
f58a3d4401 Change to support loading of older files without UserVersion atribute 2020-06-03 19:53:17 +02:00
Uwe Kindler
a3e979a8ad Disabled setFocus in CDockWidget::setActiveTab 2020-06-03 19:49:57 +02:00
Uwe Kindler
adb72737e8 Merge branch 'version_fix' into focused_dockwidget 2020-06-03 17:53:05 +02:00
Uwe Kindler
e626a7e302 Merge branch 'master' into focused_dockwidget 2020-06-03 17:52:46 +02:00
Uwe Kindler
8b6df4aaa5 Fixed saveState() and restoreState() version handling to work like the function from QMainWindow 2020-06-03 07:25:09 +02:00
Uwe Kindler
ae999f132e Improved focus styling 2020-05-23 14:45:49 +02:00
Uwe Kindler
9aa958e8b0 Made all focus related code optional - only if FocusStyling flag is enabled 2020-05-23 11:17:31 +02:00
Uwe Kindler
5652c8440e Added new CDockManger config flag FocusStyling 2020-05-23 11:10:03 +02:00
Uwe Kindler
26f4c9b049 Merge branch 'focused_dockwidget' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System into focused_dockwidget 2020-05-22 21:30:10 +02:00
Uwe Kindler
ce11fa9d10 Merge branch 'master' into focused_dockwidget 2020-05-22 21:28:02 +02:00
Uwe Kindler
333d2920db Merge remote-tracking branch 'origin/focused_dockwidget' into focused_dockwidget 2020-05-22 19:26:54 +02:00
Uwe Kindler
25eb02d07c Added support for focus styling of CFloatingWidgetTitleBra 2020-05-22 19:23:40 +02:00
Uwe Kindler
3b2f940efa Fixed windows build 2020-05-21 10:32:31 +02:00
Uwe Kindler
9dcbe91f02 Merge branch 'focused_dockwidget' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System into focused_dockwidget 2020-05-21 08:29:55 +02:00
Uwe Kindler
4da810ba7c Added window()->activateWindow() dropFloatingWidget() function 2020-05-20 14:20:27 +02:00
Uwe Kindler
819f1effc5 Added support for focus styling of CFloatingWidgetTitleBra 2020-05-19 22:53:52 +02:00
Uwe Kindler
ba94ef3493 Merge branch 'master' into focused_dockwidget 2020-05-19 20:51:19 +02:00
Uwe Kindler
0127fd89a3 Merge branch 'master' into focused_dockwidget 2020-05-17 12:26:22 +02:00
Uwe Kindler
79cb889d83 Improved focus style handling 2020-05-17 08:51:58 +02:00
Uwe Kindler
e760d3e967 Improved focus handling when dropping a dock widget 2020-05-14 09:06:04 +02:00
Uwe Kindler
c5333a2414 Merge branch 'master' into focused_dockwidget 2020-05-14 07:34:31 +02:00
Uwe Kindler
3a0c2a3113 Some refactorings in onFocusChanged() to improve code readibility 2020-05-13 22:51:44 +02:00
Uwe Kindler
789f78354a Merge branch 'master' into focused_dockwidget 2020-05-13 21:27:21 +02:00
Uwe Kindler
4c75168152 Improved focus setting when closing a dock area widget 2020-05-13 13:18:05 +02:00
Uwe Kindler
64a2024513 Removed debug output 2020-05-13 11:20:32 +02:00
Uwe Kindler
056e1ef947 Improved highlighting focused dock widget 2020-05-13 11:17:43 +02:00
Uwe Kindler
f54869fbf7 Improved setting of CDockWidgetTab focus 2020-05-11 16:29:58 +02:00
Uwe Kindler
835a20f03f Merge branch 'master' into focused_dockwidget 2020-05-11 15:50:47 +02:00
Uwe Kindler
067338ef23 Enable styling of focused dockwidget 2020-05-10 19:30:34 +02:00
39 changed files with 1536 additions and 287 deletions

View File

@@ -7,22 +7,12 @@
[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.
[![Video Advanced Docking](doc/advanced-docking_video.png)](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.
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.
## Features
### Overview
@@ -38,6 +28,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 +127,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
<img src="doc/python_logo.png" height="140">
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.4.2](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.4.2)
## Tested Compatible Environments
### Windows
@@ -247,7 +252,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

View File

@@ -196,6 +196,9 @@ static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
.arg(FileSystemCount++));
DockWidget->setWidget(w);
ViewMenu->addAction(DockWidget->toggleViewAction());
// We disable focus to test focus highlighting if the dock widget content
// does not support focus
w->setFocusPolicy(Qt::NoFocus);
return DockWidget;
}
@@ -571,6 +574,10 @@ 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);
// Now create the dock manager and its content
d->DockManager = new CDockManager(this);
@@ -656,13 +663,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 << ")";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
doc/python_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -23,6 +23,7 @@
- [`FloatingContainerHasWidgetTitle`](#floatingcontainerhaswidgettitle)
- [`FloatingContainerHasWidgetIcon`](#floatingcontainerhaswidgeticon)
- [`HideSingleCentralWidgetTitleBar`](#hidesinglecentralwidgettitlebar)
- [`FocusHighlighting`](#focushighlighting)
- [Styling](#styling)
- [Disabling the Internal Style Sheet](#disabling-the-internal-style-sheet)
@@ -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.
![HideSingleCentralWidgetTitleBar false](cfg_flag_HideSingleCentralWidgetTitleBar_false.png)
### `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.
![FocusHighlighting](cfg_flag_FocusHighlighting.gif)
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

View File

@@ -10,6 +10,7 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
QMainWindow w;
ads::CDockManager::setConfigFlag(ads::CDockManager::FocusHighlighting, true);
auto dockManager = new ads::CDockManager(&w);
QAction *action = new QAction("New Delete On Close", &w);

View File

@@ -214,6 +214,7 @@ class build_ext(sipdistutils.build_ext):
# /usr/bin/rcc -name ads ../../Qt-Advanced-Docking-System/src/ads.qrc -o release/qrc_ads.cpp
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 +248,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()]

View 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

View File

@@ -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;

View File

@@ -194,8 +194,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);

View File

@@ -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/);

View File

@@ -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/);

View File

@@ -5,6 +5,7 @@
%Include ads_globals.sip
%Include DockWidget.sip
%Include DockAreaTabBar.sip
%Include DockAreaTitleBar_p.sip
%Include DockAreaTitleBar.sip
%Include DockAreaWidget.sip
%Include DockComponentsFactory.sip

View File

@@ -8,13 +8,6 @@ namespace ads
#include <ads_globals.h>
%End
enum eStateFileVersion
{
InitialVersion,
Version1,
CurrentVersion
};
enum DockWidgetArea
{
NoDockWidgetArea,

View File

@@ -17,6 +17,7 @@ set(ads_SRCS
DockWidget.cpp
DockWidgetTab.cpp
DockingStateReader.cpp
DockFocusController.cpp
ElidingLabel.cpp
FloatingDockContainer.cpp
FloatingDragPreview.cpp
@@ -37,6 +38,7 @@ set(ads_INSTALL_INCLUDE
DockWidget.h
DockWidgetTab.h
DockingStateReader.h
DockFocusController.h
ElidingLabel.h
FloatingDockContainer.h
FloatingDragPreview.h

View File

@@ -465,6 +465,11 @@ void CDockAreaTitleBar::mousePressEvent(QMouseEvent* ev)
ev->accept();
d->DragStartMousePos = ev->pos();
d->DragState = DraggingMousePressed;
if (CDockManager::configFlags().testFlag(CDockManager::FocusHighlighting))
{
d->TabBar->currentTab()->setFocus(Qt::OtherFocusReason);
}
return;
}
Super::mousePressEvent(ev);
@@ -485,6 +490,7 @@ void CDockAreaTitleBar::mouseReleaseEvent(QMouseEvent* ev)
{
d->FloatingWidget->finishDragging();
}
return;
}
Super::mouseReleaseEvent(ev);

View File

@@ -413,6 +413,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 +429,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())

View File

@@ -1459,6 +1459,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 +1485,19 @@ 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);
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Widget);
if (!DockWidget)
{
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Widget);
auto OpenDockWidgets = DockArea->openedDockWidgets();
if (OpenDockWidgets.count() == 1)
{
DockWidget = OpenDockWidgets[0];
}
}
window()->activateWindow();
d->DockManager->notifyWidgetOrAreaRelocation(Widget);
}

View File

@@ -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;

322
src/DockFocusController.cpp Normal file
View File

@@ -0,0 +1,322 @@
//============================================================================
/// \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 "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;
#ifdef Q_OS_LINUX
QPointer<CFloatingDockContainer> FloatingWidget = nullptr;
#endif
CDockManager* DockManager;
/**
* 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)
{
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)
{
emit DockManager->focusedDockWidgetChanged(old, 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;
}
Q_UNUSED(focusedOld)
if (!focusedNow)
{
return;
}
CDockWidget* DockWidget = nullptr;
auto DockWidgetTab = qobject_cast<CDockWidgetTab*>(focusedNow);
if (DockWidgetTab)
{
DockWidget = DockWidgetTab->dockWidget();
}
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)
{
CDockManager::setWidgetFocus(DockWidget->tabWidget());
return;
}
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(DroppedWidget);
if (!DockArea)
{
return;
}
DockWidget = DockArea->currentDockWidget();
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)
{
DockWidget->dockAreaWidget()->setCurrentDockWidget(DockWidget);
CDockManager::setWidgetFocus(DockWidget->tabWidget());
}
}
//==========================================================================
void CDockFocusController::onStateRestored()
{
if (d->FocusedDockWidget)
{
updateDockWidgetFocusStyle(d->FocusedDockWidget, false);
}
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockFocusController.cpp

89
src/DockFocusController.h Normal file
View File

@@ -0,0 +1,89 @@
#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();
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::configFlags().testFlag(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

View File

@@ -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
@@ -239,8 +256,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 +466,11 @@ CDockManager::CDockManager(QWidget *parent) :
d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay);
d->Containers.append(this);
d->loadStylesheet();
if (CDockManager::configFlags().testFlag(CDockManager::FocusHighlighting))
{
d->FocusController = new CDockFocusController(this);
}
}
//============================================================================
@@ -528,7 +562,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 +605,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;
}
@@ -872,6 +906,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
//---------------------------------------------------------------------------

View File

@@ -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,7 @@ 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
DefaultDockAreaButtons = DockAreaHasCloseButton
| DockAreaHasUndockButton
@@ -308,8 +325,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 +338,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 +427,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::configFlags().testFlag(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 +523,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
//-----------------------------------------------------------------------------

View File

@@ -235,6 +235,11 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
SLOT(toggleView(bool)));
setToolbarFloatingStyle(false);
if (CDockManager::configFlags().testFlag(CDockManager::FocusHighlighting))
{
setFocusPolicy(Qt::ClickFocus);
}
}
//============================================================================

View File

@@ -160,6 +160,7 @@ struct DockWidgetTabPrivate
GlobalDragStartMousePosition = GlobalPos;
DragStartMousePosition = _this->mapFromGlobal(GlobalPos);
}
};
// struct DockWidgetTabPrivate
@@ -284,6 +285,10 @@ CDockWidgetTab::CDockWidgetTab(CDockWidget* DockWidget, QWidget *parent) :
setAttribute(Qt::WA_NoMousePropagation, true);
d->DockWidget = DockWidget;
d->createLayout();
if (CDockManager::configFlags().testFlag(CDockManager::FocusHighlighting))
{
setFocusPolicy(Qt::ClickFocus);
}
}
//============================================================================
@@ -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::configFlags().testFlag(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

View File

@@ -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;

View File

@@ -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
//---------------------------------------------------------------------------

View File

@@ -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

View File

@@ -4,5 +4,6 @@
<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>
</qresource>
</RCC>

View File

@@ -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

View File

@@ -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

View File

@@ -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="-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:#000000;fill-opacity:0.50196081;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>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View 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

View File

@@ -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

View File

@@ -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,26 @@ 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::repolishStyle(d->TitleLabel);
}
} // namespace ads

View File

@@ -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.

View File

@@ -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 {

View File

@@ -9,10 +9,6 @@ ads--CDockContainerWidget
background: palette(dark);
}
ads--CDockContainerWidget QSplitter::handle
{
background: palette(dark);
}
ads--CDockAreaWidget
{
@@ -82,13 +78,74 @@ QScrollArea#dockWidgetScrollArea
#tabCloseButton:hover
{
border: 1px solid rgba(0, 0, 0, 32);
background: rgba(0, 0, 0, 16);
/*border: 1px solid rgba(0, 0, 0, 32);*/
background: rgba(0, 0, 0, 24);
}
#tabCloseButton:pressed
{
background: rgba(0, 0, 0, 32);
background: rgba(0, 0, 0, 48);
}
#tabCloseButton
{
qproperty-icon: url(:/ads/images/close-button.svg);
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;
}

View File

@@ -84,13 +84,74 @@ QScrollArea#dockWidgetScrollArea
#tabCloseButton:hover
{
border: 1px solid rgba(0, 0, 0, 32);
background: rgba(0, 0, 0, 16);
/*border: 1px solid rgba(0, 0, 0, 32);*/
background: rgba(0, 0, 0, 24);
}
#tabCloseButton:pressed
{
background: rgba(0, 0, 0, 32);
background: rgba(0, 0, 0, 48);
}
#tabCloseButton
{
qproperty-icon: url(:/ads/images/close-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"] ads--CFloatingWidgetTitleBar > QLabel
{
color: palette(light);
}