Skip to content

Commit a941c10

Browse files
authored
Add the possibility to open an auto-hide dock on a drag & drop (#667)
* Add open auto-hide dock on hover from drag and drop (#663) * Fix formatting (#663) * Fix formatting#2 (#663) * Add AutoHideDragNDrop example
1 parent 952131a commit a941c10

18 files changed

+498
-17
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.5)
2-
2+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
33
if (POLICY CMP0091)
44
cmake_policy(SET CMP0091 NEW)
55
endif (POLICY CMP0091)
269 KB
Loading

doc/user-guide.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
5050
- [`AutoHideHasCloseButton`](#autohidehasclosebutton)
5151
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
52+
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
5253
- [DockWidget Feature Flags](#dockwidget-feature-flags)
5354
- [`DockWidgetClosable`](#dockwidgetclosable)
5455
- [`DockWidgetMovable`](#dockwidgetmovable)
@@ -150,7 +151,7 @@ This ie enabled by default to minimize the size of the saved data.
150151
151152
### `TabCloseButtonIsToolButton`
152153
153-
If enabled the tab close buttons will be `QToolButtons` instead of `QPushButtons` -
154+
If enabled the tab close buttons will be `QToolButtons` instead of `QPushButtons` -
154155
disabled by default. Normally the default configuration should be ok but if your
155156
application requires `QToolButtons` instead of `QPushButtons` for styling reasons
156157
or for any other reasons, then you can enable this flag.
@@ -181,7 +182,7 @@ constant, that means, if enabled, the tabs need more space.
181182
182183
### `DragPreviewIsDynamic`
183184
184-
If non-opaque undocking is enabled, this flag defines the behavior of the drag
185+
If non-opaque undocking is enabled, this flag defines the behavior of the drag
185186
preview window. If this flag is enabled, then it will give the user the
186187
impression, that the floating drag preview is dynamically adjusted to the drop
187188
area. In order to give the perfect impression, you should disable the flags
@@ -197,7 +198,7 @@ CDockManager::setConfigFlag(CDockManager::DragPreviewHasWindowFrame, false);
197198

198199
### `DragPreviewShowsContentPixmap`
199200

200-
If non-opaque undocking is enabled, the created drag preview window shows a
201+
If non-opaque undocking is enabled, the created drag preview window shows a
201202
copy of the content of the dock widget / dock are that is dragged, if this
202203
flag is enabled (default).
203204

@@ -210,7 +211,7 @@ like window without any content.
210211

211212
### `DragPreviewHasWindowFrame`
212213

213-
If non-opaque undocking is enabled, then this flag configures if the drag
214+
If non-opaque undocking is enabled, then this flag configures if the drag
214215
preview is frameless (default) or looks like a real window. If it is enabled,
215216
then the drag preview is a transparent window with a system window frame.
216217

@@ -378,7 +379,7 @@ ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar
378379

379380
If you have a content widget that does not support focussing for some reason
380381
(like `QVTKOpenGLStereoWidget` from the [VTK library](https://github.com/Kitware/VTK)),
381-
then you can manually switch the focus by reacting on mouse events. The
382+
then you can manually switch the focus by reacting on mouse events. The
382383
following code shows, how to install en event filter on the `QVTKOpenGLStereoWidget`
383384
to properly switch the focus on `QEvent::MouseButtonPress`:
384385

@@ -422,7 +423,7 @@ bool CMainWindow::eventFilter(QObject *watched, QEvent *event)
422423
### `EqualSplitOnInsertion`
423424

424425
This flag configures how the space is distributed if a new dock widget is
425-
inserted into an existing dock area. The flag is disabled by default. If 3
426+
inserted into an existing dock area. The flag is disabled by default. If 3
426427
dock widgets are inserted with the following code
427428

428429
```c++
@@ -433,7 +434,7 @@ then this is the result, if the flag is disabled:
433434
434435
![EqualSplitOnInsertion false](cfg_flag_EqualSplitOnInsertion_false.png)
435436
436-
If the flag is enabled, then the space is equally distributed to all widgets
437+
If the flag is enabled, then the space is equally distributed to all widgets
437438
in a splitter:
438439
439440
![EqualSplitOnInsertion true](cfg_flag_EqualSplitOnInsertion_true.png)
@@ -501,7 +502,7 @@ for active tabs. Inactive tabs only show their icon:
501502
502503
The Advanced Docking System supports "Auto-Hide" functionality for **all**
503504
dock containers. The "Auto Hide" feature allows to display more information
504-
using less screen space by hiding or showing windows pinned to one of the
505+
using less screen space by hiding or showing windows pinned to one of the
505506
four dock container borders.
506507
507508
Enabling this feature adds a button with a pin icon to each dock area.
@@ -563,7 +564,7 @@ That means, you can drag them to a different border or sidebar:
563564
564565
### Auto-Hide Tab Sorting
565566
566-
You can drag Auto-Hide tabs to a new position in the current sidebar
567+
You can drag Auto-Hide tabs to a new position in the current sidebar
567568
to sort them:
568569
569570
![Auo-Hide sort tabs](AutoHide_Sort_Tabs.gif)
@@ -632,7 +633,7 @@ the other Auto-Hide flags will be evaluated.
632633
633634
### `DockAreaHasAutoHideButton`
634635
635-
If this flag is set (default), then each dock area has a pin button in the title
636+
If this flag is set (default), then each dock area has a pin button in the title
636637
bar to toggle Auto-Hide state.
637638
638639
![DockAreaHasAutoHideButton true](cfg_flag_DockAreaHasAutoHideButton.png)
@@ -676,7 +677,7 @@ works if this feature is enabled.
676677
Some users don't understand the distinction between closing an auto hide dock and
677678
collapsing an auto hide dock. This may lead to situations where they press the
678679
close button (losing the side tab widget) instead of simply clicking outside
679-
the auto hide dock (collapsing the dock).
680+
the auto hide dock (collapsing the dock).
680681
681682
![AutoHideCloseButtonCollapsesDock false](cfg_flag_AutoHideCloseButtonCollapsesDock_false.gif)
682683
@@ -704,6 +705,15 @@ If this flag is set (disabled by default), then each auto hide widget has a mini
704705
705706
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
706707
708+
709+
### `AutoHideOpenOnDragHover`
710+
711+
If this flag is set (disabled by default), then holding a dragging cursor hover an auto-hide collapsed dock's tab will open said dock:
712+
713+
![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif)
714+
715+
Said dock must be set to accept drops to hide when cursor leaves its scope. See `AutoHideDragNDropExample` for more details.
716+
707717
## DockWidget Feature Flags
708718
709719
### `DockWidgetClosable`

examples/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ add_subdirectory(sidebar)
66
add_subdirectory(deleteonclose)
77
add_subdirectory(centralwidget)
88
add_subdirectory(autohide)
9+
add_subdirectory(autohidedragndrop)
910
add_subdirectory(emptydockarea)
10-
add_subdirectory(dockindock)
11+
add_subdirectory(dockindock)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(ads_example_autohide_dragndrop VERSION ${VERSION_SHORT})
3+
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
4+
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
5+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
6+
add_executable(AutoHideDragNDropExample WIN32
7+
main.cpp
8+
mainwindow.cpp
9+
mainwindow.ui
10+
droppableitem.cpp
11+
)
12+
target_include_directories(AutoHideDragNDropExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
13+
target_link_libraries(AutoHideDragNDropExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
14+
target_link_libraries(AutoHideDragNDropExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
15+
Qt${QT_VERSION_MAJOR}::Gui
16+
Qt${QT_VERSION_MAJOR}::Widgets)
17+
set_target_properties(AutoHideDragNDropExample PROPERTIES
18+
AUTOMOC ON
19+
AUTORCC ON
20+
AUTOUIC ON
21+
CXX_STANDARD 14
22+
CXX_STANDARD_REQUIRED ON
23+
CXX_EXTENSIONS OFF
24+
VERSION ${VERSION_SHORT}
25+
EXPORT_NAME "Qt Advanced Docking System Auto Hide With Drag N Drop Example"
26+
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
27+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
28+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
29+
)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
ADS_OUT_ROOT = $${OUT_PWD}/../..
2+
3+
QT += core gui widgets
4+
5+
TARGET = AutoHideDragNDropExample
6+
DESTDIR = $${ADS_OUT_ROOT}/lib
7+
TEMPLATE = app
8+
CONFIG += c++14
9+
CONFIG += debug_and_release
10+
adsBuildStatic {
11+
DEFINES += ADS_STATIC
12+
}
13+
14+
# The following define makes your compiler emit warnings if you use
15+
# any Qt feature that has been marked deprecated (the exact warnings
16+
# depend on your compiler). Please consult the documentation of the
17+
# deprecated API in order to know how to port your code away from it.
18+
DEFINES += QT_DEPRECATED_WARNINGS
19+
20+
SOURCES += \
21+
main.cpp \
22+
mainwindow.cpp \
23+
droppableitem.cpp
24+
25+
HEADERS += \
26+
mainwindow.h
27+
droppableitem.h
28+
29+
FORMS += \
30+
mainwindow.ui
31+
32+
LIBS += -L$${ADS_OUT_ROOT}/lib
33+
include(../../ads.pri)
34+
INCLUDEPATH += ../../src
35+
DEPENDPATH += ../../src
36+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "droppableitem.h"
2+
3+
#include <QDragEnterEvent>
4+
#include <QDragLeaveEvent>
5+
#include <QDropEvent>
6+
#include <QMimeData>
7+
#include <qsizepolicy.h>
8+
9+
DroppableItem::DroppableItem(const QString& text, QWidget* parent)
10+
: QPushButton(text, parent)
11+
{
12+
setAcceptDrops(true);
13+
setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
14+
}
15+
16+
void DroppableItem::dragEnterEvent(QDragEnterEvent* event)
17+
{
18+
if (event->mimeData()->hasText())
19+
{
20+
event->acceptProposedAction();
21+
setCursor(Qt::DragMoveCursor);
22+
}
23+
}
24+
25+
void DroppableItem::dragLeaveEvent(QDragLeaveEvent* event)
26+
{
27+
unsetCursor();
28+
}
29+
30+
void DroppableItem::dropEvent(QDropEvent* event)
31+
{
32+
if (event->mimeData()->hasText())
33+
{
34+
event->acceptProposedAction();
35+
setText(event->mimeData()->text());
36+
}
37+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <QObject>
2+
#include <QPushButton>
3+
4+
class QDragEnterEvent;
5+
class QDragLeaveEvent;
6+
class QDropEvent;
7+
8+
class DroppableItem : public QPushButton
9+
{
10+
Q_OBJECT;
11+
12+
public:
13+
DroppableItem(const QString& text = QString(), QWidget* parent = nullptr);
14+
15+
protected:
16+
void dragEnterEvent(QDragEnterEvent* event) override;
17+
void dragLeaveEvent(QDragLeaveEvent* event) override;
18+
void dropEvent(QDropEvent* event) override;
19+
};

examples/autohidedragndrop/main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <mainwindow.h>
2+
#include <QApplication>
3+
4+
int main(int argc, char *argv[])
5+
{
6+
QApplication a(argc, argv);
7+
CMainWindow w;
8+
w.show();
9+
return a.exec();
10+
}

examples/autohidedragndrop/main.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import os
2+
import sys
3+
4+
from PyQt5 import uic
5+
from PyQt5.QtCore import Qt, QTimer, QDir, QSignalBlocker
6+
from PyQt5.QtGui import QCloseEvent, QIcon
7+
from PyQt5.QtWidgets import (QApplication, QLabel, QCalendarWidget, QFrame, QTreeView,
8+
QTableWidget, QFileSystemModel, QPlainTextEdit, QToolBar,
9+
QWidgetAction, QComboBox, QAction, QSizePolicy, QInputDialog)
10+
11+
import PyQtAds as QtAds
12+
13+
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
14+
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
15+
16+
class MainWindow(MainWindowUI, MainWindowBase):
17+
18+
def __init__(self, parent=None):
19+
super().__init__(parent)
20+
21+
self.setupUi(self)
22+
23+
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.OpaqueSplitterResize, True)
24+
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.XmlCompressionEnabled, False)
25+
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FocusHighlighting, True)
26+
QtAds.CDockManager.setAutoHideConfigFlag(QtAds.CDockManager.AutoHideOpenOnDragHover, True);
27+
self.dock_manager = QtAds.CDockManager(self)
28+
29+
# Set central widget
30+
text_edit = QPlainTextEdit()
31+
text_edit.setPlaceholderText("This is the central editor. Enter your text here.")
32+
central_dock_widget = QtAds.CDockWidget("CentralWidget")
33+
central_dock_widget.setWidget(text_edit)
34+
central_dock_area = self.dock_manager.setCentralWidget(central_dock_widget)
35+
central_dock_area.setAllowedAreas(QtAds.DockWidgetArea.OuterDockAreas)
36+
37+
38+
droppable_item = DroppableItem("Drop text here.")
39+
drop_dock_widget = QtAds.CDockWidget("Tab")
40+
drop_dock_widget.setWidget(droppable_item)
41+
drop_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
42+
drop_dock_widget.setMinimumSize(200, 150)
43+
drop_dock_widget.setAcceptDrops(True)
44+
drop_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.LeftDockWidgetArea, drop_dock_widget)
45+
drop_area.setAcceptDrops(True)
46+
self.menuView.addAction(drop_dock_widget.toggleViewAction())
47+
48+
self.create_perspective_ui()
49+
50+
def create_perspective_ui(self):
51+
save_perspective_action = QAction("Create Perspective", self)
52+
save_perspective_action.triggered.connect(self.save_perspective)
53+
perspective_list_action = QWidgetAction(self)
54+
self.perspective_combobox = QComboBox(self)
55+
self.perspective_combobox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
56+
self.perspective_combobox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
57+
self.perspective_combobox.activated[str].connect(self.dock_manager.openPerspective)
58+
perspective_list_action.setDefaultWidget(self.perspective_combobox)
59+
self.toolBar.addSeparator()
60+
self.toolBar.addAction(perspective_list_action)
61+
self.toolBar.addAction(save_perspective_action)
62+
63+
def save_perspective(self):
64+
perspective_name, ok = QInputDialog.getText(self, "Save Perspective", "Enter Unique name:")
65+
if not ok or not perspective_name:
66+
return
67+
68+
self.dock_manager.addPerspective(perspective_name)
69+
blocker = QSignalBlocker(self.perspective_combobox)
70+
self.perspective_combobox.clear()
71+
self.perspective_combobox.addItems(self.dock_manager.perspectiveNames())
72+
self.perspective_combobox.setCurrentText(perspective_name)
73+
74+
def closeEvent(self, event: QCloseEvent):
75+
self.dock_manager.deleteLater()
76+
super().closeEvent(event)
77+
78+
79+
if __name__ == '__main__':
80+
app = QApplication(sys.argv)
81+
82+
w = MainWindow()
83+
w.show()
84+
app.exec_()

0 commit comments

Comments
 (0)