Compare commits

..

35 Commits
4.0.3 ... 4.0.4

Author SHA1 Message Date
Uwe Kindler
957afe3a07 Updated cmake build for demo to use quick and quickwidgets 2023-06-30 14:01:56 +02:00
Uwe Kindler
4ab726fee3 Updated Linux install requirements in README.md for building the demo application with QQuickWidget 2023-06-30 13:07:42 +02:00
Uwe Kindler
8d4507e9d8 Fixed mouse pressed state for Linux (use memeber variable instead of static) 2023-06-30 11:28:11 +02:00
Uwe Kindler
5a00eece87 Added QQuickWidget to demo application for testing OpenGl QtQuick on Linux 2023-06-30 08:27:51 +02:00
Uwe Kindler
09e4e6fa5a Fixed nullptr access in DockWidgetTab 2023-06-27 10:18:38 +02:00
Uwe Kindler
34cc91a9af Fixed #527 - updateDockWidgetFocusStyle() function error 2023-06-23 21:06:52 +02:00
Uwe Kindler
36cdf4a252 Fixed warnings on MacOS: replaced QApplication::setActiveWindow(this); with QWidget::activateWindow 2023-06-23 10:28:55 +02:00
Uwe Kindler
85f65b3f1a Avoid multiple function calls of parentWidget() function in CAutoHideSideBar::visibleTabCount() and CAutoHideSideBar::hasVisibleTabs() 2023-06-23 10:21:08 +02:00
Ahmad Syarifuddin
92da2eb8bd Bug fix sidebar state during restore (#526)
* fix side bar state being incorrect during restore

* isVisible is invalid during restore state

* Make visibleTabCount function consistent with hasVisibleTabs. Add a bit of documentation.

---------

Co-authored-by: Syarif Fakhri <fakhri.s@duerr-ndt.com>
2023-06-23 09:15:24 +02:00
Uwe Kindler
27edfe63ee Fixed issue #524: Sometimes sidebar visibility state is incorrect 2023-06-22 14:45:29 +02:00
Uwe Kindler
5517822008 Updated README.md with information about filing PySide related issues 2023-06-19 10:25:32 +02:00
Uwe Kindler
702702cbfd Merge branch '7c0o-master' 2023-06-19 10:03:56 +02:00
Uwe Kindler
c552fef134 Added documentation for the queued _this->ensureWidgetVisible(TabWidget) call 2023-06-19 10:02:19 +02:00
Eric Wong
916df28fcd Update FloatingDockContainer.cpp
remove dock container
2023-06-16 17:37:31 +08:00
Eric Wong
c08d91687a Update FloatingDockContainer.cpp
saveState() may use the floatingDockContainer to be deleted
2023-06-14 12:07:45 +08:00
Eric Wong
ccbde05fb7 Update DockAreaWidget.cpp
memory leak
2023-06-14 09:42:47 +08:00
Eric Wong
1049576349 Update DockAreaTabBar.cpp
Sometimes the synchronous calculation of the rectangular area fails
2023-06-08 09:13:41 +08:00
Uwe Kindler
0bfee09b17 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-06-06 15:26:21 +02:00
Uwe Kindler
87954e4459 Merged #518 - Add more options to determine the minimum size of a dock widget 2023-06-06 15:25:49 +02:00
githubuser0xFFFF
0301e345b4 Update linux-builds.yml 2023-05-12 19:32:39 +02:00
Uwe Kindler
f9b5ef8d89 Remove Ubuntu 18.04 from linux-builds 2023-05-09 13:36:42 +02:00
Uwe Kindler
0ed1f8f429 Fixed linux-builds.yml file 2023-05-08 10:32:58 +02:00
Uwe Kindler
659537916e Added documentation of new AutoHideCloseButtonCollapsesDock flag 2023-04-28 12:24:12 +02:00
Uwe Kindler
0cac9ac507 Merge branch 'close_button_collapse_dock' of https://github.com/duerr-ndt/Qt-Advanced-Docking-System into duerr-ndt-close_button_collapse_dock 2023-04-28 11:49:17 +02:00
Uwe Kindler
7a79ecab8a Fixed #511 - CDockWidget::toggleView now properly shows auto hide widgets 2023-04-28 11:47:01 +02:00
Uwe Kindler
1186d2b78c Fixed #509 - Implemented support for restoring maximized state of floating widgets on Windows 2023-04-28 11:12:22 +02:00
Syarif Fakhri
b46768537a Add config to make close button collapse auto hide dock 2023-04-28 15:27:22 +08:00
Uwe Kindler
44115d4bd9 Added support for printing events to diagnose window state ploblem 2023-04-28 08:33:45 +02:00
Uwe Kindler
f2d8e17981 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-04-27 23:38:19 +02:00
Uwe Kindler
7890a408f4 Added KDE LabPlot to the showcase section 2023-04-27 23:38:05 +02:00
Murmele
a940fc29c6 Use code also for other unix systems like BSD (#507) 2023-04-18 19:17:10 +02:00
Murmele
c6595563af if QT_VERSION_MAJOR is defined, use this version instead of searching again. Labplot does not support Qt6 yet and therefore the version is set manually in the project. If Qt5 and Qt6 are installed, QAd overwrites the Qt5 requirement and then the configuration of the project does not work (#504) 2023-04-16 11:32:45 +02:00
Uwe Kindler
cb24317010 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2023-04-11 08:31:26 +02:00
Uwe Kindler
fb1e427ab7 Added DREAM.3D NX to showcase section 2023-04-11 08:30:25 +02:00
Nicolas Elie
9d28a4d0d5 Fix typo in pyproject.toml (#501) 2023-04-08 09:08:01 +02:00
31 changed files with 353 additions and 104 deletions

View File

@@ -1,4 +1,4 @@
ilds
name: linux-builds
on: [push]
@@ -6,7 +6,7 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-18.04]
os: [ubuntu-20.04]
runs-on: ${{ matrix.os }}
@@ -16,7 +16,7 @@ jobs:
run: |
sudo apt-get update --fix-missing
sudo apt-get install qt5-default
sudo apt-get install qtbase5-private-dev
sudo apt-get install qtbase5-private-dev qtdeclarative5-dev
- name: qmake
run: qmake
- name: make
@@ -56,4 +56,4 @@ jobs:
- name: qmake
run: qmake
- name: make
run: make -j$(nproc)
run: make -j$(nproc)

View File

@@ -119,6 +119,8 @@ know it from Visual Studio.
- [RDE Robox Development Environment](#rde--robox-development-environment)
- [ResInsight](#resinsight)
- [ADTF 3](#adtf-3)
- [DREAM.3D NX](#dream3d-nx)
- [LabPlot](#labplot)
- [Alternative Docking System Implementations](#alternative-docking-system-implementations)
- [KDDockWidgets](#kddockwidgets)
- [QtitanDocking](#qtitandocking)
@@ -254,7 +256,7 @@ The PySide6 bindings were contributed by:
- [mborgerson](https://github.com/mborgerson)
For more information about the PySide6 bindings read [this](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/298) issue.
Please file PySide6-QtAds-specific issues on its [pyside6_qtads](https://github.com/mborgerson/pyside6_qtads) fork for tracking. For more information about the PySide6 bindings read [this](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/298) issue.
### PyQt5
@@ -318,7 +320,9 @@ Screenshot Ubuntu:
## Build
The Linux build requires private header files. Make sure that they are installed.
The library uses SVG icons, so ensure that Qt SVG support is installed.
The library uses SVG icons, so ensure that Qt SVG support is installed. The demo
application creates a `QQuickWidget` for testing, so ensure that the required
libraries are installed.
### Qt5 on Ubuntu 18.04 or 20.04
@@ -329,13 +333,13 @@ sudo apt install qt5-default qtbase5-private-dev
### Qt5 on Ubuntu 22.04
```bash
sudo apt install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools libqt5svg5
sudo apt install qtbase5-dev qtbase5-private-dev qtbase5-dev-tools libqt5svg5 libqt5qml5 qtdeclarative5-dev
```
### Qt6 on Ubuntu 22.04
```bash
sudo apt install qt6-base-dev qt6-base-private-dev qt6-tools-dev libqt6svg6
sudo apt install qt6-default qt6-base-dev qt6-base-private-dev qt6-tools-dev libqt6svg6 qt6-qtdeclarative
```
Open the `ads.pro` file with QtCreator and start the build, that's it.
@@ -593,13 +597,33 @@ says about the switch to Qt Advanced Docking:
![ADTF](doc/showcase_adtf.png)
### [DREAM.3D NX](https://github.com/BlueQuartzSoftware/DREAM3D)
DREAM.3D *(Digital Representation Environment for Analysis of Materials in 3D)* is an open source, cross-platform and modular, software suite that allows users to prepare, reconstruct, quantify, instantiate, and mesh, multidimensional, multimodal microstructural data, as well as many other applications.
[BlueQuartz Software](http://www.bluequartz.net/) is currently completely rewriting the DREAM.3D application. For the upcoming version **[DREAM3D NX](http://www.dream3d.io/)** they improved the UI by using the Advanced Docking System. An [early version](http://www.dream3d.io/) of **DREAM3D NX** with ADS is already available to any user who would like to take the brand new version out for a spin.
![DREAM.3D NX](doc/showcase_dream3d_nx.png)
[read more...](http://dream3d.bluequartz.net/)
### [LabPlot](https://labplot.kde.org/)
KDE LabPlot is the ultimate free, open source and cross-platform tool for scientists, engineers, and students who need to analyze and visualize data. With its intuitive interface and powerful features, you can create stunning plots and diagrams with ease. Whether you're working with CSV, FITS, or HDF5 data, KDE LabPlot makes it simple to import and analyze your data.
The LabPlot project recently switched to the Qt Advanced Docking System for their user interface. This switch represents a significant improvement to the LabPlot software, allowing users to create and manage complex data visualization layouts with ease.
![LabPlot](doc/showcase_labplot.png)
[read more...](https://labplot.kde.org/)
## Alternative Docking System Implementations
If this Qt Advanced Docking System does not fit to your needs you may consider some of the alternative docking system solutions for Qt.
### KDDockWidgets
This is an advanced docking framework for Qt from [KDAB](https://www.kdab.com/). The interesting thing is, that they separated GUI code from logic, so they can easily provide a QtQuick backend in the future.
This is an advanced docking framework for Qt from [KDAB](https://www.kdab.com/). The interesting thing is, that they separated GUI code from logic, so they can easily provide a QtQuick backend in the future.
- [Blog post about KDDockWidgets](https://www.kdab.com/kddockwidgets/)
- [GitHub project](https://github.com/KDAB/KDDockWidgets)

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
project(ads_demo VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets Quick QuickWidgets REQUIRED)
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS AxContainer REQUIRED)
endif()
@@ -21,7 +21,9 @@ add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
target_include_directories(AdvancedDockingSystemDemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src")
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::QuickWidgets)
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
endif()

View File

@@ -62,6 +62,7 @@
#include <QPointer>
#include <QMap>
#include <QElapsedTimer>
#include <QQuickWidget>
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
@@ -407,6 +408,17 @@ struct MainWindowPrivate
return DockWidget;
}
/**
* Create QQuickWidget for test for OpenGL and QQuick
*/
ads::CDockWidget *createQQuickWidget()
{
QQuickWidget *widget = new QQuickWidget();
ads::CDockWidget *dockWidget = new ads::CDockWidget("Quick");
dockWidget->setWidget(widget);
return dockWidget;
}
#ifdef Q_OS_WIN
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
@@ -424,7 +436,6 @@ struct MainWindowPrivate
}
#endif
#endif
};
//============================================================================
@@ -557,6 +568,11 @@ void MainWindowPrivate::createContent()
// Create image viewer
DockWidget = createImageViewer();
DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
// Create quick widget
DockWidget = createQQuickWidget();
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, true);
DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
}
@@ -734,7 +750,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
// uncomment if you would like to enable dock widget auto hiding
CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig);
CDockManager::setAutoHideConfigFlags({CDockManager::DefaultAutoHideConfig});
// uncomment if you would like to enable an equal distribution of the
// available size of a splitter to all contained dock widgets

View File

@@ -2,7 +2,7 @@ ADS_OUT_ROOT = $${OUT_PWD}/..
TARGET = AdvancedDockingSystemDemo
DESTDIR = $${ADS_OUT_ROOT}/lib
QT += core gui widgets
QT += core gui widgets quick quickwidgets
include(../ads.pri)

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
doc/showcase_dream3d_nx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

BIN
doc/showcase_labplot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View File

@@ -39,6 +39,7 @@
- [`AutoHideButtonCheckable`](#autohidebuttoncheckable)
- [`AutoHideSideBarsIconOnly`](#autohidesidebarsicononly)
- [`AutoHideShowOnMouseOver`](#autohideshowonmouseover)
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable)
@@ -589,6 +590,21 @@ is shown, if the user hovers over the Auto-Hide tab or if the users moves the
mouse outside of the Auto-Hide widget. Showing and hiding my mouse click still
works if this feature is enabled.
### `AutoHideCloseButtonCollapsesDock`
Some users don't understand the distinction between closing an auto hide dock and
collapsing an auto hide dock. This may lead to situations where they press the
close button (losing the side tab widget) instead of simply clicking outside
the auto hide dock (collapsing the dock).
![AutoHideCloseButtonCollapsesDock false](cfg_flag_AutoHideCloseButtonCollapsesDock_false.gif)
If `AutoHideCloseButtonCollapsesDock` option is active, the
close button in an auto hide widget collapses the auto hide widget instead of
closing it.
![AutoHideCloseButtonCollapsesDock true](cfg_flag_AutoHideCloseButtonCollapsesDock_true.gif)
## DockWidget Feature Flags
### `DockWidgetClosable`

View File

@@ -71,5 +71,5 @@ sources = [
"src/PushButton.cpp",
"src/ResizeHandle.cpp",
"src/ads_globals.cpp",
"src/linux/FloatingWidgetTitleBar.h; platform_system == 'Linux'",
"src/linux/FloatingWidgetTitleBar.cpp; platform_system == 'Linux'",
]

View File

@@ -127,27 +127,6 @@ void AutoHideSideBarPrivate::handleViewportEvent(QEvent* e)
}
break;
case QEvent::Resize:
if (_this->tabCount())
{
auto ev = static_cast<QResizeEvent*>(e);
auto Tab = _this->tabAt(0);
int Size = isHorizontal() ? ev->size().height() : ev->size().width();
int TabSize = isHorizontal() ? Tab->size().height() : Tab->size().width();
// If the size of the side bar is less than the size of the first tab
// then there are no visible tabs in this side bar. This check will
// fail if someone will force a very big border via CSS!!
if (Size < TabSize)
{
_this->hide();
}
}
else
{
_this->hide();
}
break;
default:
break;
}
@@ -288,20 +267,33 @@ void CAutoHideSideBar::removeTab(CAutoHideTab* SideTab)
//============================================================================
bool CAutoHideSideBar::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() != QEvent::ShowToParent)
auto Tab = qobject_cast<CAutoHideTab*>(watched);
if (!Tab)
{
return false;
}
// As soon as on tab is shown, we need to show the side tab bar
auto Tab = qobject_cast<CAutoHideTab*>(watched);
if (Tab)
switch (event->type())
{
show();
case QEvent::ShowToParent:
show();
break;
case QEvent::HideToParent:
if (!hasVisibleTabs())
{
hide();
}
break;
default:
break;
}
return false;
}
//============================================================================
Qt::Orientation CAutoHideSideBar::orientation() const
{
@@ -323,6 +315,39 @@ int CAutoHideSideBar::tabCount() const
}
//============================================================================
int CAutoHideSideBar::visibleTabCount() const
{
int count = 0;
auto ParentWidget = parentWidget();
for (auto i = 0; i < tabCount(); i++)
{
if (tabAt(i)->isVisibleTo(ParentWidget))
{
count++;
}
}
return count;
}
//============================================================================
bool CAutoHideSideBar::hasVisibleTabs() const
{
auto ParentWidget = parentWidget();
for (auto i = 0; i < tabCount(); i++)
{
if (tabAt(i)->isVisibleTo(ParentWidget))
{
return true;
}
}
return false;
}
//============================================================================
SideBarLocation CAutoHideSideBar::sideBarLocation() const
{

View File

@@ -134,6 +134,19 @@ public:
*/
int tabCount() const;
/**
* Returns the number of visible tabs to its parent widget.
*/
int visibleTabCount() const;
/**
* Returns true, if the sidebar contains visible tabs to its parent widget.
* The function returns as soon as it finds the first visible tab.
* That means, if you just want to find out if there are visible tabs
* then this function is quicker than visibleTabCount()
*/
bool hasVisibleTabs() const;
/**
* Getter for side tab bar area property
*/

View File

@@ -1,6 +1,11 @@
cmake_minimum_required(VERSION 3.5)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
if (${QT_VERSION_MAJOR})
message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}")
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
else()
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
endif()
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED)
if (UNIX AND NOT APPLE)
include_directories(${Qt${QT_VERSION_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})

View File

@@ -36,6 +36,7 @@
#include <QBoxLayout>
#include <QApplication>
#include <QtGlobal>
#include <QTimer>
#include "FloatingDockContainer.h"
#include "DockAreaWidget.h"
@@ -107,7 +108,12 @@ void DockAreaTabBarPrivate::updateTabs()
{
TabWidget->show();
TabWidget->setActiveTab(true);
_this->ensureWidgetVisible(TabWidget);
// Sometimes the synchronous calculation of the rectangular area fails
// Therefore we use QTimer::singleShot here to execute the call
// within the event loop - see #520
QTimer::singleShot(0, [&, TabWidget]{
_this->ensureWidgetVisible(TabWidget);
});
}
else
{

View File

@@ -415,7 +415,12 @@ void CDockAreaTitleBar::onTabsMenuAboutToShow()
void CDockAreaTitleBar::onCloseButtonClicked()
{
ADS_PRINT("CDockAreaTitleBar::onCloseButtonClicked");
if (d->testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideCloseButtonCollapsesDock) &&
d->DockArea->autoHideDockContainer())
{
d->DockArea->autoHideDockContainer()->collapseView(true);
}
else if (d->testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
{
d->TabBar->closeTab(d->TabBar->currentIndex());
}

View File

@@ -140,6 +140,7 @@ public:
{
LayoutItem->widget()->setParent(nullptr);
}
delete LayoutItem;
m_CurrentWidget = nullptr;
m_CurrentIndex = -1;
}

View File

@@ -27,7 +27,7 @@
#include "DockManager.h"
#include "DockAreaTitleBar.h"
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include "linux/FloatingWidgetTitleBar.h"
#endif
@@ -44,11 +44,12 @@ struct DockFocusControllerPrivate
QPointer<CDockWidget> FocusedDockWidget = nullptr;
QPointer<CDockAreaWidget> FocusedArea = nullptr;
QPointer<CDockWidget> OldFocusedDockWidget = nullptr;
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QPointer<CFloatingDockContainer> FloatingWidget = nullptr;
#endif
CDockManager* DockManager;
bool ForceFocusChangedSignal = false;
bool TabPressed = false;
/**
* Private data constructor
@@ -84,7 +85,7 @@ static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
//===========================================================================
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
{
if (FloatingWidget->hasNativeTitleBar())
@@ -168,7 +169,7 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
// This code is required for styling the floating widget titlebar for linux
// depending on the current focus state
if (FloatingWidget != NewFloatingWidget)
@@ -267,7 +268,9 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge
{
Q_UNUSED(focusedOld);
if (d->DockManager->isRestoringState())
// Ignore focus changes if we are restoring state, or if user clicked
// a tab wich in turn caused the focus change
if (d->DockManager->isRestoringState() || d->TabPressed)
{
return;
}
@@ -285,7 +288,7 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge
DockWidget = internal::findParent<CDockWidget*>(focusedNow);
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (!DockWidget)
{
return;
@@ -418,6 +421,12 @@ CDockWidget* CDockFocusController::focusedDockWidget() const
return d->FocusedDockWidget.data();
}
//==========================================================================
void CDockFocusController::setDockWidgetTabPressed(bool Value)
{
d->TabPressed = Value;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -80,6 +80,12 @@ public:
*/
void clearDockWidgetFocus(CDockWidget* dockWidget);
/**
* Notifies the dock focus controller, that a the mouse is pressed or
* released
*/
void setDockWidgetTabPressed(bool Value);
public Q_SLOTS:
/**
* Request a focus change to the given dock widget

View File

@@ -47,6 +47,7 @@
#include <QMenu>
#include <QApplication>
#include <QWindow>
#include <QWindowStateChangeEvent>
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
@@ -59,7 +60,7 @@
#include "DockFocusController.h"
#include "DockSplitter.h"
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include "linux/FloatingWidgetTitleBar.h"
#endif
@@ -116,6 +117,7 @@ struct DockManagerPrivate
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
CDockFocusController* FocusController = nullptr;
CDockWidget* CentralWidget = nullptr;
bool IsLeavingMinimized = false;
/**
* Private data constructor
@@ -192,7 +194,7 @@ void DockManagerPrivate::loadStylesheet()
QString FileName = ":ads/stylesheets/";
FileName += CDockManager::testConfigFlag(CDockManager::FocusHighlighting)
? "focus_highlighting" : "default";
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
FileName += "_linux";
#endif
FileName += ".css";
@@ -510,9 +512,10 @@ CDockManager::CDockManager(QWidget *parent) :
d->FocusController = new CDockFocusController(this);
}
#ifdef Q_OS_LINUX
window()->installEventFilter(this);
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow)
{
// bring modal dialogs to foreground to ensure that they are in front of any
@@ -552,7 +555,7 @@ CDockManager::~CDockManager()
}
//============================================================================
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
{
// Emulate Qt:Tool behaviour.
@@ -629,8 +632,39 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
}
return Super::eventFilter(obj, e);
}
#else
//============================================================================
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
{
if (e->type() == QEvent::WindowStateChange)
{
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(e);
if (ev->oldState().testFlag(Qt::WindowMinimized))
{
d->IsLeavingMinimized = true;
QMetaObject::invokeMethod(this, "endLeavingMinimizedState", Qt::QueuedConnection);
}
}
return Super::eventFilter(obj, e);
}
#endif
//============================================================================
void CDockManager::endLeavingMinimizedState()
{
d->IsLeavingMinimized = false;
this->activateWindow();
}
//============================================================================
bool CDockManager::isLeavingMinimizedState() const
{
return d->IsLeavingMinimized;
}
//============================================================================
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
{

View File

@@ -88,6 +88,12 @@ private:
friend class CAutoHideDockContainer;
friend CAutoHideSideBar;
public Q_SLOTS:
/**
* Ends the isRestoringFromMinimizedState
*/
void endLeavingMinimizedState();
protected:
/**
@@ -239,6 +245,7 @@ public:
AutoHideButtonCheckable = 0x08, //!< If the flag is set, the auto hide button will be checked and unchecked depending on the auto hide state. Mainly for styling purposes.
AutoHideSideBarsIconOnly = 0x10,///< show only icons in auto hide side tab - if a tab has no icon, then the text will be shown
AutoHideShowOnMouseOver = 0x20, ///< show the auto hide window on mouse over tab and hide it if mouse leaves auto hide container
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton ///< the default configuration for left and right side bars
@@ -539,6 +546,15 @@ public:
*/
bool isRestoringState() const;
/**
* This function returns true, if the DockManager window is restoring from
* minimized state.
* The DockManager is in this state starting from the QWindowStateChangeEvent
* that signals the state change from minimized to normal until
* endLeavingMinimizedState() function is called.
*/
bool isLeavingMinimizedState() const;
/**
* The distance the user needs to move the mouse with the left button
* hold down before a dock widget start floating
@@ -560,9 +576,7 @@ public:
widget->setFocus(Qt::OtherFocusReason);
}
#ifdef Q_OS_LINUX
bool eventFilter(QObject *obj, QEvent *e) override;
#endif
/**
* Returns the dock widget that has focus style in the ui or a nullptr if

View File

@@ -139,7 +139,7 @@ struct DockOverlayCrossPrivate
*/
qreal dropIndicatiorWidth(QLabel* l) const
{
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
Q_UNUSED(l)
return 40;
#else
@@ -333,7 +333,7 @@ CDockOverlay::CDockOverlay(QWidget* parent, eMode Mode) :
{
d->Mode = Mode;
d->Cross = new CDockOverlayCross(this);
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
#else
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
@@ -595,7 +595,7 @@ CDockOverlayCross::CDockOverlayCross(CDockOverlay* overlay) :
d(new DockOverlayCrossPrivate(this))
{
d->DockOverlay = overlay;
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
#else
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);

View File

@@ -622,6 +622,13 @@ void CDockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode Mode)
}
//============================================================================
CDockWidget::eMinimumSizeHintMode CDockWidget::minimumSizeHintMode() const
{
return d->MinimumSizeHintMode;
}
//============================================================================
bool CDockWidget::isCentralWidget() const
{
@@ -643,14 +650,20 @@ void CDockWidget::toggleView(bool Open)
// If the dock widget state is different, then we really need to toggle
// the state. If we are in the right state, then we simply make this
// dock widget the current dock widget
auto AutoHideContainer = autoHideDockContainer();
if (d->Closed != !Open)
{
toggleViewInternal(Open);
}
else if (Open && d->DockArea)
else if (Open && d->DockArea && !AutoHideContainer)
{
raise();
}
if (Open && AutoHideContainer)
{
AutoHideContainer->collapseView(false);
}
}
@@ -984,14 +997,20 @@ void CDockWidget::setClosedState(bool Closed)
//============================================================================
QSize CDockWidget::minimumSizeHint() const
{
if (d->MinimumSizeHintMode == CDockWidget::MinimumSizeHintFromDockWidget || !d->Widget)
if (!d->Widget)
{
return QSize(60, 40);
}
else
switch (d->MinimumSizeHintMode)
{
return d->Widget->minimumSizeHint();
case MinimumSizeHintFromDockWidget: return QSize(60, 40);
case MinimumSizeHintFromContent: return d->Widget->minimumSizeHint();
case MinimumSizeHintFromDockWidgetMinimumSize: return minimumSize();
case MinimumSizeHintFromContentMinimumSize: return d->Widget->minimumSize();
}
return d->Widget->minimumSizeHint();
}

View File

@@ -208,12 +208,17 @@ public:
* reimplements minimumSizeHint() function to return a very small minimum
* size hint. If you would like to adhere the minimumSizeHint() from the
* content widget, then set the minimumSizeHintMode() to
* MinimumSizeHintFromContent.
* MinimumSizeHintFromContent. If you would like to use the minimumSize()
* value of the content widget or the dock widget, then you can use the
* MinimumSizeHintFromDockWidgetMinimumSize or
* MinimumSizeHintFromContentMinimumSize modes.
*/
enum eMinimumSizeHintMode
{
MinimumSizeHintFromDockWidget,
MinimumSizeHintFromContent
MinimumSizeHintFromContent,
MinimumSizeHintFromDockWidgetMinimumSize,
MinimumSizeHintFromContentMinimumSize,
};
@@ -411,6 +416,11 @@ public:
*/
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);
/**
* Get the minimum size hint mode configured by setMinimumSizeHintMode
*/
eMinimumSizeHintMode minimumSizeHintMode() const;
/**
* Returns true if the dock widget is set as central widget of it's dock manager
*/

View File

@@ -79,6 +79,7 @@ struct DockWidgetTabPrivate
QSpacerItem* IconTextSpacer;
QPoint TabDragStartPosition;
QSize IconSize;
bool MousePressed = false;
/**
* Private data constructor
@@ -372,10 +373,12 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->MousePressed = true;
d->saveDragStartMousePosition(internal::globalPositionOf(ev));
d->DragState = DraggingMousePressed;
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
{
d->focusController()->setDockWidgetTabPressed(true);
d->focusController()->setDockWidgetTabFocused(this);
}
Q_EMIT clicked();
@@ -391,6 +394,7 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
d->MousePressed = false;
auto CurrentDragState = d->DragState;
d->GlobalDragStartMousePosition = QPoint();
d->DragStartMousePosition = QPoint();
@@ -412,7 +416,12 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
d->FloatingWidget->finishDragging();
break;
default:; // do nothing
default:
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
{
d->focusController()->setDockWidgetTabPressed(false);
}
break; // do nothing
}
}
else if (ev->button() == Qt::MiddleButton)
@@ -802,6 +811,7 @@ void CDockWidgetTab::setIconSize(const QSize& Size)
d->IconSize = Size;
d->updateIcon();
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockWidgetTab.cpp

View File

@@ -178,6 +178,12 @@ public:
*/
void setIconSize(const QSize& Size);
/**
* Returns true, if the tab has been clicked and the mouse is currently
* pressed.
*/
bool mousePressed() const;
public Q_SLOTS:
virtual void setVisible(bool visible) override;

View File

@@ -52,7 +52,7 @@
#pragma comment(lib, "User32.lib")
#endif
#endif
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include "linux/FloatingWidgetTitleBar.h"
#include <xcb/xcb.h>
#endif
@@ -374,10 +374,11 @@ struct FloatingDockContainerPrivate
QPoint DragStartPos;
bool Hiding = false;
bool AutoHideChildren = true;
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
bool IsResizing = false;
bool MousePressed = false;
#endif
/**
@@ -424,7 +425,7 @@ struct FloatingDockContainerPrivate
void setWindowTitle(const QString &Text)
{
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (TitleBar)
{
TitleBar->setTitle(Text);
@@ -540,7 +541,7 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
return;
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
// Prevent display of drop overlays and docking as long as a model dialog
// is active
if (qApp->activeModalWidget())
@@ -641,7 +642,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this,
SLOT(onDockAreasAddedOrRemoved()));
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::DockWidgetClosable
@@ -763,18 +764,43 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const
void CFloatingDockContainer::changeEvent(QEvent *event)
{
Super::changeEvent(event);
if ((event->type() == QEvent::ActivationChange) && isActiveWindow())
switch (event->type())
{
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
d->zOrderIndex = ++zOrderCounter;
#ifdef Q_OS_LINUX
if (d->DraggingState == DraggingFloatingWidget)
case QEvent::ActivationChange:
if (isActiveWindow())
{
d->titleMouseReleaseEvent();
d->DraggingState = DraggingInactive;
}
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
d->zOrderIndex = ++zOrderCounter;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (d->DraggingState == DraggingFloatingWidget)
{
d->titleMouseReleaseEvent();
d->DraggingState = DraggingInactive;
}
#endif
}
break;
case QEvent::WindowStateChange:
// If the DockManager window is restored from minimized on Windows
// then the FloatingWidgets are not properly restored to maximized but
// to normal state.
// We simply check here, if the FloatingWidget was maximized before
// and if the DockManager is just leaving the minimized state. In this
// case, we restore the maximized state of this floating widget
if (d->DockManager->isLeavingMinimizedState())
{
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(event);
if (ev->oldState().testFlag(Qt::WindowMaximized))
{
this->showMaximized();
}
}
break;
default:
break; // do nothing
}
}
@@ -920,7 +946,7 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
void CFloatingDockContainer::showEvent(QShowEvent *event)
{
Super::showEvent(event);
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
{
this->window()->activateWindow();
@@ -933,7 +959,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
{
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (!isMaximized())
{
resize(Size);
@@ -985,7 +1011,7 @@ void CFloatingDockContainer::moveFloating()
// 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);
activateWindow();
#endif
break;
default:
@@ -1070,7 +1096,7 @@ bool CFloatingDockContainer::restoreState(CDockingStateReader &Stream,
return false;
}
onDockAreasAddedOrRemoved();
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if(d->TitleBar)
{
d->TitleBar->setMaximizedIcon(windowState() == Qt::WindowMaximized);
@@ -1108,13 +1134,18 @@ void CFloatingDockContainer::hideAndDeleteLater()
d->AutoHideChildren = false;
hide();
deleteLater();
if (d->DockManager)
{
d->DockManager->removeFloatingWidget(this);
d->DockManager->removeDockContainer(this->dockContainer());
}
}
//============================================================================
void CFloatingDockContainer::finishDragging()
{
ADS_PRINT("CFloatingDockContainer::finishDragging");
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
setWindowOpacity(1);
activateWindow();
if (d->MouseEventHandler)
@@ -1218,7 +1249,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
// 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);
activateWindow();
break;
default:
break;
@@ -1229,7 +1260,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
#endif
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
//============================================================================
void CFloatingDockContainer::onMaximizeRequest()
{
@@ -1298,12 +1329,12 @@ void CFloatingDockContainer::resizeEvent(QResizeEvent *event)
Super::resizeEvent(event);
}
static bool s_mousePressed = false;
//============================================================================
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
{
Super::moveEvent(event);
if (!d->IsResizing && event->spontaneous() && s_mousePressed)
if (!d->IsResizing && event->spontaneous() && d->MousePressed)
{
d->setState(DraggingFloatingWidget);
d->updateDropOverlays(QCursor::pos());
@@ -1319,10 +1350,10 @@ bool CFloatingDockContainer::event(QEvent *e)
switch (e->type())
{
case QEvent::WindowActivate:
s_mousePressed = false;
d->MousePressed = false;
break;
case QEvent::WindowDeactivate:
s_mousePressed = true;
d->MousePressed = true;
break;
default:
break;

View File

@@ -33,7 +33,7 @@
#include <QRubberBand>
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include <QDockWidget>
#define tFloatingWidgetBase QDockWidget
#else
@@ -182,10 +182,8 @@ protected: // reimplements QWidget
#ifdef Q_OS_MACOS
virtual bool event(QEvent *e) override;
virtual void moveEvent(QMoveEvent *event) override;
#endif
#ifdef Q_OS_LINUX
virtual void moveEvent(QMoveEvent *event) override;
#elif defined(Q_OS_UNIX)
virtual void moveEvent(QMoveEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual bool event(QEvent *e) override;
@@ -264,7 +262,7 @@ public:
*/
void hideAndDeleteLater();
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
/**
* This is a function that responds to FloatingWidgetTitleBar::maximizeRequest()
* Maximize or normalize the container size.
@@ -300,7 +298,6 @@ public:
*/
bool hasNativeTitleBar();
#endif
}; // class FloatingDockContainer
}
// namespace ads

View File

@@ -262,7 +262,7 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
setAttribute(Qt::WA_TranslucentBackground);
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
auto Flags = windowFlags();
Flags |= Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint;
setWindowFlags(Flags);

View File

@@ -38,7 +38,7 @@
#include "IconProvider.h"
#include "ads_globals.h"
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include <QSettings>
#include <QFile>
#include <QApplication>
@@ -52,7 +52,7 @@ namespace internal
{
const int FloatingWidgetDragStartEvent = QEvent::registerEventType();
const int DockedWidgetDragStartEvent = QEvent::registerEventType();
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
static QString _window_manager;
static QHash<QString, xcb_atom_t> _xcb_atom_cache;
@@ -371,7 +371,7 @@ void setButtonIcon(QAbstractButton* Button, QStyle::StandardPixmap StandarPixmap
return;
}
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
Button->setIcon(Button->style()->standardIcon(StandarPixmap));
#else
// The standard icons does not look good on high DPI screens so we create

View File

@@ -40,7 +40,7 @@
#include <iostream>
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include <xcb/xcb.h>
#endif
@@ -156,7 +156,7 @@ static const char* const DirtyProperty = "dirty";
extern const int FloatingWidgetDragStartEvent;
extern const int DockedWidgetDragStartEvent;
#ifdef Q_OS_LINUX
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
// Utils to directly communicate with the X server
/**
* Get atom from cache or request it from the XServer.