Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c2d1891a2 | ||
|
|
998fe9fa11 | ||
|
|
28dc374fc2 | ||
|
|
1b6e449b4a | ||
|
|
0e88467f94 | ||
|
|
d0f4ce3248 | ||
|
|
542618fd4e | ||
|
|
661d0c4356 | ||
|
|
dceaa155c4 | ||
|
|
c541f2c69b | ||
|
|
37d305e50d | ||
|
|
4adef2b774 | ||
|
|
1c2383f8eb | ||
|
|
6c687d28de | ||
|
|
708add3ff5 | ||
|
|
e85b4167bd | ||
|
|
59c783831a | ||
|
|
4cb1931ace | ||
|
|
fe10b570d3 | ||
|
|
f3c5d51380 | ||
|
|
34cb2ae917 | ||
|
|
8cc9cc25ad | ||
|
|
c90fb9413c | ||
|
|
dec170ed24 | ||
|
|
3ffbbfb6d0 | ||
|
|
e8332575f8 | ||
|
|
8c12d912b4 | ||
|
|
fd28f0f751 | ||
|
|
3f09d5c6ea | ||
|
|
3407945f19 | ||
|
|
ce01e6b4a6 | ||
|
|
3428a4b8b4 | ||
|
|
2b9377b5ee | ||
|
|
d4a18003d9 | ||
|
|
2c15d5dacd | ||
|
|
f236de3277 | ||
|
|
93394577d0 | ||
|
|
f387c6aebc | ||
|
|
41173d067b | ||
|
|
5b60e39ed3 | ||
|
|
1916bd726d | ||
|
|
3efc5f2ada | ||
|
|
3eba02597c | ||
|
|
65eeffd5e1 | ||
|
|
ff1439c719 | ||
|
|
7ba20f37b7 |
@@ -42,6 +42,7 @@ set(ads_SRCS
|
|||||||
src/FloatingDockContainer.cpp
|
src/FloatingDockContainer.cpp
|
||||||
src/FloatingDragPreview.cpp
|
src/FloatingDragPreview.cpp
|
||||||
src/IconProvider.cpp
|
src/IconProvider.cpp
|
||||||
|
src/DockComponentsFactory.cpp
|
||||||
src/ads.qrc
|
src/ads.qrc
|
||||||
src/linux/FloatingWidgetTitleBar.cpp
|
src/linux/FloatingWidgetTitleBar.cpp
|
||||||
)
|
)
|
||||||
@@ -61,6 +62,7 @@ set(ads_INSTALL_INCLUDE
|
|||||||
src/FloatingDockContainer.h
|
src/FloatingDockContainer.h
|
||||||
src/FloatingDragPreview.h
|
src/FloatingDragPreview.h
|
||||||
src/IconProvider.h
|
src/IconProvider.h
|
||||||
|
src/DockComponentsFactory.h
|
||||||
src/linux/FloatingWidgetTitleBar.h
|
src/linux/FloatingWidgetTitleBar.h
|
||||||
)
|
)
|
||||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||||
|
|||||||
21
README.md
21
README.md
@@ -48,6 +48,9 @@ of his docking system project.
|
|||||||
- [KDDockWidgets](#kddockwidgets)
|
- [KDDockWidgets](#kddockwidgets)
|
||||||
- [QtitanDocking](#qtitandocking)
|
- [QtitanDocking](#qtitandocking)
|
||||||
- [Donation](#donation)
|
- [Donation](#donation)
|
||||||
|
- [Showcase](#showcase)
|
||||||
|
- [Qt Design Studio](#qt-design-studio)
|
||||||
|
- [QmixElements](#qmixelements)
|
||||||
|
|
||||||
### Docking everywhere - no central widget
|
### Docking everywhere - no central widget
|
||||||
|
|
||||||
@@ -273,3 +276,21 @@ If this project help you reduce time to develop or if you just like it, you can
|
|||||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=85R64TMMSY9T6">
|
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=85R64TMMSY9T6">
|
||||||
<img src="doc/donate.png" alt="Donate with PayPal" width="160"/>
|
<img src="doc/donate.png" alt="Donate with PayPal" width="160"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
## Showcase
|
||||||
|
|
||||||
|
### [Qt Design Studio](https://www.qt.io/ui-design-tools)
|
||||||
|
|
||||||
|
Taken from the [Qt Blog](https://www.qt.io/blog/qt-design-studio-1.5-beta-released):
|
||||||
|
|
||||||
|
> The most obvious change in [Qt Design Studio 1.5](https://www.qt.io/blog/qt-design-studio-1.5-beta-released) is the integration of dock widgets using the Qt Advanced Docking System. This allows the user to fully customize the workspace and also to undock any view into its own top level window. This especially improves the usability when using multiple screens.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### [QmixElements](https://www.cetoni.com/products/qmixelements/)
|
||||||
|
|
||||||
|
The QmixElements software from [CETONI](https://www.cetoni.com) is a comprehensive,
|
||||||
|
plugin-based and modular laboratory automation software for controlling CETONI devices using a joint graphical user interface. The software features a powerful script system to automate processes. This [blog post](https://www.cetoni.com/blog/qmixelements-advanced-docking-system/) gives a nice overview about the use of the Qt
|
||||||
|
Advanced Docking System in the QmixElements sofware.
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
316
demo.py
316
demo.py
@@ -1,316 +0,0 @@
|
|||||||
import datetime
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
|
|
||||||
QRect)
|
|
||||||
from PyQt5.QtGui import QGuiApplication
|
|
||||||
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
|
|
||||||
QMenu, QTreeView, QAction, QWidgetAction,
|
|
||||||
QComboBox, QStyle, QSizePolicy, QInputDialog)
|
|
||||||
|
|
||||||
from PyQt5 import QtWidgets
|
|
||||||
|
|
||||||
from PyQtAds import QtAds
|
|
||||||
|
|
||||||
|
|
||||||
class _State:
|
|
||||||
label_count = 0
|
|
||||||
calendar_count = 0
|
|
||||||
file_system_count = 0
|
|
||||||
|
|
||||||
|
|
||||||
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
||||||
'''
|
|
||||||
Create long text label dock widget
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
view_menu : QMenu
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
value : QtAds.CDockWidget
|
|
||||||
'''
|
|
||||||
label = QLabel()
|
|
||||||
label.setWordWrap(True)
|
|
||||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
|
||||||
label.setText('''\
|
|
||||||
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
|
||||||
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
|
||||||
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
|
||||||
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
|
||||||
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
|
||||||
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
|
||||||
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
|
||||||
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
|
||||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
|
||||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
|
||||||
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
|
||||||
'''.format(_State.label_count, str(datetime.datetime.now())))
|
|
||||||
_State.label_count += 1
|
|
||||||
|
|
||||||
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
|
||||||
dock_widget.setWidget(label)
|
|
||||||
|
|
||||||
view_menu.addAction(dock_widget.toggleViewAction())
|
|
||||||
return dock_widget
|
|
||||||
|
|
||||||
|
|
||||||
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
||||||
'''
|
|
||||||
Create calendar dock widget
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
view_menu : QMenu
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
value : QtAds.CDockWidget
|
|
||||||
'''
|
|
||||||
widget = QCalendarWidget()
|
|
||||||
|
|
||||||
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
|
||||||
_State.calendar_count += 1
|
|
||||||
dock_widget.setWidget(widget)
|
|
||||||
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
|
||||||
view_menu.addAction(dock_widget.toggleViewAction())
|
|
||||||
return dock_widget
|
|
||||||
|
|
||||||
|
|
||||||
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
||||||
'''
|
|
||||||
Create file system tree dock widget
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
view_menu : QMenu
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
value : QtAds.CDockWidget
|
|
||||||
'''
|
|
||||||
widget = QTreeView()
|
|
||||||
widget.setFrameShape(QFrame.NoFrame)
|
|
||||||
|
|
||||||
m = QFileSystemModel(widget)
|
|
||||||
m.setRootPath(QDir.currentPath())
|
|
||||||
widget.setModel(m)
|
|
||||||
|
|
||||||
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
|
||||||
_State.file_system_count += 1
|
|
||||||
dock_widget.setWidget(widget)
|
|
||||||
view_menu.addAction(dock_widget.toggleViewAction())
|
|
||||||
return dock_widget
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QtWidgets.QMainWindow):
|
|
||||||
save_perspective_action: QAction
|
|
||||||
perspective_list_action: QWidgetAction
|
|
||||||
perspective_combo_box: QComboBox
|
|
||||||
dock_manager: QtAds.CDockManager
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.save_perspective_action = None
|
|
||||||
self.perspective_list_action = None
|
|
||||||
self.perspective_combo_box = None
|
|
||||||
self.dock_manager = None
|
|
||||||
|
|
||||||
self.setup_ui()
|
|
||||||
|
|
||||||
self.dock_manager = QtAds.CDockManager(self)
|
|
||||||
self.perspective_combo_box.activated[str].connect(self.dock_manager.openPerspective)
|
|
||||||
self.create_content()
|
|
||||||
self.resize(800, 600)
|
|
||||||
self.restore_state()
|
|
||||||
self.restore_perspectives()
|
|
||||||
|
|
||||||
def setup_ui(self):
|
|
||||||
self.setObjectName("MainWindow")
|
|
||||||
self.resize(400, 300)
|
|
||||||
self.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks)
|
|
||||||
self.centralWidget = QtWidgets.QWidget(self)
|
|
||||||
self.centralWidget.setObjectName("centralWidget")
|
|
||||||
self.setCentralWidget(self.centralWidget)
|
|
||||||
self.status_bar = QtWidgets.QStatusBar(self)
|
|
||||||
self.status_bar.setObjectName("statusBar")
|
|
||||||
self.setStatusBar(self.status_bar)
|
|
||||||
self.menu_bar = QtWidgets.QMenuBar(self)
|
|
||||||
self.menu_bar.setGeometry(QRect(0, 0, 400, 21))
|
|
||||||
self.menu_bar.setObjectName("menuBar")
|
|
||||||
self.menu_file = QtWidgets.QMenu(self.menu_bar)
|
|
||||||
self.menu_file.setObjectName("menuFile")
|
|
||||||
self.menu_view = QtWidgets.QMenu(self.menu_bar)
|
|
||||||
self.menu_view.setObjectName("menuView")
|
|
||||||
self.menu_about = QtWidgets.QMenu(self.menu_bar)
|
|
||||||
self.menu_about.setObjectName("menuAbout")
|
|
||||||
self.setMenuBar(self.menu_bar)
|
|
||||||
self.tool_bar = QtWidgets.QToolBar(self)
|
|
||||||
self.tool_bar.setObjectName("toolBar")
|
|
||||||
self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
|
|
||||||
self.action_exit = QtWidgets.QAction(self)
|
|
||||||
self.action_exit.setObjectName("actionExit")
|
|
||||||
self.action_save_state = QtWidgets.QAction(self)
|
|
||||||
self.action_save_state.setObjectName("actionSaveState")
|
|
||||||
self.action_save_state.triggered.connect(self.saveState)
|
|
||||||
|
|
||||||
self.action_restore_state = QtWidgets.QAction(self)
|
|
||||||
self.action_restore_state.setObjectName("actionRestoreState")
|
|
||||||
self.action_restore_state.triggered.connect(self.restore_state)
|
|
||||||
|
|
||||||
self.menu_file.addAction(self.action_exit)
|
|
||||||
self.menu_file.addAction(self.action_save_state)
|
|
||||||
self.menu_file.addAction(self.action_restore_state)
|
|
||||||
self.menu_bar.addAction(self.menu_file.menuAction())
|
|
||||||
self.menu_bar.addAction(self.menu_view.menuAction())
|
|
||||||
self.menu_bar.addAction(self.menu_about.menuAction())
|
|
||||||
|
|
||||||
self.setWindowTitle("MainWindow")
|
|
||||||
self.menu_file.setTitle("File")
|
|
||||||
self.menu_view.setTitle("View")
|
|
||||||
self.menu_about.setTitle("About")
|
|
||||||
self.tool_bar.setWindowTitle("toolBar")
|
|
||||||
self.action_exit.setText("Exit")
|
|
||||||
self.action_save_state.setText("Save State")
|
|
||||||
self.action_restore_state.setText("Restore State")
|
|
||||||
self.create_actions()
|
|
||||||
|
|
||||||
def create_actions(self):
|
|
||||||
'''
|
|
||||||
Creates the toolbar actions
|
|
||||||
'''
|
|
||||||
self.tool_bar.addAction(self.action_save_state)
|
|
||||||
self.action_save_state.setIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton))
|
|
||||||
self.tool_bar.addAction(self.action_restore_state)
|
|
||||||
self.action_restore_state.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
|
|
||||||
self.save_perspective_action = QAction("Save Perspective", self)
|
|
||||||
self.save_perspective_action.triggered.connect(self.save_perspective)
|
|
||||||
|
|
||||||
self.perspective_list_action = QWidgetAction(self)
|
|
||||||
self.perspective_combo_box = QComboBox(self)
|
|
||||||
self.perspective_combo_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
|
||||||
self.perspective_combo_box.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
|
||||||
self.perspective_list_action.setDefaultWidget(self.perspective_combo_box)
|
|
||||||
self.tool_bar.addSeparator()
|
|
||||||
self.tool_bar.addAction(self.perspective_list_action)
|
|
||||||
self.tool_bar.addAction(self.save_perspective_action)
|
|
||||||
|
|
||||||
def create_content(self):
|
|
||||||
'''
|
|
||||||
Fill the dock manager with dock widgets
|
|
||||||
'''
|
|
||||||
# Test container docking
|
|
||||||
view_menu = self.menu_view
|
|
||||||
dock_widget = create_calendar_dock_widget(view_menu)
|
|
||||||
dock_widget.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
|
|
||||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
|
||||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
|
||||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
|
|
||||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
|
||||||
tool_bar = file_system_widget.createDefaultToolBar()
|
|
||||||
tool_bar.addAction(self.action_save_state)
|
|
||||||
tool_bar.addAction(self.action_restore_state)
|
|
||||||
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
|
|
||||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
|
||||||
tool_bar = file_system_widget.createDefaultToolBar()
|
|
||||||
tool_bar.addAction(self.action_save_state)
|
|
||||||
tool_bar.addAction(self.action_restore_state)
|
|
||||||
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
|
||||||
top_dock_area = self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, file_system_widget)
|
|
||||||
dock_widget = create_calendar_dock_widget(view_menu)
|
|
||||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
|
||||||
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
|
|
||||||
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
|
|
||||||
|
|
||||||
# Test dock area docking
|
|
||||||
right_dock_area = self.dock_manager.addDockWidget(
|
|
||||||
QtAds.RightDockWidgetArea,
|
|
||||||
create_long_text_label_dock_widget(view_menu), top_dock_area)
|
|
||||||
self.dock_manager.addDockWidget(
|
|
||||||
QtAds.TopDockWidgetArea,
|
|
||||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
||||||
|
|
||||||
bottom_dock_area = self.dock_manager.addDockWidget(
|
|
||||||
QtAds.BottomDockWidgetArea,
|
|
||||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
||||||
|
|
||||||
self.dock_manager.addDockWidget(
|
|
||||||
QtAds.RightDockWidgetArea,
|
|
||||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
||||||
self.dock_manager.addDockWidget(
|
|
||||||
QtAds.CenterDockWidgetArea,
|
|
||||||
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
|
|
||||||
|
|
||||||
def save_state(self):
|
|
||||||
'''
|
|
||||||
Saves the dock manager state and the main window geometry
|
|
||||||
'''
|
|
||||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
||||||
settings.setValue("mainWindow/Geometry", self.saveGeometry())
|
|
||||||
settings.setValue("mainWindow/State", self.saveState())
|
|
||||||
settings.setValue("mainWindow/DockingState", self.dock_manager.saveState())
|
|
||||||
|
|
||||||
def save_perspectives(self):
|
|
||||||
'''
|
|
||||||
Save the list of perspectives
|
|
||||||
'''
|
|
||||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
||||||
self.dock_manager.savePerspectives(settings)
|
|
||||||
|
|
||||||
def restore_state(self):
|
|
||||||
'''
|
|
||||||
Restores the dock manager state
|
|
||||||
'''
|
|
||||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
||||||
geom = settings.value("mainWindow/Geometry")
|
|
||||||
if geom is not None:
|
|
||||||
self.restoreGeometry(geom)
|
|
||||||
|
|
||||||
state = settings.value("mainWindow/State")
|
|
||||||
if state is not None:
|
|
||||||
self.restoreState(state)
|
|
||||||
|
|
||||||
state = settings.value("mainWindow/DockingState")
|
|
||||||
if state is not None:
|
|
||||||
self.dock_manager.restore_state(state)
|
|
||||||
|
|
||||||
def restore_perspectives(self):
|
|
||||||
'''
|
|
||||||
Restore the perspective listo of the dock manager
|
|
||||||
'''
|
|
||||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
||||||
self.dock_manager.loadPerspectives(settings)
|
|
||||||
self.perspective_combo_box.clear()
|
|
||||||
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
|
||||||
|
|
||||||
def save_perspective(self):
|
|
||||||
perspective_name, ok = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
|
|
||||||
if ok and perspective_name:
|
|
||||||
self.dock_manager.addPerspective(perspective_name)
|
|
||||||
_ = QSignalBlocker(self.perspective_combo_box)
|
|
||||||
self.perspective_combo_box.clear()
|
|
||||||
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
|
||||||
self.perspective_combo_box.setCurrentText(perspective_name)
|
|
||||||
self.save_perspectives()
|
|
||||||
|
|
||||||
|
|
||||||
def main(app_):
|
|
||||||
main_window = MainWindow()
|
|
||||||
main_window.show()
|
|
||||||
state = main_window.dock_manager.saveState()
|
|
||||||
# print('This is what the saved state looks like in XML:')
|
|
||||||
# print(str(state, 'utf-8'))
|
|
||||||
# print()
|
|
||||||
# main_window.dock_manager.restore_state(state)
|
|
||||||
return main_window
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# logging.basicConfig(level='DEBUG')
|
|
||||||
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
|
||||||
QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
|
||||||
app = QtWidgets.QApplication([])
|
|
||||||
window = main(app)
|
|
||||||
window.show()
|
|
||||||
app.exec_()
|
|
||||||
@@ -73,6 +73,8 @@
|
|||||||
#include "DockAreaTitleBar.h"
|
#include "DockAreaTitleBar.h"
|
||||||
#include "DockAreaTabBar.h"
|
#include "DockAreaTabBar.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
|
#include "DockComponentsFactory.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@@ -142,6 +144,25 @@ static QIcon svgIcon(const QString& File)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
class CCustomComponentsFactory : public ads::CDockComponentsFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Super = ads::CDockComponentsFactory;
|
||||||
|
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
|
||||||
|
{
|
||||||
|
auto TitleBar = new ads::CDockAreaTitleBar(DockArea);
|
||||||
|
auto CustomButton = new QToolButton(DockArea);
|
||||||
|
CustomButton->setToolTip(QObject::tr("Help"));
|
||||||
|
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
|
||||||
|
CustomButton->setAutoRaise(true);
|
||||||
|
int Index = TitleBar->indexOf(TitleBar->button(ads::TitleBarButtonTabsMenu));
|
||||||
|
TitleBar->insertWidget(Index + 1, CustomButton);
|
||||||
|
return TitleBar;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
|
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
|
||||||
{
|
{
|
||||||
@@ -202,28 +223,46 @@ static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
|
|||||||
return DockWidget;
|
return DockWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
/**
|
||||||
|
* Custom QTableWidget with a minimum size hint to test CDockWidget
|
||||||
|
* setMinimumSizeHintMode() function of CDockWidget
|
||||||
|
*/
|
||||||
|
class CMinSizeTableWidget : public QTableWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using QTableWidget::QTableWidget;
|
||||||
|
virtual QSize minimumSizeHint() const override
|
||||||
|
{
|
||||||
|
return QSize(300, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
|
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
|
||||||
{
|
{
|
||||||
static int TableCount = 0;
|
static int TableCount = 0;
|
||||||
QTableWidget* w = new QTableWidget();
|
auto w = new CMinSizeTableWidget();
|
||||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
|
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
|
||||||
static int colCount = 5;
|
static int colCount = 5;
|
||||||
static int rowCount = 30;
|
static int rowCount = 30;
|
||||||
w->setColumnCount(colCount);
|
w->setColumnCount(colCount);
|
||||||
w->setRowCount(rowCount);
|
w->setRowCount(rowCount);
|
||||||
for (int col = 0; col < colCount; ++col)
|
for (int col = 0; col < colCount; ++col)
|
||||||
{
|
{
|
||||||
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
|
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
|
||||||
for (int row = 0; row < rowCount; ++row)
|
for (int row = 0; row < rowCount; ++row)
|
||||||
{
|
{
|
||||||
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
|
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DockWidget->setWidget(w);
|
DockWidget->setWidget(w);
|
||||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
||||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
DockWidget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromContent);
|
||||||
return DockWidget;
|
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||||
|
return DockWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,6 +348,8 @@ void MainWindowPrivate::createContent()
|
|||||||
auto ToolBar = FileSystemWidget->createDefaultToolBar();
|
auto ToolBar = FileSystemWidget->createDefaultToolBar();
|
||||||
ToolBar->addAction(ui.actionSaveState);
|
ToolBar->addAction(ui.actionSaveState);
|
||||||
ToolBar->addAction(ui.actionRestoreState);
|
ToolBar->addAction(ui.actionRestoreState);
|
||||||
|
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||||
|
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||||
DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget);
|
DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget);
|
||||||
|
|
||||||
FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
||||||
@@ -318,9 +359,13 @@ void MainWindowPrivate::createContent()
|
|||||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||||
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
|
|
||||||
|
|
||||||
// We create a calender widget and clear all flags to prevent the dock area
|
// Test custom factory - we inject a help button into the title bar
|
||||||
|
ads::CDockComponentsFactory::setFactory(new CCustomComponentsFactory());
|
||||||
|
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
|
||||||
|
ads::CDockComponentsFactory::resetDefaultFactory();
|
||||||
|
|
||||||
|
// We create a calendar widget and clear all flags to prevent the dock area
|
||||||
// from closing
|
// from closing
|
||||||
DockWidget = createCalendarDockWidget(ViewMenu);
|
DockWidget = createCalendarDockWidget(ViewMenu);
|
||||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
||||||
@@ -458,9 +503,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
|||||||
// a QToolButton instead of a QPushButton
|
// a QToolButton instead of a QPushButton
|
||||||
// CDockManager::setConfigFlags(CDockManager::configFlags() | CDockManager::TabCloseButtonIsToolButton);
|
// CDockManager::setConfigFlags(CDockManager::configFlags() | CDockManager::TabCloseButtonIsToolButton);
|
||||||
|
|
||||||
// comment the following line if you want to use opaque undocking and
|
// uncomment the following line if you want to use opaque undocking and
|
||||||
// opaque splitter resizing
|
// opaque splitter resizing
|
||||||
CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig);
|
// CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
|
||||||
|
|
||||||
// uncomment the following line if you want a fixed tab width that does
|
// uncomment the following line if you want a fixed tab width that does
|
||||||
// not change if the visibility of the close button changes
|
// not change if the visibility of the close button changes
|
||||||
@@ -481,6 +526,12 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
|||||||
// uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title
|
// uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title
|
||||||
//CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true);
|
//CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true);
|
||||||
|
|
||||||
|
// uncomment the following line if you want floating container to always show application title instead of active dock widget's title
|
||||||
|
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetTitle, false);
|
||||||
|
|
||||||
|
// uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon
|
||||||
|
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetIcon, true);
|
||||||
|
|
||||||
// Now create the dock manager and its content
|
// Now create the dock manager and its content
|
||||||
d->DockManager = new CDockManager(this);
|
d->DockManager = new CDockManager(this);
|
||||||
|
|
||||||
|
|||||||
505
demo/demo.py
Normal file
505
demo/demo.py
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PyQt5 import uic
|
||||||
|
from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
|
||||||
|
QRect, QPoint, qDebug, qInstallMessageHandler,
|
||||||
|
QtDebugMsg, QtInfoMsg, QtWarningMsg,
|
||||||
|
QtCriticalMsg, QtFatalMsg)
|
||||||
|
from PyQt5.QtGui import (QGuiApplication, QIcon, QCloseEvent)
|
||||||
|
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
|
||||||
|
QMenu, QTreeView, QAction, QWidgetAction,
|
||||||
|
QComboBox, QStyle, QSizePolicy, QInputDialog, QMenu,
|
||||||
|
QToolButton, QWidget, QPlainTextEdit,
|
||||||
|
QTableWidget, QTableWidgetItem, QApplication,
|
||||||
|
QMessageBox)
|
||||||
|
try:
|
||||||
|
from PyQt5.QAxContainer import QAxWidget
|
||||||
|
except ImportError:
|
||||||
|
ACTIVEX_AVAILABLE = False
|
||||||
|
else:
|
||||||
|
ACTIVEX_AVAILABLE = True
|
||||||
|
|
||||||
|
from PyQtAds import QtAds
|
||||||
|
|
||||||
|
import rc # pyrcc5 demo.qrc -o rc.py
|
||||||
|
|
||||||
|
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
|
||||||
|
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
class _State:
|
||||||
|
label_count = 0
|
||||||
|
calendar_count = 0
|
||||||
|
file_system_count = 0
|
||||||
|
editor_count = 0
|
||||||
|
table_count = 0
|
||||||
|
activex_count = 0
|
||||||
|
|
||||||
|
|
||||||
|
def features_string(dock_widget: QtAds.CDockWidget) -> str:
|
||||||
|
'''Function returns a features string with closable (c), movable (m) and floatable (f)
|
||||||
|
features. i.e. The following string is for a not closable but movable and floatable
|
||||||
|
widget: c- m+ f+'''
|
||||||
|
|
||||||
|
f = dock_widget.features()
|
||||||
|
closable = f & QtAds.CDockWidget.DockWidgetClosable
|
||||||
|
movable = f & QtAds.CDockWidget.DockWidgetMovable
|
||||||
|
floatable = f &QtAds.CDockWidget.DockWidgetFloatable
|
||||||
|
|
||||||
|
return "c{} m{} f{}".format("+" if closable else "-",
|
||||||
|
"+" if movable else "-",
|
||||||
|
"+" if floatable else "-")
|
||||||
|
|
||||||
|
|
||||||
|
def append_feature_string_to_window_title(dock_widget: QtAds.CDockWidget):
|
||||||
|
'''Appends the string returned by features_string() to the window title of
|
||||||
|
the given DockWidget'''
|
||||||
|
|
||||||
|
dock_widget.setWindowTitle(dock_widget.windowTitle() + " ({})".format(features_string(dock_widget)))
|
||||||
|
|
||||||
|
|
||||||
|
def svg_icon(filename: str):
|
||||||
|
'''Helper function to create an SVG icon'''
|
||||||
|
# This is a workaround, because because in item views SVG icons are not
|
||||||
|
# properly scaled an look blurry or pixelate
|
||||||
|
icon = QIcon(filename)
|
||||||
|
icon.addPixmap(icon.pixmap(92))
|
||||||
|
return icon
|
||||||
|
|
||||||
|
|
||||||
|
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||||
|
label = QLabel()
|
||||||
|
label.setWordWrap(True)
|
||||||
|
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||||
|
label.setText('''\
|
||||||
|
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
||||||
|
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
||||||
|
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
||||||
|
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
||||||
|
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
||||||
|
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
||||||
|
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
||||||
|
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
||||||
|
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
||||||
|
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
||||||
|
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
||||||
|
'''.format(_State.label_count, datetime.datetime.now().strftime("%H:%M:%S:%f")))
|
||||||
|
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
||||||
|
_State.label_count += 1
|
||||||
|
dock_widget.setWidget(label)
|
||||||
|
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||||
|
widget = QCalendarWidget()
|
||||||
|
|
||||||
|
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
||||||
|
_State.calendar_count += 1
|
||||||
|
dock_widget.setWidget(widget)
|
||||||
|
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
||||||
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/date_range.svg"))
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||||
|
widget = QTreeView()
|
||||||
|
widget.setFrameShape(QFrame.NoFrame)
|
||||||
|
|
||||||
|
m = QFileSystemModel(widget)
|
||||||
|
m.setRootPath(QDir.currentPath())
|
||||||
|
widget.setModel(m)
|
||||||
|
|
||||||
|
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
||||||
|
_State.file_system_count += 1
|
||||||
|
dock_widget.setWidget(widget)
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
def create_editor_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||||
|
widget = QPlainTextEdit()
|
||||||
|
widget.setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||||
|
"deleted. Enter your text here.")
|
||||||
|
widget.setStyleSheet("border: none")
|
||||||
|
dock_widget = QtAds.CDockWidget("Editor {}".format(_State.editor_count))
|
||||||
|
_State.editor_count += 1
|
||||||
|
dock_widget.setWidget(widget)
|
||||||
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/edit.svg"))
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.CustomCloseHandling, True)
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
|
||||||
|
options_menu = QMenu(dock_widget)
|
||||||
|
options_menu.setTitle("Options")
|
||||||
|
options_menu.setToolTip(options_menu.title())
|
||||||
|
options_menu.setIcon(svg_icon(":/adsdemo/images/custom-menu-button.svg"))
|
||||||
|
menu_action = options_menu.menuAction()
|
||||||
|
# The object name of the action will be set for the QToolButton that
|
||||||
|
# is created in the dock area title bar. You can use this name for CSS
|
||||||
|
# styling
|
||||||
|
menu_action.setObjectName("options_menu")
|
||||||
|
dock_widget.setTitleBarActions([options_menu.menuAction()])
|
||||||
|
a = options_menu.addAction("Clear Editor")
|
||||||
|
a.triggered.connect(widget.clear)
|
||||||
|
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
def create_table_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||||
|
widget = QTableWidget()
|
||||||
|
dock_widget = QtAds.CDockWidget("Table {}".format(_State.table_count))
|
||||||
|
_State.table_count += 1
|
||||||
|
COLCOUNT = 5
|
||||||
|
ROWCOUNT = 30
|
||||||
|
widget.setColumnCount(COLCOUNT)
|
||||||
|
widget.setRowCount(ROWCOUNT)
|
||||||
|
for col in range(ROWCOUNT):
|
||||||
|
widget.setHorizontalHeaderItem(col, QTableWidgetItem("Col {}".format(col+1)))
|
||||||
|
for row in range(ROWCOUNT):
|
||||||
|
widget.setItem(row, col, QTableWidgetItem("T {:}-{:}".format(row+1, col+1)))
|
||||||
|
|
||||||
|
dock_widget.setWidget(widget)
|
||||||
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
if ACTIVEX_AVAILABLE:
|
||||||
|
def create_activex_widget(view_menu: QMenu, parent: QWidget = None) -> QtAds.CDockWidget:
|
||||||
|
widget = QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent)
|
||||||
|
dock_widget = QtAds.CDockWidget("Active X {}".format(_State.activex_count))
|
||||||
|
_State.activex_count += 1
|
||||||
|
dock_widget.setWidget(widget)
|
||||||
|
view_menu.addAction(dock_widget.toggleViewAction())
|
||||||
|
return dock_widget
|
||||||
|
|
||||||
|
|
||||||
|
class CustomComponentsFactory(QtAds.CDockComponentsFactory):
|
||||||
|
|
||||||
|
def createDockAreaTitleBar(self, dock_area: QtAds.CDockAreaWidget) -> QtAds.CDockAreaTitleBar:
|
||||||
|
title_bar = QtAds.CDockAreaTitleBar(dock_area)
|
||||||
|
custom_button = QToolButton(dock_area)
|
||||||
|
custom_button.setToolTip("Help")
|
||||||
|
custom_button.setIcon(svg_icon(":/adsdemo/images/help_outline.svg"))
|
||||||
|
custom_button.setAutoRaise(True)
|
||||||
|
index = title_bar.indexOf(title_bar.button(QtAds.TitleBarButtonTabsMenu))
|
||||||
|
title_bar.insertWidget(index + 1, custom_button)
|
||||||
|
return title_bar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(MainWindowUI, MainWindowBase):
|
||||||
|
save_perspective_action: QAction
|
||||||
|
perspective_list_action: QWidgetAction
|
||||||
|
perspective_combo_box: QComboBox
|
||||||
|
dock_manager: QtAds.CDockManager
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.save_perspective_action = None
|
||||||
|
self.perspective_list_action = None
|
||||||
|
self.perspective_combo_box = None
|
||||||
|
self.dock_manager = None
|
||||||
|
|
||||||
|
self.setupUi(self)
|
||||||
|
self.create_actions()
|
||||||
|
|
||||||
|
# uncomment the following line if the tab close button should be
|
||||||
|
# a QToolButton instead of a QPushButton
|
||||||
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.configFlags() | QtAds.CDockManager.TabCloseButtonIsToolButton)
|
||||||
|
|
||||||
|
# uncomment the following line if you want a fixed tab width that does
|
||||||
|
# not change if the visibility of the close button changes
|
||||||
|
# QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.RetainTabSizeWhenCloseButtonHidden, True)
|
||||||
|
|
||||||
|
# uncomment the follwing line if you want to use non opaque undocking and splitter
|
||||||
|
# movements
|
||||||
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DefaultNonOpaqueConfig)
|
||||||
|
|
||||||
|
# Now create the dock manager and its content
|
||||||
|
self.dock_manager = QtAds.CDockManager(self)
|
||||||
|
|
||||||
|
# Uncomment the following line to have the old style where the dock
|
||||||
|
# area close button closes the active tab
|
||||||
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DockAreaHasCloseButton
|
||||||
|
# | QtAds.CDockManager.DockAreaCloseButtonClosesTab)
|
||||||
|
self.perspective_combo_box.activated[str].connect(self.dock_manager.openPerspective)
|
||||||
|
|
||||||
|
self.create_content()
|
||||||
|
# Default window geometry - center on screen
|
||||||
|
self.resize(1280, 720)
|
||||||
|
self.setGeometry(QStyle.alignedRect(
|
||||||
|
Qt.LeftToRight, Qt.AlignCenter, self.frameSize(),
|
||||||
|
QGuiApplication.primaryScreen().availableGeometry()))
|
||||||
|
|
||||||
|
# self.restore_state()
|
||||||
|
self.restore_perspectives()
|
||||||
|
|
||||||
|
def create_content(self):
|
||||||
|
# Test container docking
|
||||||
|
view_menu = self.menuView
|
||||||
|
dock_widget = create_calendar_dock_widget(view_menu)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
||||||
|
special_dock_area = self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
||||||
|
|
||||||
|
# For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
||||||
|
special_dock_area.setAllowedAreas(QtAds.OuterDockAreas)
|
||||||
|
# special_dock_area.setAllowedAreas(QtAds.LeftDockWidgetArea | QtAds.RightDockWidgetArea) # just for testing
|
||||||
|
|
||||||
|
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
|
||||||
|
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||||
|
tool_bar = file_system_widget.createDefaultToolBar()
|
||||||
|
tool_bar.addAction(self.actionSaveState)
|
||||||
|
tool_bar.addAction(self.actionRestoreState)
|
||||||
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
||||||
|
append_feature_string_to_window_title(file_system_widget)
|
||||||
|
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
|
||||||
|
|
||||||
|
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||||
|
tool_bar = file_system_widget.createDefaultToolBar()
|
||||||
|
tool_bar.addAction(self.actionSaveState)
|
||||||
|
tool_bar.addAction(self.actionRestoreState)
|
||||||
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
||||||
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
||||||
|
append_feature_string_to_window_title(file_system_widget)
|
||||||
|
|
||||||
|
# Test custom factory - we inject a help button into the title bar
|
||||||
|
self.factory = CustomComponentsFactory()
|
||||||
|
QtAds.CDockComponentsFactory.setFactory(self.factory)
|
||||||
|
top_dock_area = self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, file_system_widget)
|
||||||
|
QtAds.CDockComponentsFactory.resetDefaultFactory()
|
||||||
|
|
||||||
|
|
||||||
|
# We create a calendar widget and clear all flags to prevent the dock area
|
||||||
|
# from closing
|
||||||
|
dock_widget = create_calendar_dock_widget(view_menu)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
||||||
|
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
|
||||||
|
dock_area = self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
|
||||||
|
|
||||||
|
# Now we add a custom button to the dock area title bar that will create
|
||||||
|
# new editor widgets when clicked
|
||||||
|
custom_button = QToolButton(dock_area)
|
||||||
|
custom_button.setToolTip("Create Editor")
|
||||||
|
custom_button.setIcon(svg_icon(":/adsdemo/images/plus.svg"))
|
||||||
|
custom_button.setAutoRaise(True)
|
||||||
|
title_bar = dock_area.titleBar()
|
||||||
|
index = title_bar.indexOf(title_bar.tabBar())
|
||||||
|
title_bar.insertWidget(index + 1, custom_button)
|
||||||
|
def on_button_clicked():
|
||||||
|
dock_widget = create_editor_widget(self.menuView)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||||
|
self.dock_manager.addDockWidgetTabToArea(dock_widget, dock_area)
|
||||||
|
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
||||||
|
custom_button.clicked.connect(on_button_clicked)
|
||||||
|
|
||||||
|
# Test dock area docking
|
||||||
|
right_dock_area = self.dock_manager.addDockWidget(
|
||||||
|
QtAds.RightDockWidgetArea,
|
||||||
|
create_long_text_label_dock_widget(view_menu), top_dock_area)
|
||||||
|
self.dock_manager.addDockWidget(
|
||||||
|
QtAds.TopDockWidgetArea,
|
||||||
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||||
|
|
||||||
|
bottom_dock_area = self.dock_manager.addDockWidget(
|
||||||
|
QtAds.BottomDockWidgetArea,
|
||||||
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||||
|
|
||||||
|
self.dock_manager.addDockWidget(
|
||||||
|
QtAds.CenterDockWidgetArea,
|
||||||
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||||
|
self.dock_manager.addDockWidget(
|
||||||
|
QtAds.CenterDockWidgetArea,
|
||||||
|
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
|
||||||
|
|
||||||
|
action = self.menuView.addAction("Set {} floating".format(dock_widget.windowTitle()))
|
||||||
|
action.triggered.connect(dock_widget.setFloating)
|
||||||
|
|
||||||
|
if ACTIVEX_AVAILABLE:
|
||||||
|
flags = self.dock_manager.configFlags()
|
||||||
|
if flags & QtAds.CDockManager.OpaqueUndocking:
|
||||||
|
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea,
|
||||||
|
create_activex_widget(view_menu), right_dock_area)
|
||||||
|
|
||||||
|
for dock_widget in self.dock_manager.dockWidgetsMap().values():
|
||||||
|
dock_widget.viewToggled.connect(self.on_view_toggled)
|
||||||
|
dock_widget.visibilityChanged.connect(self.on_view_visibility_changed)
|
||||||
|
|
||||||
|
def create_actions(self):
|
||||||
|
self.toolBar.addAction(self.actionSaveState)
|
||||||
|
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
||||||
|
self.actionSaveState.setIcon(svg_icon(":/adsdemo/images/save.svg"))
|
||||||
|
self.toolBar.addAction(self.actionRestoreState)
|
||||||
|
self.actionRestoreState.setIcon(svg_icon(":/adsdemo/images/restore.svg"))
|
||||||
|
|
||||||
|
self.save_perspective_action = QAction("Create Perspective", self)
|
||||||
|
self.save_perspective_action.setIcon(svg_icon(":/adsdemo/images/picture_in_picture.svg"))
|
||||||
|
self.save_perspective_action.triggered.connect(self.save_perspective)
|
||||||
|
self.perspective_list_action = QWidgetAction(self)
|
||||||
|
self.perspective_combo_box = QComboBox(self)
|
||||||
|
self.perspective_combo_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
self.perspective_combo_box.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
||||||
|
self.perspective_list_action.setDefaultWidget(self.perspective_combo_box)
|
||||||
|
self.toolBar.addSeparator()
|
||||||
|
self.toolBar.addAction(self.perspective_list_action)
|
||||||
|
self.toolBar.addAction(self.save_perspective_action)
|
||||||
|
|
||||||
|
a = self.toolBar.addAction("Create Editor")
|
||||||
|
a.setToolTip("Creates floating dynamic dockable editor windows that are deleted on close")
|
||||||
|
a.setIcon(svg_icon(":/adsdemo/images/note_add.svg"))
|
||||||
|
a.triggered.connect(self.create_editor)
|
||||||
|
|
||||||
|
a = self.toolBar.addAction("Create Table")
|
||||||
|
a.setToolTip("Creates floating dynamic dockable table with millions of entries")
|
||||||
|
a.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
||||||
|
a.triggered.connect(self.create_table)
|
||||||
|
|
||||||
|
def closeEvent(self, event: QCloseEvent):
|
||||||
|
self.save_state()
|
||||||
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
def on_action_save_state_triggered(state: bool):
|
||||||
|
qDebug("MainWindow::on_action_save_state_triggered")
|
||||||
|
self.save_state()
|
||||||
|
|
||||||
|
def on_action_restore_state_triggered(state: bool):
|
||||||
|
qDebug("MainWindow::on_action_restore_state_triggered")
|
||||||
|
self.restore_state()
|
||||||
|
|
||||||
|
def save_perspective(self):
|
||||||
|
perspective_name, ok = QInputDialog.getText(self, "Save perspective",
|
||||||
|
"Enter unique name:")
|
||||||
|
|
||||||
|
if ok and perspective_name:
|
||||||
|
self.dock_manager.addPerspective(perspective_name)
|
||||||
|
_ = QSignalBlocker(self.perspective_combo_box)
|
||||||
|
self.perspective_combo_box.clear()
|
||||||
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
||||||
|
self.perspective_combo_box.setCurrentText(perspective_name)
|
||||||
|
|
||||||
|
self.save_perspectives()
|
||||||
|
|
||||||
|
def on_view_toggled(self, open: bool):
|
||||||
|
dock_widget = self.sender()
|
||||||
|
if dock_widget is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
qDebug("{} view_toggled({})".format(dock_widget.objectName(), open))
|
||||||
|
|
||||||
|
def on_view_visibility_changed(self, visible: bool):
|
||||||
|
dock_widget = self.sender()
|
||||||
|
if dock_widget is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
qDebug("{} visibility_changed({})".format(dock_widget.objectName(), visible))
|
||||||
|
|
||||||
|
def create_editor(self):
|
||||||
|
dock_widget = create_editor_widget(self.menuView)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||||
|
floating_widget = self.dock_manager.addDockWidgetFloating(dock_widget)
|
||||||
|
floating_widget.move(QPoint(20, 20))
|
||||||
|
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
||||||
|
|
||||||
|
def on_editor_close_requested(self):
|
||||||
|
dock_widget = self.sender()
|
||||||
|
result = QMessageBox.question(self, "Close Editor",
|
||||||
|
"Editor {} contains unsaved changes? Would you like to close it?".format(dock_widget.windowTitle()))
|
||||||
|
if result == QMessageBox.Yes:
|
||||||
|
dock_widget.closeDockWidget()
|
||||||
|
|
||||||
|
def create_table(self):
|
||||||
|
dock_widget = create_table_widget(self.menuView)
|
||||||
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
||||||
|
floating_widget = self.dock_manager.addDockWidgetFloating(dock_widget)
|
||||||
|
floating_widget.move(QPoint(40, 40))
|
||||||
|
|
||||||
|
def save_state(self):
|
||||||
|
'''
|
||||||
|
Saves the dock manager state and the main window geometry
|
||||||
|
'''
|
||||||
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||||
|
settings.setValue("mainWindow/Geometry", self.saveGeometry())
|
||||||
|
settings.setValue("mainWindow/State", self.saveState())
|
||||||
|
settings.setValue("mainWindow/DockingState", self.dock_manager.saveState())
|
||||||
|
|
||||||
|
def restore_state(self):
|
||||||
|
'''
|
||||||
|
Restores the dock manager state
|
||||||
|
'''
|
||||||
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||||
|
geom = settings.value("mainWindow/Geometry")
|
||||||
|
if geom is not None:
|
||||||
|
self.restoreGeometry(geom)
|
||||||
|
|
||||||
|
state = settings.value("mainWindow/State")
|
||||||
|
if state is not None:
|
||||||
|
self.restoreState(state)
|
||||||
|
|
||||||
|
state = settings.value("mainWindow/DockingState")
|
||||||
|
if state is not None:
|
||||||
|
self.dock_manager.restore_state(state)
|
||||||
|
|
||||||
|
def save_perspectives(self):
|
||||||
|
'''
|
||||||
|
Save the list of perspectives
|
||||||
|
'''
|
||||||
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||||
|
self.dock_manager.savePerspectives(settings)
|
||||||
|
|
||||||
|
def restore_perspectives(self):
|
||||||
|
'''
|
||||||
|
Restore the perspective listo of the dock manager
|
||||||
|
'''
|
||||||
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||||
|
self.dock_manager.loadPerspectives(settings)
|
||||||
|
self.perspective_combo_box.clear()
|
||||||
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
||||||
|
|
||||||
|
def save_perspective(self):
|
||||||
|
perspective_name, ok = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
|
||||||
|
if ok and perspective_name:
|
||||||
|
self.dock_manager.addPerspective(perspective_name)
|
||||||
|
_ = QSignalBlocker(self.perspective_combo_box)
|
||||||
|
self.perspective_combo_box.clear()
|
||||||
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
||||||
|
self.perspective_combo_box.setCurrentText(perspective_name)
|
||||||
|
self.save_perspectives()
|
||||||
|
|
||||||
|
|
||||||
|
def my_message_output(type, context, msg):
|
||||||
|
if type == QtDebugMsg:
|
||||||
|
print("Debug: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
||||||
|
elif type == QtInfoMsg:
|
||||||
|
print("Info: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
||||||
|
elif type == QtWarningMsg:
|
||||||
|
print("Warning: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
||||||
|
elif type == QtCriticalMsg:
|
||||||
|
print("Critical: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
||||||
|
elif type == QtFatalMsg:
|
||||||
|
print("Fatal: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
||||||
|
QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
app.setQuitOnLastWindowClosed(True)
|
||||||
|
|
||||||
|
with open(os.path.join(os.path.dirname(__file__), "app.css"), "r") as style_sheet_file:
|
||||||
|
app.setStyleSheet(style_sheet_file.read())
|
||||||
|
|
||||||
|
qInstallMessageHandler(my_message_output)
|
||||||
|
qDebug("Message handler test")
|
||||||
|
|
||||||
|
mw = MainWindow()
|
||||||
|
mw.show()
|
||||||
|
app.exec_()
|
||||||
@@ -12,5 +12,6 @@
|
|||||||
<file>images/custom-menu-button.svg</file>
|
<file>images/custom-menu-button.svg</file>
|
||||||
<file>app.css</file>
|
<file>app.css</file>
|
||||||
<file>images/plus.svg</file>
|
<file>images/plus.svg</file>
|
||||||
|
<file>images/help_outline.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
6
demo/images/help_outline.svg
Normal file
6
demo/images/help_outline.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||||
|
<desc>help_outline icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||||
|
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||||
|
<path d="M938.67,512c0,235.52 -191.15,426.67 -426.67,426.67c-235.52,0 -426.67,-191.15 -426.67,-426.67c0,-235.52 191.15,-426.67 426.67,-426.67c235.52,0 426.67,191.15 426.67,426.67zM853.33,512c0,-188.16 -153.17,-341.33 -341.33,-341.33c-188.16,0 -341.33,153.17 -341.33,341.33c0,188.16 153.17,341.33 341.33,341.33c188.16,0 341.33,-153.17 341.33,-341.33zM682.67,426.67c0,106.67 -128,117.33 -128,213.33h-85.34c0,-138.67 128,-128 128,-213.33c0,-46.93 -38.4,-85.34 -85.33,-85.34c-46.93,0 -85.33,38.41 -85.33,85.34h-85.34c0,-94.29 76.38,-170.67 170.67,-170.67c94.29,0 170.67,76.38 170.67,170.67zM469.33,682.67h85.34v85.33h-85.34z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
doc/qmix_elements.png
Normal file
BIN
doc/qmix_elements.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 539 KiB |
BIN
doc/qt_design_studio.png
Normal file
BIN
doc/qt_design_studio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
52
example/example.py
Normal file
52
example/example.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PyQt5 import uic
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
|
from PyQt5.QtWidgets import QApplication, QLabel
|
||||||
|
|
||||||
|
from PyQtAds import QtAds
|
||||||
|
|
||||||
|
UI_FILE = os.path.join(os.path.dirname(__file__), 'MainWindow.ui')
|
||||||
|
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(MainWindowUI, MainWindowBase):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
# Create the dock manager. Because the parent parameter is a QMainWindow
|
||||||
|
# the dock manager registers itself as the central widget.
|
||||||
|
self.dock_manager = QtAds.CDockManager(self)
|
||||||
|
|
||||||
|
# Create example content label - this can be any application specific
|
||||||
|
# widget
|
||||||
|
l = QLabel()
|
||||||
|
l.setWordWrap(True)
|
||||||
|
l.setAlignment(Qt.AlignTop | Qt.AlignLeft);
|
||||||
|
l.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ")
|
||||||
|
|
||||||
|
# Create a dock widget with the title Label 1 and set the created label
|
||||||
|
# as the dock widget content
|
||||||
|
dock_widget = QtAds.CDockWidget("Label 1")
|
||||||
|
dock_widget.setWidget(l)
|
||||||
|
|
||||||
|
# Add the toggleViewAction of the dock widget to the menu to give
|
||||||
|
# the user the possibility to show the dock widget if it has been closed
|
||||||
|
self.menuView.addAction(dock_widget.toggleViewAction())
|
||||||
|
|
||||||
|
# Add the dock widget to the top dock widget area
|
||||||
|
self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, dock_widget)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
|
||||||
|
w = MainWindow()
|
||||||
|
w.show()
|
||||||
|
app.exec_()
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
{% set data = load_setup_py_data() %}
|
|
||||||
|
|
||||||
package:
|
|
||||||
name: pyqtads
|
|
||||||
version: {{ data.get('version') }}
|
|
||||||
|
|
||||||
source:
|
|
||||||
path: ../
|
|
||||||
|
|
||||||
build:
|
|
||||||
number: 0
|
|
||||||
script: python setup.py install --single-version-externally-managed --record=record.txt --conda-recipe
|
|
||||||
|
|
||||||
requirements:
|
|
||||||
build:
|
|
||||||
- python
|
|
||||||
- setuptools
|
|
||||||
- pyqt>=5.9
|
|
||||||
- sip>=4.19
|
|
||||||
run:
|
|
||||||
- python
|
|
||||||
- pyqt>=5.9
|
|
||||||
- sip>=4.19
|
|
||||||
- pywin32 [win]
|
|
||||||
|
|
||||||
test:
|
|
||||||
imports:
|
|
||||||
- PyQtAds
|
|
||||||
|
|
||||||
about:
|
|
||||||
home: {{ data.get('url') }}
|
|
||||||
license: {{ data.get('license') }}
|
|
||||||
license_family: LGPL
|
|
||||||
license_file: 'LICENSE.md'
|
|
||||||
summary: {{ data.get('description') }}
|
|
||||||
description: {{ data.get('description') }}
|
|
||||||
doc_url: ''
|
|
||||||
dev_url: {{ data.get('url') }}
|
|
||||||
|
|
||||||
extra:
|
|
||||||
recipe-maintainers: 'nicolas.elie@cnrs.fr'
|
|
||||||
70
setup.py
70
setup.py
@@ -18,7 +18,7 @@ from PyQt5.pyrcc_main import processResourceFile
|
|||||||
|
|
||||||
MODULE_NAME = "ads"
|
MODULE_NAME = "ads"
|
||||||
SRC_PATH = "PyQtAds"
|
SRC_PATH = "PyQtAds"
|
||||||
|
|
||||||
REQUIRE_PYQT = True
|
REQUIRE_PYQT = True
|
||||||
if "--conda-recipe" in sys.argv:
|
if "--conda-recipe" in sys.argv:
|
||||||
REQUIRE_PYQT = False
|
REQUIRE_PYQT = False
|
||||||
@@ -40,7 +40,7 @@ class HostPythonConfiguration(object):
|
|||||||
else:
|
else:
|
||||||
self.data_dir = sys.prefix + '/share'
|
self.data_dir = sys.prefix + '/share'
|
||||||
self.lib_dir = sys.prefix + '/lib'
|
self.lib_dir = sys.prefix + '/lib'
|
||||||
|
|
||||||
|
|
||||||
class TargetQtConfiguration(object):
|
class TargetQtConfiguration(object):
|
||||||
def __init__(self, qmake):
|
def __init__(self, qmake):
|
||||||
@@ -63,12 +63,12 @@ class TargetQtConfiguration(object):
|
|||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
pipe.close()
|
pipe.close()
|
||||||
|
|
||||||
|
|
||||||
class build_ext(sipdistutils.build_ext):
|
class build_ext(sipdistutils.build_ext):
|
||||||
|
|
||||||
description = "Builds the " + MODULE_NAME + " module."
|
description = "Builds the " + MODULE_NAME + " module."
|
||||||
|
|
||||||
user_options = sipdistutils.build_ext.user_options + [
|
user_options = sipdistutils.build_ext.user_options + [
|
||||||
('qmake-bin=', None, "Path to qmake binary"),
|
('qmake-bin=', None, "Path to qmake binary"),
|
||||||
('sip-bin=', None, "Path to sip binary"),
|
('sip-bin=', None, "Path to sip binary"),
|
||||||
@@ -78,7 +78,7 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
('sip-dir=', None, "Path to module's SIP files"),
|
('sip-dir=', None, "Path to module's SIP files"),
|
||||||
('inc-dir=', None, "Path to module's include files")
|
('inc-dir=', None, "Path to module's include files")
|
||||||
]
|
]
|
||||||
|
|
||||||
def initialize_options (self):
|
def initialize_options (self):
|
||||||
super().initialize_options()
|
super().initialize_options()
|
||||||
self.qmake_bin = 'qmake'
|
self.qmake_bin = 'qmake'
|
||||||
@@ -92,16 +92,16 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
self.inc_dir = None
|
self.inc_dir = None
|
||||||
self.pyconfig = HostPythonConfiguration()
|
self.pyconfig = HostPythonConfiguration()
|
||||||
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
|
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
|
||||||
self.config = sipconfig.Configuration()
|
self.config = sipconfig.Configuration()
|
||||||
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
|
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
|
||||||
(sys.version_info.major, sys.version_info.minor))
|
(sys.version_info.major, sys.version_info.minor))
|
||||||
|
|
||||||
def finalize_options (self):
|
def finalize_options (self):
|
||||||
super().finalize_options()
|
super().finalize_options()
|
||||||
|
|
||||||
if not self.qt_include_dir:
|
if not self.qt_include_dir:
|
||||||
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
|
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
|
||||||
|
|
||||||
if not self.qt_libinfix:
|
if not self.qt_libinfix:
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
|
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
|
||||||
@@ -113,16 +113,16 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
|
|
||||||
if not self.pyqt_sip_dir:
|
if not self.pyqt_sip_dir:
|
||||||
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
|
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
|
||||||
|
|
||||||
if not self.pyqt_sip_flags:
|
if not self.pyqt_sip_flags:
|
||||||
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
|
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
|
||||||
|
|
||||||
if not self.sip_files_dir:
|
if not self.sip_files_dir:
|
||||||
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
|
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
|
||||||
|
|
||||||
if not self.sip_inc_dir:
|
if not self.sip_inc_dir:
|
||||||
self.sip_inc_dir = self.pyconfig.venv_inc_dir
|
self.sip_inc_dir = self.pyconfig.venv_inc_dir
|
||||||
|
|
||||||
if not self.inc_dir:
|
if not self.inc_dir:
|
||||||
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
|
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
|
||||||
|
|
||||||
@@ -138,12 +138,12 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
if not self.pyqt_sip_flags:
|
if not self.pyqt_sip_flags:
|
||||||
raise SystemExit('Could not find PyQt SIP flags. '
|
raise SystemExit('Could not find PyQt SIP flags. '
|
||||||
'Please specify via --pyqt-sip-flags=')
|
'Please specify via --pyqt-sip-flags=')
|
||||||
|
|
||||||
def _find_sip(self):
|
def _find_sip(self):
|
||||||
"""override _find_sip to allow for manually speficied sip path."""
|
"""override _find_sip to allow for manually speficied sip path."""
|
||||||
return self.sip_bin or super()._find_sip()
|
return self.sip_bin or super()._find_sip()
|
||||||
|
|
||||||
def _sip_compile(self, sip_bin, source, sbf):
|
def _sip_compile(self, sip_bin, source, sbf):
|
||||||
cmd = [sip_bin]
|
cmd = [sip_bin]
|
||||||
if hasattr(self, 'sip_opts'):
|
if hasattr(self, 'sip_opts'):
|
||||||
cmd += self.sip_opts
|
cmd += self.sip_opts
|
||||||
@@ -157,11 +157,11 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
"-c", self._sip_output_dir(),
|
"-c", self._sip_output_dir(),
|
||||||
"-b", sbf,
|
"-b", sbf,
|
||||||
"-w", "-o"]
|
"-w", "-o"]
|
||||||
|
|
||||||
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
|
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
|
||||||
cmd.append(source)
|
cmd.append(source)
|
||||||
self.spawn(cmd)
|
self.spawn(cmd)
|
||||||
|
|
||||||
def swig_sources (self, sources, extension=None):
|
def swig_sources (self, sources, extension=None):
|
||||||
if not self.extensions:
|
if not self.extensions:
|
||||||
return
|
return
|
||||||
@@ -179,7 +179,7 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
extension.libraries += ['Qt5Core' + self.qt_libinfix,
|
extension.libraries += ['Qt5Core' + self.qt_libinfix,
|
||||||
'Qt5Gui' + self.qt_libinfix,
|
'Qt5Gui' + self.qt_libinfix,
|
||||||
'Qt5Widgets' + self.qt_libinfix]
|
'Qt5Widgets' + self.qt_libinfix]
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
|
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
|
||||||
self.inc_dir, self._sip_output_dir()]
|
self.inc_dir, self._sip_output_dir()]
|
||||||
@@ -192,30 +192,46 @@ class build_ext(sipdistutils.build_ext):
|
|||||||
extension.extra_compile_args += ['-std=c++11']
|
extension.extra_compile_args += ['-std=c++11']
|
||||||
|
|
||||||
return super().swig_sources(sources, extension)
|
return super().swig_sources(sources, extension)
|
||||||
|
|
||||||
def build_extension(self, ext):
|
def build_extension(self, ext):
|
||||||
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
|
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
|
||||||
|
|
||||||
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
|
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
|
||||||
|
|
||||||
|
def get_moc_args(out_file, source):
|
||||||
|
if sys.platform.startswith('linux'):
|
||||||
|
return ["moc", "-D", "Q_OS_LINUX=1", "-o", out_file, source]
|
||||||
|
if sys.platform.startswith('darwin'):
|
||||||
|
return ["moc", "-D", "Q_OS_MACOS=1", "-o", out_file, source]
|
||||||
|
if sys.platform.startswith('win'):
|
||||||
|
return ["moc", "-D", "Q_OS_WIN=1", "-o", out_file, source]
|
||||||
|
return ["moc", "-o", out_file, source]
|
||||||
|
|
||||||
# Run moc on all header files.
|
# Run moc on all header files.
|
||||||
for source in cppsources:
|
for source in cppsources:
|
||||||
|
# *.cpp -> *.moc
|
||||||
|
moc_file = os.path.basename(source).replace(".cpp", ".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.replace(".cpp", ".h")
|
header = source.replace(".cpp", ".h")
|
||||||
if os.path.exists(header):
|
if os.path.exists(header):
|
||||||
|
# *.h -> moc_*.cpp
|
||||||
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
|
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
|
||||||
out_file = os.path.join(self.build_temp, moc_file)
|
out_file = os.path.join(self.build_temp, moc_file)
|
||||||
|
|
||||||
if newer(header, out_file) or self.force:
|
if newer(header, out_file) or self.force:
|
||||||
call_arg = ["moc", "-o", out_file, header]
|
spawn.spawn(get_moc_args(out_file, header), dry_run=self.dry_run)
|
||||||
spawn.spawn(call_arg, dry_run=self.dry_run)
|
|
||||||
|
|
||||||
if os.path.getsize(out_file) > 0:
|
if os.path.getsize(out_file) > 0:
|
||||||
ext.sources.append(out_file)
|
ext.sources.append(out_file)
|
||||||
|
|
||||||
# Add the temp build directory to include path, for compiler to find
|
# Add the temp build directory to include path, for compiler to find
|
||||||
# the created .moc files
|
# the created .moc files
|
||||||
ext.include_dirs += [self._sip_output_dir()]
|
ext.include_dirs += [self._sip_output_dir()]
|
||||||
|
|
||||||
sipdistutils.build_ext.build_extension(self, ext)
|
sipdistutils.build_ext.build_extension(self, ext)
|
||||||
|
|
||||||
|
|
||||||
@@ -253,7 +269,7 @@ ext_modules = [Extension('PyQtAds.QtAds.ads', cpp_sources + sip_sources)]
|
|||||||
install_requires = ["PyQt5"]
|
install_requires = ["PyQt5"]
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
install_requires.append("pywin32")
|
install_requires.append("pywin32")
|
||||||
|
|
||||||
|
|
||||||
with open('README.md', 'r') as f:
|
with open('README.md', 'r') as f:
|
||||||
LONG_DESCRIPTION = f.read()
|
LONG_DESCRIPTION = f.read()
|
||||||
|
|||||||
82
simple.py
82
simple.py
@@ -1,82 +0,0 @@
|
|||||||
import logging
|
|
||||||
|
|
||||||
from PyQt5 import QtWidgets, QtCore
|
|
||||||
from PyQt5.QtCore import Qt
|
|
||||||
from PyQtAds import QtAds
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QtWidgets.QMainWindow):
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setup_ui()
|
|
||||||
self.dock_manager = QtAds.CDockManager(self)
|
|
||||||
|
|
||||||
self.dock_widgets = []
|
|
||||||
|
|
||||||
for label_text, area in (
|
|
||||||
('1 Top', QtAds.TopDockWidgetArea),
|
|
||||||
('2 Bottom', QtAds.BottomDockWidgetArea),
|
|
||||||
('3 Left', QtAds.LeftDockWidgetArea),
|
|
||||||
('4 Right', QtAds.RightDockWidgetArea),
|
|
||||||
):
|
|
||||||
# Create example content label - this can be any application specific
|
|
||||||
# widget
|
|
||||||
label = QtWidgets.QLabel()
|
|
||||||
label.setWordWrap(True)
|
|
||||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
|
||||||
label.setText(f"{label_text}: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ")
|
|
||||||
|
|
||||||
# Create a dock widget with the title Label 1 and set the created label
|
|
||||||
# as the dock widget content
|
|
||||||
dock_widget = QtAds.CDockWidget(label_text)
|
|
||||||
dock_widget.setWidget(label)
|
|
||||||
self.dock_widgets.append(dock_widget)
|
|
||||||
|
|
||||||
# Add the toggleViewAction of the dock widget to the menu to give
|
|
||||||
# the user the possibility to show the dock widget if it has been closed
|
|
||||||
self.menu_view.addAction(dock_widget.toggleViewAction())
|
|
||||||
|
|
||||||
# Add the dock widget to the top dock widget area
|
|
||||||
self.dock_manager.addDockWidget(area, dock_widget)
|
|
||||||
|
|
||||||
def setup_ui(self):
|
|
||||||
self.setWindowTitle("MainWindow")
|
|
||||||
self.setObjectName("MainWindow")
|
|
||||||
self.resize(400, 300)
|
|
||||||
self.central_widget = QtWidgets.QWidget(self)
|
|
||||||
self.central_widget.setObjectName("central_widget")
|
|
||||||
self.setCentralWidget(self.central_widget)
|
|
||||||
|
|
||||||
self.menu_bar = QtWidgets.QMenuBar(self)
|
|
||||||
self.menu_bar.setGeometry(QtCore.QRect(0, 0, 400, 21))
|
|
||||||
self.menu_bar.setObjectName("menuBar")
|
|
||||||
|
|
||||||
self.menu_view = QtWidgets.QMenu(self.menu_bar)
|
|
||||||
self.menu_view.setObjectName("menu_view")
|
|
||||||
self.menu_view.setTitle("View")
|
|
||||||
self.setMenuBar(self.menu_bar)
|
|
||||||
|
|
||||||
self.status_bar = QtWidgets.QStatusBar(self)
|
|
||||||
self.status_bar.setObjectName("statusBar")
|
|
||||||
self.setStatusBar(self.status_bar)
|
|
||||||
self.menu_bar.addAction(self.menu_view.menuAction())
|
|
||||||
|
|
||||||
|
|
||||||
def main(app):
|
|
||||||
main = MainWindow()
|
|
||||||
main.show()
|
|
||||||
state = main.dock_manager.saveState()
|
|
||||||
print('This is what the saved state looks like in XML:')
|
|
||||||
print(state)
|
|
||||||
print()
|
|
||||||
main.dock_manager.restoreState(state)
|
|
||||||
return main
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
logging.basicConfig(level='DEBUG')
|
|
||||||
app = QtWidgets.QApplication([])
|
|
||||||
window = main(app)
|
|
||||||
window.show()
|
|
||||||
print('shown')
|
|
||||||
app.exec_()
|
|
||||||
@@ -13,14 +13,6 @@ class CDockAreaTabBar : QScrollArea
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void wheelEvent(QWheelEvent* Event);
|
virtual void wheelEvent(QWheelEvent* Event);
|
||||||
virtual void mousePressEvent(QMouseEvent* ev);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* ev);
|
|
||||||
virtual void mouseMoveEvent(QMouseEvent* ev);
|
|
||||||
virtual void mouseDoubleClickEvent(QMouseEvent *event);
|
|
||||||
void startFloating(const QPoint& Offset);
|
|
||||||
ads::IFloatingWidget* makeAreaFloating(const QPoint& Offset,
|
|
||||||
ads::eDragState DragState);
|
|
||||||
ads::eDragState dragState() const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDockAreaTabBar(ads::CDockAreaWidget* parent /TransferThis/);
|
CDockAreaTabBar(ads::CDockAreaWidget* parent /TransferThis/);
|
||||||
@@ -35,6 +27,7 @@ public:
|
|||||||
bool isTabOpen(int Index) const;
|
bool isTabOpen(int Index) const;
|
||||||
virtual QSize minimumSizeHint() const;
|
virtual QSize minimumSizeHint() const;
|
||||||
virtual QSize sizeHint() const;
|
virtual QSize sizeHint() const;
|
||||||
|
void elidedChanged(bool elided);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentIndex(int Index);
|
void setCurrentIndex(int Index);
|
||||||
@@ -54,4 +47,4 @@ signals:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%End
|
%End
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ class CDockAreaTitleBar : QFrame
|
|||||||
#include <DockAreaTitleBar.h>
|
#include <DockAreaTitleBar.h>
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QMouseEvent* ev);
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent* ev);
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent* ev);
|
||||||
|
virtual void mouseDoubleClickEvent(QMouseEvent *event);
|
||||||
|
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void markTabsMenuOutdated();
|
void markTabsMenuOutdated();
|
||||||
|
|
||||||
@@ -20,7 +27,10 @@ public:
|
|||||||
virtual ~CDockAreaTitleBar();
|
virtual ~CDockAreaTitleBar();
|
||||||
ads::CDockAreaTabBar* tabBar() const;
|
ads::CDockAreaTabBar* tabBar() const;
|
||||||
QAbstractButton* button(ads::TitleBarButton which) const;
|
QAbstractButton* button(ads::TitleBarButton which) const;
|
||||||
|
void updateDockWidgetActionsButtons();
|
||||||
virtual void setVisible(bool Visible);
|
virtual void setVisible(bool Visible);
|
||||||
|
void insertWidget(int index, QWidget *widget /Transfer/ );
|
||||||
|
int indexOf(QWidget *widget) const;
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@@ -42,12 +42,16 @@ public:
|
|||||||
int currentIndex() const;
|
int currentIndex() const;
|
||||||
int indexOfFirstOpenDockWidget() const;
|
int indexOfFirstOpenDockWidget() const;
|
||||||
ads::CDockWidget* currentDockWidget() const;
|
ads::CDockWidget* currentDockWidget() const;
|
||||||
void setCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
void setCurrentDockWidget(ads::CDockWidget* DockWidget);
|
||||||
void saveState(QXmlStreamWriter& Stream) const;
|
void saveState(QXmlStreamWriter& Stream) const;
|
||||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
ads::CDockWidget::DockWidgetFeatures features(ads::eBitwiseOperator Mode = ads::BitwiseAnd) const;
|
||||||
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
|
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
|
||||||
virtual void setVisible(bool Visible);
|
virtual void setVisible(bool Visible);
|
||||||
|
|
||||||
|
void setAllowedAreas(DockWidgetAreas areas);
|
||||||
|
DockWidgetAreas allowedAreas() const;
|
||||||
|
CDockAreaTitleBar* titleBar() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentIndex(int index);
|
void setCurrentIndex(int index);
|
||||||
void closeArea();
|
void closeArea();
|
||||||
|
|||||||
26
sip/DockComponentsFactory.sip
Normal file
26
sip/DockComponentsFactory.sip
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
%If (Qt_5_0_0 -)
|
||||||
|
|
||||||
|
namespace ads
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDockComponentsFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <DockComponentsFactory.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~CDockComponentsFactory();
|
||||||
|
virtual CDockWidgetTab* createDockWidgetTab(CDockWidget* DockWidget /Transfer/ ) const;
|
||||||
|
virtual CDockAreaTabBar* createDockAreaTabBar(CDockAreaWidget* DockArea /Transfer/ ) const;
|
||||||
|
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea /Transfer/ ) const;
|
||||||
|
static const CDockComponentsFactory* factory();
|
||||||
|
static void setFactory(CDockComponentsFactory* Factory);
|
||||||
|
static void resetDefaultFactory();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
%End
|
||||||
@@ -23,13 +23,12 @@ protected:
|
|||||||
QSplitter* rootSplitter() const;
|
QSplitter* rootSplitter() const;
|
||||||
void createRootSplitter();
|
void createRootSplitter();
|
||||||
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||||
void dropWidget(QWidget* widget, const QPoint& TargetPos);
|
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
|
||||||
void addDockArea(ads::CDockAreaWidget* DockAreaWidget /Transfer/, ads::DockWidgetArea area = ads::CenterDockWidgetArea);
|
void addDockArea(ads::CDockAreaWidget* DockAreaWidget /Transfer/, ads::DockWidgetArea area = ads::CenterDockWidgetArea);
|
||||||
void removeDockArea(ads::CDockAreaWidget* area /Transfer/);
|
void removeDockArea(ads::CDockAreaWidget* area /TransferBack/);
|
||||||
void saveState(QXmlStreamWriter& Stream) const;
|
void saveState(QXmlStreamWriter& Stream) const;
|
||||||
bool restoreState(CDockingStateReader& Stream, bool Testing);
|
bool restoreState(CDockingStateReader& Stream, bool Testing);
|
||||||
ads::CDockAreaWidget* lastAddedDockAreaWidget(ads::DockWidgetArea area) const;
|
ads::CDockAreaWidget* lastAddedDockAreaWidget(ads::DockWidgetArea area) const;
|
||||||
bool hasTopLevelDockWidget() const;
|
|
||||||
ads::CDockWidget* topLevelDockWidget() const;
|
ads::CDockWidget* topLevelDockWidget() const;
|
||||||
ads::CDockAreaWidget* topLevelDockArea() const;
|
ads::CDockAreaWidget* topLevelDockArea() const;
|
||||||
QList<ads::CDockWidget*> dockWidgets() const;
|
QList<ads::CDockWidget*> dockWidgets() const;
|
||||||
@@ -88,6 +87,7 @@ public:
|
|||||||
* If all dock widgets in a dock area are closed, the dock area will be closed
|
* If all dock widgets in a dock area are closed, the dock area will be closed
|
||||||
*/
|
*/
|
||||||
QList<ads::CDockAreaWidget*> openedDockAreas() const;
|
QList<ads::CDockAreaWidget*> openedDockAreas() const;
|
||||||
|
bool hasTopLevelDockWidget() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of dock areas in this container
|
* Returns the number of dock areas in this container
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ protected:
|
|||||||
ads::CDockOverlay* containerOverlay() const;
|
ads::CDockOverlay* containerOverlay() const;
|
||||||
ads::CDockOverlay* dockAreaOverlay() const;
|
ads::CDockOverlay* dockAreaOverlay() const;
|
||||||
|
|
||||||
|
virtual void showEvent(QShowEvent *event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum eViewMenuInsertionOrder
|
enum eViewMenuInsertionOrder
|
||||||
{
|
{
|
||||||
@@ -143,7 +145,7 @@ public:
|
|||||||
|
|
||||||
enum eConfigFlag
|
enum eConfigFlag
|
||||||
{
|
{
|
||||||
ActiveTabHasCloseButton,
|
ActiveTabHasCloseButton,
|
||||||
DockAreaHasCloseButton,
|
DockAreaHasCloseButton,
|
||||||
DockAreaCloseButtonClosesTab,
|
DockAreaCloseButtonClosesTab,
|
||||||
OpaqueSplitterResize,
|
OpaqueSplitterResize,
|
||||||
@@ -152,13 +154,22 @@ public:
|
|||||||
TabCloseButtonIsToolButton,
|
TabCloseButtonIsToolButton,
|
||||||
AllTabsHaveCloseButton,
|
AllTabsHaveCloseButton,
|
||||||
RetainTabSizeWhenCloseButtonHidden,
|
RetainTabSizeWhenCloseButtonHidden,
|
||||||
OpaqueUndocking,
|
OpaqueUndocking,
|
||||||
DragPreviewIsDynamic,
|
DragPreviewIsDynamic,
|
||||||
DragPreviewShowsContentPixmap,
|
DragPreviewShowsContentPixmap,
|
||||||
DragPreviewHasWindowFrame,
|
DragPreviewHasWindowFrame,
|
||||||
DefaultConfig,
|
AlwaysShowTabs,
|
||||||
DefaultNonOpaqueConfig,
|
DockAreaHasUndockButton,
|
||||||
NonOpaqueWithWindowFrame,
|
DockAreaHasTabsMenuButton,
|
||||||
|
DockAreaHideDisabledButtons,
|
||||||
|
DockAreaDynamicTabsMenuButtonVisibility,
|
||||||
|
FloatingContainerHasWidgetTitle,
|
||||||
|
FloatingContainerHasWidgetIcon,
|
||||||
|
DefaultDockAreaButtons,
|
||||||
|
DefaultBaseConfig,
|
||||||
|
DefaultOpaqueConfig,
|
||||||
|
DefaultNonOpaqueConfig,
|
||||||
|
NonOpaqueWithWindowFrame,
|
||||||
};
|
};
|
||||||
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
|
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
|
||||||
|
|
||||||
@@ -167,6 +178,7 @@ public:
|
|||||||
static ads::CDockManager::ConfigFlags configFlags();
|
static ads::CDockManager::ConfigFlags configFlags();
|
||||||
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
|
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
|
||||||
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
|
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
|
||||||
|
static bool testConfigFlag(eConfigFlag Flag);
|
||||||
static ads::CIconProvider& iconProvider();
|
static ads::CIconProvider& iconProvider();
|
||||||
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
||||||
@@ -180,7 +192,7 @@ public:
|
|||||||
QMap<QString, ads::CDockWidget*> dockWidgetsMap() const;
|
QMap<QString, ads::CDockWidget*> dockWidgetsMap() const;
|
||||||
const QList<ads::CDockContainerWidget*> dockContainers() const;
|
const QList<ads::CDockContainerWidget*> dockContainers() const;
|
||||||
const QList<ads::CFloatingDockContainer*> floatingWidgets() const;
|
const QList<ads::CFloatingDockContainer*> floatingWidgets() const;
|
||||||
virtual unsigned int zOrderIndex() const;
|
unsigned int zOrderIndex() const;
|
||||||
QByteArray saveState(int version = 1) const;
|
QByteArray saveState(int version = 1) const;
|
||||||
bool restoreState(const QByteArray &state, int version = 1);
|
bool restoreState(const QByteArray &state, int version = 1);
|
||||||
void addPerspective(const QString& UniquePrespectiveName);
|
void addPerspective(const QString& UniquePrespectiveName);
|
||||||
@@ -206,6 +218,7 @@ signals:
|
|||||||
void stateRestored();
|
void stateRestored();
|
||||||
void openingPerspective(const QString& PerspectiveName);
|
void openingPerspective(const QString& PerspectiveName);
|
||||||
void perspectiveOpened(const QString& PerspectiveName);
|
void perspectiveOpened(const QString& PerspectiveName);
|
||||||
|
void floatingWidgetCreated(CFloatingDockContainer* FloatingWidget);
|
||||||
void dockAreaCreated(ads::CDockAreaWidget* DockArea);
|
void dockAreaCreated(ads::CDockAreaWidget* DockArea);
|
||||||
void dockWidgetAboutToBeRemoved(ads::CDockWidget* DockWidget);
|
void dockWidgetAboutToBeRemoved(ads::CDockWidget* DockWidget);
|
||||||
void dockWidgetRemoved(ads::CDockWidget* DockWidget);
|
void dockWidgetRemoved(ads::CDockWidget* DockWidget);
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ public:
|
|||||||
void setAllowedAreas(ads::DockWidgetAreas areas);
|
void setAllowedAreas(ads::DockWidgetAreas areas);
|
||||||
ads::DockWidgetAreas allowedAreas() const;
|
ads::DockWidgetAreas allowedAreas() const;
|
||||||
ads::DockWidgetArea dropAreaUnderCursor() const;
|
ads::DockWidgetArea dropAreaUnderCursor() const;
|
||||||
|
ads::DockWidgetArea visibleDropAreaUnderCursor() const;
|
||||||
ads::DockWidgetArea showOverlay(QWidget* target);
|
ads::DockWidgetArea showOverlay(QWidget* target);
|
||||||
void hideOverlay();
|
void hideOverlay();
|
||||||
void enableDropPreview(bool Enable);
|
void enableDropPreview(bool Enable);
|
||||||
|
bool dropPreviewEnabled() const;
|
||||||
QRect dropOverlayRect() const;
|
QRect dropOverlayRect() const;
|
||||||
virtual bool event(QEvent *e);
|
virtual bool event(QEvent *e);
|
||||||
|
|
||||||
@@ -58,6 +60,8 @@ protected:
|
|||||||
void setIconOverlayColor(const QColor& Color);
|
void setIconOverlayColor(const QColor& Color);
|
||||||
void setIconArrowColor(const QColor& Color);
|
void setIconArrowColor(const QColor& Color);
|
||||||
void setIconShadowColor(const QColor& Color);
|
void setIconShadowColor(const QColor& Color);
|
||||||
|
virtual void showEvent(QShowEvent* e);
|
||||||
|
void setAreaWidgets(const QHash<ads::DockWidgetArea, QWidget*>& widgets);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDockOverlayCross(ads::CDockOverlay* overlay /TransferThis/);
|
CDockOverlayCross(ads::CDockOverlay* overlay /TransferThis/);
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ public:
|
|||||||
CDockSplitter(Qt::Orientation orientation, QWidget *parent /TransferThis/ = 0);
|
CDockSplitter(Qt::Orientation orientation, QWidget *parent /TransferThis/ = 0);
|
||||||
virtual ~CDockSplitter();
|
virtual ~CDockSplitter();
|
||||||
bool hasVisibleContent() const;
|
bool hasVisibleContent() const;
|
||||||
|
QWidget* firstWidget() const;
|
||||||
|
QWidget* lastWidget() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ class CDockWidget : QFrame
|
|||||||
%End
|
%End
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setDockManager(ads::CDockManager* DockManager /Transfer/);
|
void setDockManager(ads::CDockManager* DockManager /Transfer/ );
|
||||||
void setDockArea(ads::CDockAreaWidget* DockArea /Transfer/);
|
void setDockArea(ads::CDockAreaWidget* DockArea /Transfer/ );
|
||||||
void setToggleViewActionChecked(bool Checked);
|
void setToggleViewActionChecked(bool Checked);
|
||||||
void saveState(QXmlStreamWriter& Stream) const;
|
void saveState(QXmlStreamWriter& Stream) const;
|
||||||
void flagAsUnassigned();
|
void flagAsUnassigned();
|
||||||
static void emitTopLevelEventForWidget(ads::CDockWidget* TopLevelDockWidget, bool Floating);
|
static void emitTopLevelEventForWidget(ads::CDockWidget* TopLevelDockWidget, bool Floating);
|
||||||
void emitTopLevelChanged(bool Floating);
|
void emitTopLevelChanged(bool Floating);
|
||||||
void setClosedState(bool Closed);
|
void setClosedState(bool Closed);
|
||||||
void toggleViewInternal(bool Open);
|
void toggleViewInternal(bool Open);
|
||||||
|
bool closeDockWidgetInternal(bool ForceClose = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DockWidgetFeature
|
enum DockWidgetFeature
|
||||||
@@ -29,7 +30,9 @@ public:
|
|||||||
DockWidgetMovable,
|
DockWidgetMovable,
|
||||||
DockWidgetFloatable,
|
DockWidgetFloatable,
|
||||||
DockWidgetDeleteOnClose,
|
DockWidgetDeleteOnClose,
|
||||||
AllDockWidgetFeatures,
|
CustomCloseHandling,
|
||||||
|
DefaultDockWidgetFeatures,
|
||||||
|
AllDockWidgetFeatures,
|
||||||
NoDockWidgetFeatures
|
NoDockWidgetFeatures
|
||||||
};
|
};
|
||||||
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
|
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
|
||||||
@@ -47,6 +50,12 @@ public:
|
|||||||
ForceScrollArea,
|
ForceScrollArea,
|
||||||
ForceNoScrollArea
|
ForceNoScrollArea
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eMinimumSizeHintMode
|
||||||
|
{
|
||||||
|
MinimumSizeHintFromDockWidget,
|
||||||
|
MinimumSizeHintFromContent
|
||||||
|
};
|
||||||
|
|
||||||
enum eToggleViewActionMode
|
enum eToggleViewActionMode
|
||||||
{
|
{
|
||||||
@@ -73,15 +82,19 @@ public:
|
|||||||
bool isClosed() const;
|
bool isClosed() const;
|
||||||
QAction* toggleViewAction() const;
|
QAction* toggleViewAction() const;
|
||||||
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
|
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
|
||||||
|
void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode);
|
||||||
void setIcon(const QIcon& Icon);
|
void setIcon(const QIcon& Icon);
|
||||||
QIcon icon() const;
|
QIcon icon() const;
|
||||||
QToolBar* toolBar() const;
|
QToolBar* toolBar() const;
|
||||||
QToolBar* createDefaultToolBar();
|
QToolBar* createDefaultToolBar();
|
||||||
void setToolBar(QToolBar* ToolBar);
|
void setToolBar(QToolBar* ToolBar /Transfer/ );
|
||||||
void setToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
|
void setToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
|
||||||
Qt::ToolButtonStyle toolBarStyle(ads::CDockWidget::eState State) const;
|
Qt::ToolButtonStyle toolBarStyle(ads::CDockWidget::eState State) const;
|
||||||
void setToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
|
void setToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
|
||||||
QSize toolBarIconSize(eState State) const;
|
QSize toolBarIconSize(eState State) const;
|
||||||
|
void setTitleBarActions(QList<QAction*> actions);
|
||||||
|
virtual QList<QAction*> titleBarActions() const;
|
||||||
|
|
||||||
void setTabToolTip(const QString &text);
|
void setTabToolTip(const QString &text);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -91,12 +104,14 @@ public slots:
|
|||||||
void toggleView(bool Open = true);
|
void toggleView(bool Open = true);
|
||||||
void setFloating();
|
void setFloating();
|
||||||
void deleteDockWidget();
|
void deleteDockWidget();
|
||||||
|
void closeDockWidget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void viewToggled(bool Open);
|
void viewToggled(bool Open);
|
||||||
void closed();
|
void closed();
|
||||||
void titleChanged(const QString& Title);
|
void titleChanged(const QString& Title);
|
||||||
void topLevelChanged(bool topLevel);
|
void topLevelChanged(bool topLevel);
|
||||||
|
void closeRequested();
|
||||||
void visibilityChanged(bool visible);
|
void visibilityChanged(bool visible);
|
||||||
void featuresChanged(ads::CDockWidget::DockWidgetFeatures features);
|
void featuresChanged(ads::CDockWidget::DockWidgetFeatures features);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,13 +23,14 @@ public:
|
|||||||
virtual ~CDockWidgetTab();
|
virtual ~CDockWidgetTab();
|
||||||
bool isActiveTab() const;
|
bool isActiveTab() const;
|
||||||
void setActiveTab(bool active);
|
void setActiveTab(bool active);
|
||||||
ads::CDockWidget* dockWidget() const;
|
|
||||||
void setDockAreaWidget(ads::CDockAreaWidget* DockArea /Transfer/);
|
void setDockAreaWidget(ads::CDockAreaWidget* DockArea /Transfer/);
|
||||||
ads::CDockAreaWidget* dockAreaWidget() const;
|
ads::CDockAreaWidget* dockAreaWidget() const;
|
||||||
|
ads::CDockWidget* dockWidget() const;
|
||||||
void setIcon(const QIcon& Icon);
|
void setIcon(const QIcon& Icon);
|
||||||
const QIcon& icon() const;
|
const QIcon& icon() const;
|
||||||
QString text() const;
|
QString text() const;
|
||||||
void setText(const QString& title);
|
void setText(const QString& title);
|
||||||
|
bool isTitleElided() const;
|
||||||
bool isClosable() const;
|
bool isClosable() const;
|
||||||
virtual bool event(QEvent *e);
|
virtual bool event(QEvent *e);
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ signals:
|
|||||||
void closeRequested();
|
void closeRequested();
|
||||||
void closeOtherTabsRequested();
|
void closeOtherTabsRequested();
|
||||||
void moved(const QPoint& GlobalPos);
|
void moved(const QPoint& GlobalPos);
|
||||||
|
void elidedChanged(bool elided);
|
||||||
}; // class DockWidgetTab
|
}; // class DockWidgetTab
|
||||||
};
|
};
|
||||||
// namespace ads
|
// namespace ads
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
virtual ~CElidingLabel();
|
virtual ~CElidingLabel();
|
||||||
Qt::TextElideMode elideMode() const;
|
Qt::TextElideMode elideMode() const;
|
||||||
void setElideMode(Qt::TextElideMode mode);
|
void setElideMode(Qt::TextElideMode mode);
|
||||||
|
bool isElided() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual QSize minimumSizeHint() const;
|
virtual QSize minimumSizeHint() const;
|
||||||
@@ -33,6 +33,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
void doubleClicked();
|
void doubleClicked();
|
||||||
|
void elidedChanged(bool elided);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
|
// NOTE: there is a separate sip/linux/FloatingDockContainer.sip as the base
|
||||||
|
// class for CFloatingDockContainer changes for Linux.
|
||||||
|
|
||||||
%Import QtWidgets/QtWidgetsmod.sip
|
%Import QtWidgets/QtWidgetsmod.sip
|
||||||
|
|
||||||
%If (Qt_5_0_0 -)
|
%If (Qt_5_0_0 -)
|
||||||
|
|
||||||
|
%If (WS_X11)
|
||||||
|
typedef QDockWidget tFloatingWidgetBase;
|
||||||
|
%End
|
||||||
|
%If (!WS_X11)
|
||||||
|
typedef QWidget tFloatingWidgetBase;
|
||||||
|
%End
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -20,7 +30,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CFloatingDockContainer : QWidget, ads::IFloatingWidget
|
class CFloatingDockContainer : tFloatingWidgetBase, ads::IFloatingWidget
|
||||||
{
|
{
|
||||||
|
|
||||||
%TypeHeaderCode
|
%TypeHeaderCode
|
||||||
@@ -46,7 +56,6 @@ protected:
|
|||||||
virtual void closeEvent(QCloseEvent *event);
|
virtual void closeEvent(QCloseEvent *event);
|
||||||
virtual void hideEvent(QHideEvent *event);
|
virtual void hideEvent(QHideEvent *event);
|
||||||
virtual void showEvent(QShowEvent *event);
|
virtual void showEvent(QShowEvent *event);
|
||||||
virtual bool eventFilter(QObject *watched, QEvent *event);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CFloatingDockContainer(ads::CDockManager* DockManager /TransferThis/);
|
CFloatingDockContainer(ads::CDockManager* DockManager /TransferThis/);
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ class CFloatingDragPreview : QWidget, ads::IFloatingWidget
|
|||||||
#include <FloatingDragPreview.h>
|
#include <FloatingDragPreview.h>
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void moveEvent(QMoveEvent *event);
|
||||||
|
virtual void paintEvent(QPaintEvent *e);
|
||||||
|
CFloatingDragPreview(QWidget* Content /TransferThis/, QWidget* parent /TransferThis/);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CFloatingDragPreview(ads::CDockWidget* Content /TransferThis/ );
|
CFloatingDragPreview(ads::CDockWidget* Content /TransferThis/ );
|
||||||
@@ -21,6 +25,7 @@ public:
|
|||||||
|
|
||||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||||
|
|
||||||
|
public: // implements IFloatingWidget
|
||||||
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||||
ads::eDragState DragState, QWidget* MouseEventHandler);
|
ads::eDragState DragState, QWidget* MouseEventHandler);
|
||||||
|
|
||||||
@@ -35,4 +40,4 @@ signals:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%End
|
%End
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
%Module(name=PyQtAds.QtAds.ads, call_super_init=True, keyword_arguments="Optional", use_limited_api=True)
|
%Module(name=PyQtAds.QtAds.ads, call_super_init=True, keyword_arguments="Optional", use_limited_api=True)
|
||||||
%Import QtCore/QtCoremod.sip
|
%Import QtCore/QtCoremod.sip
|
||||||
%DefaultSupertype sip.simplewrapper
|
%DefaultSupertype sip.simplewrapper
|
||||||
%Platforms {Linux macOS Windows}
|
|
||||||
|
|
||||||
%Include ads_globals.sip
|
%Include ads_globals.sip
|
||||||
%Include DockWidget.sip
|
%Include DockWidget.sip
|
||||||
%Include DockAreaTabBar.sip
|
%Include DockAreaTabBar.sip
|
||||||
%Include DockAreaTitleBar.sip
|
%Include DockAreaTitleBar.sip
|
||||||
%Include DockAreaWidget.sip
|
%Include DockAreaWidget.sip
|
||||||
|
%Include DockComponentsFactory.sip
|
||||||
%Include DockContainerWidget.sip
|
%Include DockContainerWidget.sip
|
||||||
%Include DockingStateReader.sip
|
%Include DockingStateReader.sip
|
||||||
%Include DockManager.sip
|
%Include DockManager.sip
|
||||||
@@ -18,6 +18,6 @@
|
|||||||
%Include FloatingDockContainer.sip
|
%Include FloatingDockContainer.sip
|
||||||
%Include FloatingDragPreview.sip
|
%Include FloatingDragPreview.sip
|
||||||
%Include IconProvider.sip
|
%Include IconProvider.sip
|
||||||
%If (Linux)
|
%If (WS_X11)
|
||||||
%Include linux/FloatingWidgetTitleBar.sip
|
%Include linux/FloatingWidgetTitleBar.sip
|
||||||
%End
|
%End
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ namespace ads
|
|||||||
#include <ads_globals.h>
|
#include <ads_globals.h>
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
enum eStateFileVersion
|
||||||
|
{
|
||||||
|
InitialVerison,
|
||||||
|
Version1,
|
||||||
|
CurrentVersion
|
||||||
|
};
|
||||||
|
|
||||||
enum DockWidgetArea
|
enum DockWidgetArea
|
||||||
{
|
{
|
||||||
NoDockWidgetArea,
|
NoDockWidgetArea,
|
||||||
@@ -49,6 +56,12 @@ namespace ads
|
|||||||
IconCount,
|
IconCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eBitwiseOperator
|
||||||
|
{
|
||||||
|
BitwiseAnd,
|
||||||
|
BitwiseOr
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%End
|
%End
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
%TypeHeaderCode
|
%TypeHeaderCode
|
||||||
#include <FloatingWidgetTitleBar.h>
|
#include <linux/FloatingWidgetTitleBar.h>
|
||||||
%End
|
%End
|
||||||
|
|
||||||
class CFloatingWidgetTitleBar : QWidget
|
class CFloatingWidgetTitleBar : QWidget
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
@@ -69,6 +70,16 @@ struct DockAreaTabBarPrivate
|
|||||||
* The function reassigns the stylesheet to update the tabs
|
* The function reassigns the stylesheet to update the tabs
|
||||||
*/
|
*/
|
||||||
void updateTabs();
|
void updateTabs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function to access first tab
|
||||||
|
*/
|
||||||
|
CDockWidgetTab* firstTab() const {return _this->tab(0);}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function to access last tab
|
||||||
|
*/
|
||||||
|
CDockWidgetTab* lastTab() const {return _this->tab(_this->count() - 1);}
|
||||||
};
|
};
|
||||||
// struct DockAreaTabBarPrivate
|
// struct DockAreaTabBarPrivate
|
||||||
|
|
||||||
@@ -366,6 +377,8 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
|
|||||||
|
|
||||||
int fromIndex = d->TabsLayout->indexOf(MovingTab);
|
int fromIndex = d->TabsLayout->indexOf(MovingTab);
|
||||||
auto MousePos = mapFromGlobal(GlobalPos);
|
auto MousePos = mapFromGlobal(GlobalPos);
|
||||||
|
MousePos.rx() = qMax(d->firstTab()->geometry().left(), MousePos.x());
|
||||||
|
MousePos.rx() = qMin(d->lastTab()->geometry().right(), MousePos.x());
|
||||||
int toIndex = -1;
|
int toIndex = -1;
|
||||||
// Find tab under mouse
|
// Find tab under mouse
|
||||||
for (int i = 0; i < count(); ++i)
|
for (int i = 0; i < count(); ++i)
|
||||||
@@ -381,38 +394,23 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
|
|||||||
if (toIndex == fromIndex)
|
if (toIndex == fromIndex)
|
||||||
{
|
{
|
||||||
toIndex = -1;
|
toIndex = -1;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toIndex < 0)
|
|
||||||
{
|
|
||||||
toIndex = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check if the mouse is behind the last tab
|
if (toIndex > -1)
|
||||||
if (toIndex < 0)
|
|
||||||
{
|
|
||||||
if (MousePos.x() > tab(count() - 1)->geometry().right())
|
|
||||||
{
|
|
||||||
ADS_PRINT("after all tabs");
|
|
||||||
toIndex = count() - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toIndex = fromIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d->TabsLayout->removeWidget(MovingTab);
|
|
||||||
d->TabsLayout->insertWidget(toIndex, MovingTab);
|
|
||||||
if (toIndex >= 0)
|
|
||||||
{
|
{
|
||||||
|
d->TabsLayout->removeWidget(MovingTab);
|
||||||
|
d->TabsLayout->insertWidget(toIndex, MovingTab);
|
||||||
ADS_PRINT("tabMoved from " << fromIndex << " to " << toIndex);
|
ADS_PRINT("tabMoved from " << fromIndex << " to " << toIndex);
|
||||||
emit tabMoved(fromIndex, toIndex);
|
emit tabMoved(fromIndex, toIndex);
|
||||||
setCurrentIndex(toIndex);
|
setCurrentIndex(toIndex);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Ensure that the moved tab is reset to its start position
|
||||||
|
d->TabsLayout->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#include "DockWidgetTab.h"
|
#include "DockWidgetTab.h"
|
||||||
#include "DockAreaTabBar.h"
|
#include "DockAreaTabBar.h"
|
||||||
#include "IconProvider.h"
|
#include "IconProvider.h"
|
||||||
|
#include "DockComponentsFactory.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -234,7 +235,7 @@ void DockAreaTitleBarPrivate::createButtons()
|
|||||||
#endif
|
#endif
|
||||||
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
|
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
|
||||||
TabsMenuButton->setMenu(TabsMenu);
|
TabsMenuButton->setMenu(TabsMenu);
|
||||||
internal::setToolTip(TabsMenuButton, QObject::tr("List all tabs"));
|
internal::setToolTip(TabsMenuButton, QObject::tr("List All Tabs"));
|
||||||
TabsMenuButton->setSizePolicy(ButtonSizePolicy);
|
TabsMenuButton->setSizePolicy(ButtonSizePolicy);
|
||||||
Layout->addWidget(TabsMenuButton, 0);
|
Layout->addWidget(TabsMenuButton, 0);
|
||||||
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
|
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
|
||||||
@@ -273,7 +274,7 @@ void DockAreaTitleBarPrivate::createButtons()
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void DockAreaTitleBarPrivate::createTabBar()
|
void DockAreaTitleBarPrivate::createTabBar()
|
||||||
{
|
{
|
||||||
TabBar = new CDockAreaTabBar(DockArea);
|
TabBar = componentsFactory()->createDockAreaTabBar(DockArea);
|
||||||
TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||||
Layout->addWidget(TabBar);
|
Layout->addWidget(TabBar);
|
||||||
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
|
_this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
|
||||||
@@ -599,7 +600,11 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
|||||||
|
|
||||||
// If one single dock widget in this area is not floatable then the whole
|
// If one single dock widget in this area is not floatable then the whole
|
||||||
// area is not floatable
|
// area is not floatable
|
||||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
// If we do non opaque undocking, then we can create the floating drag
|
||||||
|
// preview if the dock widget is movable
|
||||||
|
auto Features = d->DockArea->features();
|
||||||
|
if (!Features.testFlag(CDockWidget::DockWidgetFloatable)
|
||||||
|
&& !(Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,10 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include "DockWidgetTab.h"
|
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <QStackedLayout>
|
#include <QStackedLayout>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
@@ -53,8 +54,8 @@
|
|||||||
#include "DockAreaTabBar.h"
|
#include "DockAreaTabBar.h"
|
||||||
#include "DockSplitter.h"
|
#include "DockSplitter.h"
|
||||||
#include "DockAreaTitleBar.h"
|
#include "DockAreaTitleBar.h"
|
||||||
|
#include "DockComponentsFactory.h"
|
||||||
#include <iostream>
|
#include "DockWidgetTab.h"
|
||||||
|
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
@@ -246,6 +247,7 @@ struct DockAreaWidgetPrivate
|
|||||||
CDockManager* DockManager = nullptr;
|
CDockManager* DockManager = nullptr;
|
||||||
bool UpdateTitleBarButtons = false;
|
bool UpdateTitleBarButtons = false;
|
||||||
DockWidgetAreas AllowedAreas = AllDockAreas;
|
DockWidgetAreas AllowedAreas = AllDockAreas;
|
||||||
|
QSize MinSizeHint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@@ -262,7 +264,7 @@ struct DockAreaWidgetPrivate
|
|||||||
*/
|
*/
|
||||||
CDockWidget* dockWidgetAt(int index)
|
CDockWidget* dockWidgetAt(int index)
|
||||||
{
|
{
|
||||||
return dynamic_cast<CDockWidget*>(ContentsLayout->widget(index));
|
return qobject_cast<CDockWidget*>(ContentsLayout->widget(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,6 +304,20 @@ struct DockAreaWidgetPrivate
|
|||||||
* Udpates the enable state of the close and detach button
|
* Udpates the enable state of the close and detach button
|
||||||
*/
|
*/
|
||||||
void updateTitleBarButtonStates();
|
void updateTitleBarButtonStates();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans all contained dock widgets for the max. minimum size hint
|
||||||
|
*/
|
||||||
|
void updateMinimumSizeHint()
|
||||||
|
{
|
||||||
|
MinSizeHint = QSize();
|
||||||
|
for (int i = 0; i < ContentsLayout->count(); ++i)
|
||||||
|
{
|
||||||
|
auto Widget = ContentsLayout->widget(i);
|
||||||
|
MinSizeHint.setHeight(qMax(MinSizeHint.height(), Widget->minimumSizeHint().height()));
|
||||||
|
MinSizeHint.setWidth(qMax(MinSizeHint.width(), Widget->minimumSizeHint().width()));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// struct DockAreaWidgetPrivate
|
// struct DockAreaWidgetPrivate
|
||||||
|
|
||||||
@@ -317,7 +333,7 @@ DockAreaWidgetPrivate::DockAreaWidgetPrivate(CDockAreaWidget* _public) :
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void DockAreaWidgetPrivate::createTitleBar()
|
void DockAreaWidgetPrivate::createTitleBar()
|
||||||
{
|
{
|
||||||
TitleBar = new CDockAreaTitleBar(_this);
|
TitleBar = componentsFactory()->createDockAreaTitleBar(_this);
|
||||||
Layout->addWidget(TitleBar);
|
Layout->addWidget(TitleBar);
|
||||||
QObject::connect(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested);
|
QObject::connect(tabBar(), &CDockAreaTabBar::tabCloseRequested, _this, &CDockAreaWidget::onTabCloseRequested);
|
||||||
QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex);
|
QObject::connect(TitleBar, &CDockAreaTitleBar::tabBarClicked, _this, &CDockAreaWidget::setCurrentIndex);
|
||||||
@@ -406,6 +422,8 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
|||||||
d->tabBar()->blockSignals(false);
|
d->tabBar()->blockSignals(false);
|
||||||
TabWidget->setVisible(!DockWidget->isClosed());
|
TabWidget->setVisible(!DockWidget->isClosed());
|
||||||
DockWidget->setProperty(INDEX_PROPERTY, index);
|
DockWidget->setProperty(INDEX_PROPERTY, index);
|
||||||
|
d->MinSizeHint.setHeight(qMax(d->MinSizeHint.height(), DockWidget->minimumSizeHint().height()));
|
||||||
|
d->MinSizeHint.setWidth(qMax(d->MinSizeHint.width(), DockWidget->minimumSizeHint().width()));
|
||||||
if (Activate)
|
if (Activate)
|
||||||
{
|
{
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
@@ -446,6 +464,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
|||||||
|
|
||||||
d->updateTitleBarButtonStates();
|
d->updateTitleBarButtonStates();
|
||||||
updateTitleBarVisibility();
|
updateTitleBarVisibility();
|
||||||
|
d->updateMinimumSizeHint();
|
||||||
auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
|
auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
|
||||||
if (TopLevelDockWidget)
|
if (TopLevelDockWidget)
|
||||||
{
|
{
|
||||||
@@ -496,7 +515,6 @@ void CDockAreaWidget::onTabCloseRequested(int Index)
|
|||||||
auto* DockWidget = dockWidget(Index);
|
auto* DockWidget = dockWidget(Index);
|
||||||
if (DockWidget->features().testFlag(CDockWidget::DockWidgetDeleteOnClose))
|
if (DockWidget->features().testFlag(CDockWidget::DockWidgetDeleteOnClose))
|
||||||
{
|
{
|
||||||
//DockWidget->deleteDockWidget();
|
|
||||||
DockWidget->closeDockWidgetInternal();
|
DockWidget->closeDockWidgetInternal();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -863,6 +881,13 @@ CDockAreaTitleBar* CDockAreaWidget::titleBar() const
|
|||||||
{
|
{
|
||||||
return d->TitleBar;
|
return d->TitleBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
QSize CDockAreaWidget::minimumSizeHint() const
|
||||||
|
{
|
||||||
|
return d->MinSizeHint.isValid() ? d->MinSizeHint : Super::minimumSizeHint();
|
||||||
|
}
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -164,6 +164,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
CDockContainerWidget* dockContainer() const;
|
CDockContainerWidget* dockContainer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest minimumSizeHint() of the dock widgets in this
|
||||||
|
* area.
|
||||||
|
* The minimum size hint is updated if a dock widget is removed or added.
|
||||||
|
*/
|
||||||
|
virtual QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rectangle of the title area
|
* Returns the rectangle of the title area
|
||||||
*/
|
*/
|
||||||
|
|||||||
69
src/DockComponentsFactory.cpp
Normal file
69
src/DockComponentsFactory.cpp
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
//============================================================================
|
||||||
|
/// \file DockComponentsFactory.cpp
|
||||||
|
/// \author Uwe Kindler
|
||||||
|
/// \date 10.02.2020
|
||||||
|
/// \brief Implementation of DockComponentsFactory
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// INCLUDES
|
||||||
|
//============================================================================
|
||||||
|
#include <DockComponentsFactory.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "DockWidgetTab.h"
|
||||||
|
#include "DockAreaTabBar.h"
|
||||||
|
#include "DockAreaTitleBar.h"
|
||||||
|
#include "DockWidget.h"
|
||||||
|
#include "DockAreaWidget.h"
|
||||||
|
|
||||||
|
namespace ads
|
||||||
|
{
|
||||||
|
static std::unique_ptr<CDockComponentsFactory> DefaultFactory(new CDockComponentsFactory());
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockWidgetTab* CDockComponentsFactory::createDockWidgetTab(CDockWidget* DockWidget) const
|
||||||
|
{
|
||||||
|
return new CDockWidgetTab(DockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockAreaTabBar* CDockComponentsFactory::createDockAreaTabBar(CDockAreaWidget* DockArea) const
|
||||||
|
{
|
||||||
|
return new CDockAreaTabBar(DockArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
CDockAreaTitleBar* CDockComponentsFactory::createDockAreaTitleBar(CDockAreaWidget* DockArea) const
|
||||||
|
{
|
||||||
|
return new CDockAreaTitleBar(DockArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
const CDockComponentsFactory* CDockComponentsFactory::factory()
|
||||||
|
{
|
||||||
|
return DefaultFactory.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockComponentsFactory::setFactory(CDockComponentsFactory* Factory)
|
||||||
|
{
|
||||||
|
DefaultFactory.reset(Factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockComponentsFactory::resetDefaultFactory()
|
||||||
|
{
|
||||||
|
DefaultFactory.reset(new CDockComponentsFactory());
|
||||||
|
}
|
||||||
|
} // namespace ads
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// EOF DockComponentsFactory.cpp
|
||||||
90
src/DockComponentsFactory.h
Normal file
90
src/DockComponentsFactory.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#ifndef DockComponentsFactoryH
|
||||||
|
#define DockComponentsFactoryH
|
||||||
|
//============================================================================
|
||||||
|
/// \file DockComponentsFactory.h
|
||||||
|
/// \author Uwe Kindler
|
||||||
|
/// \date 10.02.2020
|
||||||
|
/// \brief Declaration of DockComponentsFactory
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// INCLUDES
|
||||||
|
//============================================================================
|
||||||
|
#include "ads_globals.h"
|
||||||
|
|
||||||
|
namespace ads
|
||||||
|
{
|
||||||
|
class CDockWidgetTab;
|
||||||
|
class CDockAreaTitleBar;
|
||||||
|
class CDockAreaTabBar;
|
||||||
|
class CDockAreaWidget;
|
||||||
|
class CDockWidget;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for creation of certain GUI elements for the docking framework.
|
||||||
|
* A default unique instance provided by CDockComponentsFactory is used for
|
||||||
|
* creation of all supported components. To inject your custom components,
|
||||||
|
* you can create your own derived dock components factory and register
|
||||||
|
* it via setDefaultFactory() function.
|
||||||
|
* \code
|
||||||
|
* CDockComponentsFactory::setDefaultFactory(new MyComponentsFactory()));
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class ADS_EXPORT CDockComponentsFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Force virtual destructor
|
||||||
|
*/
|
||||||
|
virtual ~CDockComponentsFactory() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This default implementation just creates a dock widget tab with
|
||||||
|
* new CDockWidgetTab(DockWIdget).
|
||||||
|
*/
|
||||||
|
virtual CDockWidgetTab* createDockWidgetTab(CDockWidget* DockWidget) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This default implementation just creates a dock area tab bar with
|
||||||
|
* new CDockAreaTabBar(DockArea).
|
||||||
|
*/
|
||||||
|
virtual CDockAreaTabBar* createDockAreaTabBar(CDockAreaWidget* DockArea) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This default implementation just creates a dock area title bar with
|
||||||
|
* new CDockAreaTitleBar(DockArea).
|
||||||
|
*/
|
||||||
|
virtual CDockAreaTitleBar* createDockAreaTitleBar(CDockAreaWidget* DockArea) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default components factory
|
||||||
|
*/
|
||||||
|
static const CDockComponentsFactory* factory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new default factory for creation of GUI elements.
|
||||||
|
* This function takes ownership of the given Factory.
|
||||||
|
*/
|
||||||
|
static void setFactory(CDockComponentsFactory* Factory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the current factory to the
|
||||||
|
*/
|
||||||
|
static void resetDefaultFactory();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function to ease factory instance access
|
||||||
|
*/
|
||||||
|
inline const CDockComponentsFactory* componentsFactory()
|
||||||
|
{
|
||||||
|
return CDockComponentsFactory::factory();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ads
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#endif // DockComponentsFactoryH
|
||||||
@@ -679,6 +679,23 @@ void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// We check, if we insert the dropped widget into the same place that
|
||||||
|
// it already has and do nothing, if it is the same place. It would
|
||||||
|
// also work without this check, but it looks nicer with the check
|
||||||
|
// because there will be no layout updates
|
||||||
|
auto Splitter = internal::findParent<CDockSplitter*>(DroppedDockArea);
|
||||||
|
auto InsertParam = internal::dockAreaInsertParameters(area);
|
||||||
|
if (Splitter == RootSplitter && InsertParam.orientation() == Splitter->orientation())
|
||||||
|
{
|
||||||
|
if (InsertParam.append() && Splitter->lastWidget() == DroppedDockArea)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!InsertParam.append() && Splitter->firstWidget() == DroppedDockArea)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea);
|
DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea);
|
||||||
NewDockArea = DroppedDockArea;
|
NewDockArea = DroppedDockArea;
|
||||||
}
|
}
|
||||||
@@ -736,7 +753,7 @@ void DockContainerWidgetPrivate::appendDockAreas(const QList<CDockAreaWidget*> N
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidget* Widget)
|
void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidget* Widget)
|
||||||
{
|
{
|
||||||
QSplitter* Splitter = dynamic_cast<QSplitter*>(Widget);
|
QSplitter* Splitter = qobject_cast<QSplitter*>(Widget);
|
||||||
if (Splitter)
|
if (Splitter)
|
||||||
{
|
{
|
||||||
s.writeStartElement("Splitter");
|
s.writeStartElement("Splitter");
|
||||||
@@ -759,7 +776,7 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(Widget);
|
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||||
if (DockArea)
|
if (DockArea)
|
||||||
{
|
{
|
||||||
DockArea->saveState(s);
|
DockArea->saveState(s);
|
||||||
@@ -1046,7 +1063,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
|||||||
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
||||||
{
|
{
|
||||||
#if defined(QT_DEBUG)
|
#if defined(QT_DEBUG)
|
||||||
QSplitter* Splitter = dynamic_cast<QSplitter*>(widget);
|
QSplitter* Splitter = qobject_cast<QSplitter*>(widget);
|
||||||
QByteArray buf;
|
QByteArray buf;
|
||||||
buf.fill(' ', level * 4);
|
buf.fill(' ', level * 4);
|
||||||
if (Splitter)
|
if (Splitter)
|
||||||
@@ -1069,7 +1086,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(widget);
|
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(widget);
|
||||||
if (!DockArea)
|
if (!DockArea)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -1285,7 +1302,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWidget* widget = Splitter->widget(0);
|
QWidget* widget = Splitter->widget(0);
|
||||||
QSplitter* ChildSplitter = dynamic_cast<QSplitter*>(widget);
|
QSplitter* ChildSplitter = qobject_cast<QSplitter*>(widget);
|
||||||
// If the one and only content widget of the splitter is not a splitter
|
// If the one and only content widget of the splitter is not a splitter
|
||||||
// then we are finished
|
// then we are finished
|
||||||
if (!ChildSplitter)
|
if (!ChildSplitter)
|
||||||
@@ -1436,41 +1453,16 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockContainerWidget::dropWidget(QWidget* Widget, const QPoint& TargetPos)
|
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
|
||||||
{
|
{
|
||||||
ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
|
|
||||||
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
||||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
if (TargetAreaWidget)
|
||||||
auto dropArea = InvalidDockWidgetArea;
|
|
||||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
|
||||||
|
|
||||||
if (DockArea)
|
|
||||||
{
|
{
|
||||||
auto dropOverlay = d->DockManager->dockAreaOverlay();
|
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
|
||||||
dropOverlay->setAllowedAreas(DockArea->allowedAreas());
|
|
||||||
dropArea = dropOverlay->showOverlay(DockArea);
|
|
||||||
if (ContainerDropArea != InvalidDockWidgetArea &&
|
|
||||||
ContainerDropArea != dropArea)
|
|
||||||
{
|
|
||||||
dropArea = InvalidDockWidgetArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dropArea != InvalidDockWidgetArea)
|
|
||||||
{
|
|
||||||
ADS_PRINT("Dock Area Drop Content: " << dropArea);
|
|
||||||
d->moveToNewSection(Widget, DockArea, dropArea);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// mouse is over container
|
|
||||||
if (InvalidDockWidgetArea == dropArea)
|
|
||||||
{
|
{
|
||||||
dropArea = ContainerDropArea;
|
d->moveToContainer(Widget, DropArea);
|
||||||
ADS_PRINT("Container Drop Content: " << dropArea);
|
|
||||||
if (dropArea != InvalidDockWidgetArea)
|
|
||||||
{
|
|
||||||
d->moveToContainer(Widget, dropArea);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there was a top level widget before the drop, then it is not top
|
// If there was a top level widget before the drop, then it is not top
|
||||||
@@ -1573,7 +1565,7 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
|
|||||||
|
|
||||||
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
||||||
QSplitter* OldRoot = d->RootSplitter;
|
QSplitter* OldRoot = d->RootSplitter;
|
||||||
d->RootSplitter = dynamic_cast<QSplitter*>(NewRootSplitter);
|
d->RootSplitter = qobject_cast<QSplitter*>(NewRootSplitter);
|
||||||
OldRoot->deleteLater();
|
OldRoot->deleteLater();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -96,9 +96,13 @@ protected:
|
|||||||
void dropFloatingWidget(CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
void dropFloatingWidget(CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop a dock area or a dock widget given in widget parameter
|
* Drop a dock area or a dock widget given in widget parameter.
|
||||||
|
* If the TargetAreaWidget is a nullptr, then the DropArea indicates
|
||||||
|
* the drop area for the container. If the given TargetAreaWidget is not
|
||||||
|
* a nullptr, then the DropArea indicates the drop area in the given
|
||||||
|
* TargetAreaWidget
|
||||||
*/
|
*/
|
||||||
void dropWidget(QWidget* Widget, const QPoint& TargetPos);
|
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given dock area to this container widget
|
* Adds the given dock area to this container widget
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
{
|
{
|
||||||
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultOpaqueConfig;
|
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data class of CDockManager class (pimpl)
|
* Private data class of CDockManager class (pimpl)
|
||||||
@@ -411,7 +411,7 @@ CDockManager::CDockManager(QWidget *parent) :
|
|||||||
d(new DockManagerPrivate(this))
|
d(new DockManagerPrivate(this))
|
||||||
{
|
{
|
||||||
createRootSplitter();
|
createRootSplitter();
|
||||||
QMainWindow* MainWindow = dynamic_cast<QMainWindow*>(parent);
|
QMainWindow* MainWindow = qobject_cast<QMainWindow*>(parent);
|
||||||
if (MainWindow)
|
if (MainWindow)
|
||||||
{
|
{
|
||||||
MainWindow->setCentralWidget(this);
|
MainWindow->setCentralWidget(this);
|
||||||
@@ -440,6 +440,7 @@ CDockManager::~CDockManager()
|
|||||||
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
||||||
{
|
{
|
||||||
d->FloatingWidgets.append(FloatingWidget);
|
d->FloatingWidgets.append(FloatingWidget);
|
||||||
|
emit floatingWidgetCreated(FloatingWidget);
|
||||||
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
|
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,6 +778,10 @@ QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
|
|||||||
d->addActionToMenu(GroupMenu->menuAction(), d->ViewMenu, AlphabeticallySorted);
|
d->addActionToMenu(GroupMenu->menuAction(), d->ViewMenu, AlphabeticallySorted);
|
||||||
d->ViewMenuGroups.insert(Group, GroupMenu);
|
d->ViewMenuGroups.insert(Group, GroupMenu);
|
||||||
}
|
}
|
||||||
|
else if (GroupMenu->icon().isNull() && !GroupIcon.isNull())
|
||||||
|
{
|
||||||
|
GroupMenu->setIcon(GroupIcon);
|
||||||
|
}
|
||||||
|
|
||||||
d->addActionToMenu(ToggleViewAction, GroupMenu, AlphabeticallySorted);
|
d->addActionToMenu(ToggleViewAction, GroupMenu, AlphabeticallySorted);
|
||||||
return GroupMenu->menuAction();
|
return GroupMenu->menuAction();
|
||||||
|
|||||||
@@ -30,18 +30,11 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include <ads_globals.h>
|
#include "ads_globals.h"
|
||||||
#include <DockContainerWidget.h>
|
#include "DockContainerWidget.h"
|
||||||
#include <DockWidget.h>
|
#include "DockWidget.h"
|
||||||
#include <FloatingDockContainer.h>
|
#include "FloatingDockContainer.h"
|
||||||
#include <qbytearray.h>
|
|
||||||
#include <qflags.h>
|
|
||||||
#include <qlist.h>
|
|
||||||
#include <qmap.h>
|
|
||||||
#include <qobjectdefs.h>
|
|
||||||
#include <qstring.h>
|
|
||||||
#include <qstringlist.h>
|
|
||||||
#include <QtGui/qicon.h>
|
|
||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
@@ -59,6 +52,7 @@ class CDockWidgetTab;
|
|||||||
struct DockWidgetTabPrivate;
|
struct DockWidgetTabPrivate;
|
||||||
struct DockAreaWidgetPrivate;
|
struct DockAreaWidgetPrivate;
|
||||||
class CIconProvider;
|
class CIconProvider;
|
||||||
|
class CDockComponentsFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central dock manager that maintains the complete docking system.
|
* The central dock manager that maintains the complete docking system.
|
||||||
@@ -141,6 +135,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* These global configuration flags configure some global dock manager
|
* These global configuration flags configure some global dock manager
|
||||||
* settings.
|
* settings.
|
||||||
|
* Set the dock manager flags, before you create the dock manager instance.
|
||||||
*/
|
*/
|
||||||
enum eConfigFlag
|
enum eConfigFlag
|
||||||
{
|
{
|
||||||
@@ -162,6 +157,8 @@ public:
|
|||||||
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
|
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
|
||||||
DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
|
DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
|
||||||
DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
|
DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
|
||||||
|
FloatingContainerHasWidgetTitle = 0x40000,
|
||||||
|
FloatingContainerHasWidgetIcon = 0x80000,
|
||||||
|
|
||||||
|
|
||||||
DefaultDockAreaButtons = DockAreaHasCloseButton
|
DefaultDockAreaButtons = DockAreaHasCloseButton
|
||||||
@@ -170,7 +167,8 @@ public:
|
|||||||
|
|
||||||
DefaultBaseConfig = DefaultDockAreaButtons
|
DefaultBaseConfig = DefaultDockAreaButtons
|
||||||
| ActiveTabHasCloseButton
|
| ActiveTabHasCloseButton
|
||||||
| XmlCompressionEnabled,///< default base configuration settings
|
| XmlCompressionEnabled
|
||||||
|
| FloatingContainerHasWidgetTitle,///< default base configuration settings
|
||||||
|
|
||||||
DefaultOpaqueConfig = DefaultBaseConfig
|
DefaultOpaqueConfig = DefaultBaseConfig
|
||||||
| OpaqueSplitterResize
|
| OpaqueSplitterResize
|
||||||
@@ -191,12 +189,12 @@ public:
|
|||||||
* Before you create any dock widgets, you should properly setup the
|
* Before you create any dock widgets, you should properly setup the
|
||||||
* configuration flags via setConfigFlags().
|
* configuration flags via setConfigFlags().
|
||||||
*/
|
*/
|
||||||
CDockManager(QWidget* parent = 0);
|
CDockManager(QWidget* parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual Destructor
|
* Virtual Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CDockManager();
|
virtual ~CDockManager() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the global configuration flags
|
* This function returns the global configuration flags
|
||||||
@@ -205,12 +203,14 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the global configuration flags for the whole docking system.
|
* Sets the global configuration flags for the whole docking system.
|
||||||
* Call this function before you create your first dock widget.
|
* Call this function before you create the dock manager and before
|
||||||
|
* your create the first dock widget.
|
||||||
*/
|
*/
|
||||||
static void setConfigFlags(const ConfigFlags Flags);
|
static void setConfigFlags(const ConfigFlags Flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a certain config flag
|
* Set a certain config flag.
|
||||||
|
* \see setConfigFlags()
|
||||||
*/
|
*/
|
||||||
static void setConfigFlag(eConfigFlag Flag, bool On = true);
|
static void setConfigFlag(eConfigFlag Flag, bool On = true);
|
||||||
|
|
||||||
@@ -446,10 +446,17 @@ signals:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This signal is emitted if the dock manager finished opening a
|
* This signal is emitted if the dock manager finished opening a
|
||||||
* perspective
|
* perspective.
|
||||||
*/
|
*/
|
||||||
void perspectiveOpened(const QString& PerspectiveName);
|
void perspectiveOpened(const QString& PerspectiveName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted, if a new floating widget has been created.
|
||||||
|
* An application can use this signal to e.g. subscribe to events of
|
||||||
|
* the newly created window.
|
||||||
|
*/
|
||||||
|
void floatingWidgetCreated(CFloatingDockContainer* FloatingWidget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This signal is emitted, if a new DockArea has been created.
|
* This signal is emitted, if a new DockArea has been created.
|
||||||
* An application can use this signal to set custom icons or custom
|
* An application can use this signal to set custom icons or custom
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDockAreaWidget* DockArea = dynamic_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||||
if (!DockArea)
|
if (!DockArea)
|
||||||
{
|
{
|
||||||
return Result;
|
return Result;
|
||||||
@@ -396,6 +396,20 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
|
||||||
|
{
|
||||||
|
if (isHidden() || !d->DropPreviewEnabled)
|
||||||
|
{
|
||||||
|
return InvalidDockWidgetArea;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return dropAreaUnderCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
||||||
{
|
{
|
||||||
@@ -632,7 +646,7 @@ void CDockOverlayCross::updateOverlayIcons()
|
|||||||
{
|
{
|
||||||
d->updateDropIndicatorIcon(Widget);
|
d->updateDropIndicatorIcon(Widget);
|
||||||
}
|
}
|
||||||
#if QT_VESION >= 0x050600
|
#if QT_VERSION >= 0x050600
|
||||||
d->LastDevicePixelRatio = devicePixelRatioF();
|
d->LastDevicePixelRatio = devicePixelRatioF();
|
||||||
#else
|
#else
|
||||||
d->LastDevicePixelRatio = devicePixelRatio();
|
d->LastDevicePixelRatio = devicePixelRatio();
|
||||||
|
|||||||
@@ -81,6 +81,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
DockWidgetArea dropAreaUnderCursor() const;
|
DockWidgetArea dropAreaUnderCursor() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the same like dropAreaUnderCursor() if this
|
||||||
|
* overlay is not hidden and if drop preview is enabled and returns
|
||||||
|
* InvalidDockWidgetArea if it is hidden or drop preview is disabled.
|
||||||
|
*/
|
||||||
|
DockWidgetArea visibleDropAreaUnderCursor() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the drop overly for the given target widget
|
* Show the drop overly for the given target widget
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -88,6 +88,20 @@ bool CDockSplitter::hasVisibleContent() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
QWidget* CDockSplitter::firstWidget() const
|
||||||
|
{
|
||||||
|
return (count() > 0) ? widget(0) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
QWidget* CDockSplitter::lastWidget() const
|
||||||
|
{
|
||||||
|
return (count() > 0) ? widget(count() - 1) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -61,6 +61,16 @@ public:
|
|||||||
* Returns true, if any of the internal widgets is visible
|
* Returns true, if any of the internal widgets is visible
|
||||||
*/
|
*/
|
||||||
bool hasVisibleContent() const;
|
bool hasVisibleContent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns first widget or nullptr if splitter is empty
|
||||||
|
*/
|
||||||
|
QWidget* firstWidget() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last widget of nullptr is splitter is empty
|
||||||
|
*/
|
||||||
|
QWidget* lastWidget() const;
|
||||||
}; // class CDockSplitter
|
}; // class CDockSplitter
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include "DockManager.h"
|
#include "DockManager.h"
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
#include "DockSplitter.h"
|
#include "DockSplitter.h"
|
||||||
|
#include "DockComponentsFactory.h"
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ struct DockWidgetPrivate
|
|||||||
QSize ToolBarIconSizeFloating = QSize(24, 24);
|
QSize ToolBarIconSizeFloating = QSize(24, 24);
|
||||||
bool IsFloatingTopLevel = false;
|
bool IsFloatingTopLevel = false;
|
||||||
QList<QAction*> TitleBarActions;
|
QList<QAction*> TitleBarActions;
|
||||||
|
CDockWidget::eMinimumSizeHintMode MinimumSizeHintMode = CDockWidget::MinimumSizeHintFromDockWidget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@@ -172,6 +174,12 @@ void DockWidgetPrivate::updateParentDockArea()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we don't need to change the current tab if the
|
||||||
|
// current dock widget is not the one being closed
|
||||||
|
if (DockArea->currentDockWidget() != _this){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto NextDockWidget = DockArea->nextOpenDockWidget(_this);
|
auto NextDockWidget = DockArea->nextOpenDockWidget(_this);
|
||||||
if (NextDockWidget)
|
if (NextDockWidget)
|
||||||
{
|
{
|
||||||
@@ -220,7 +228,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
|||||||
setWindowTitle(title);
|
setWindowTitle(title);
|
||||||
setObjectName(title);
|
setObjectName(title);
|
||||||
|
|
||||||
d->TabWidget = new CDockWidgetTab(this);
|
d->TabWidget = componentsFactory()->createDockWidgetTab(this);
|
||||||
d->ToggleViewAction = new QAction(title, this);
|
d->ToggleViewAction = new QAction(title, this);
|
||||||
d->ToggleViewAction->setCheckable(true);
|
d->ToggleViewAction->setCheckable(true);
|
||||||
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
||||||
@@ -417,6 +425,13 @@ void CDockWidget::setToggleViewActionMode(eToggleViewActionMode Mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CDockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode Mode)
|
||||||
|
{
|
||||||
|
d->MinimumSizeHintMode = Mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CDockWidget::toggleView(bool Open)
|
void CDockWidget::toggleView(bool Open)
|
||||||
{
|
{
|
||||||
@@ -746,7 +761,14 @@ void CDockWidget::setClosedState(bool Closed)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
QSize CDockWidget::minimumSizeHint() const
|
QSize CDockWidget::minimumSizeHint() const
|
||||||
{
|
{
|
||||||
return QSize(60, 40);
|
if (d->MinimumSizeHintMode == CDockWidget::MinimumSizeHintFromDockWidget || !d->Widget)
|
||||||
|
{
|
||||||
|
return QSize(60, 40);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return d->Widget->minimumSizeHint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -808,6 +830,7 @@ bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleteDockWidget();
|
deleteDockWidget();
|
||||||
|
emit closed();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -189,6 +189,23 @@ public:
|
|||||||
ForceNoScrollArea
|
ForceNoScrollArea
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mode of the minimumSizeHint() that is returned by the DockWidget
|
||||||
|
* minimumSizeHint() function.
|
||||||
|
* To ensure, that a dock widget does not block resizing, the dock widget
|
||||||
|
* reimplements minimumSizeHint() function to return a very small minimum
|
||||||
|
* size hint. If you would like to adhere the minimumSizeHint() from the
|
||||||
|
* content widget, the set the minimumSizeHintMode() to
|
||||||
|
* MinimumSizeHintFromContent.
|
||||||
|
*/
|
||||||
|
enum eMinimumSizeHintMode
|
||||||
|
{
|
||||||
|
MinimumSizeHintFromDockWidget,
|
||||||
|
MinimumSizeHintFromContent
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This mode configures the behavior of the toggle view action.
|
* This mode configures the behavior of the toggle view action.
|
||||||
* If the mode if ActionModeToggle, then the toggle view action is
|
* If the mode if ActionModeToggle, then the toggle view action is
|
||||||
@@ -225,7 +242,8 @@ public:
|
|||||||
virtual ~CDockWidget();
|
virtual ~CDockWidget();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We return a fixed minimum size hint for all dock widgets
|
* We return a fixed minimum size hint or the size hint of the content
|
||||||
|
* widget if minimum size hint mode is MinimumSizeHintFromContent
|
||||||
*/
|
*/
|
||||||
virtual QSize minimumSizeHint() const override;
|
virtual QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
@@ -334,6 +352,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setToggleViewActionMode(eToggleViewActionMode Mode);
|
void setToggleViewActionMode(eToggleViewActionMode Mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the minimum size hint that is returned by the
|
||||||
|
* minimumSizeHint() function.
|
||||||
|
* \see eMinimumSizeHintMode for a detailed description
|
||||||
|
*/
|
||||||
|
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the dock widget icon that is shown in tabs and in toggle view
|
* Sets the dock widget icon that is shown in tabs and in toggle view
|
||||||
* actions
|
* actions
|
||||||
@@ -346,13 +371,10 @@ public:
|
|||||||
QIcon icon() const;
|
QIcon icon() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the WithToolBar layout flag is enabled, then this function returns
|
|
||||||
* the dock widget toolbar. If the flag is disabled, the function returns
|
|
||||||
* a nullptr.
|
|
||||||
* This function returns the dock widget top tool bar.
|
* This function returns the dock widget top tool bar.
|
||||||
* If no toolbar is assigned, this function returns nullptr. To get a vaild
|
* If no toolbar is assigned, this function returns nullptr. To get a vaild
|
||||||
* toolbar you either need to create a default empty toolbar via
|
* toolbar you either need to create a default empty toolbar via
|
||||||
* createDefaultToolBar() function or you need to assign you custom
|
* createDefaultToolBar() function or you need to assign your custom
|
||||||
* toolbar via setToolBar().
|
* toolbar via setToolBar().
|
||||||
*/
|
*/
|
||||||
QToolBar* toolBar() const;
|
QToolBar* toolBar() const;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ struct DockWidgetTabPrivate
|
|||||||
QLabel* IconLabel = nullptr;
|
QLabel* IconLabel = nullptr;
|
||||||
tTabLabel* TitleLabel;
|
tTabLabel* TitleLabel;
|
||||||
QPoint GlobalDragStartMousePosition;
|
QPoint GlobalDragStartMousePosition;
|
||||||
|
QPoint DragStartMousePosition;
|
||||||
bool IsActiveTab = false;
|
bool IsActiveTab = false;
|
||||||
CDockAreaWidget* DockArea = nullptr;
|
CDockAreaWidget* DockArea = nullptr;
|
||||||
eDragState DragState = DraggingInactive;
|
eDragState DragState = DraggingInactive;
|
||||||
@@ -150,6 +151,15 @@ struct DockWidgetTabPrivate
|
|||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the drag start position in global and local coordinates
|
||||||
|
*/
|
||||||
|
void saveDragStartMousePosition(const QPoint& GlobalPos)
|
||||||
|
{
|
||||||
|
GlobalDragStartMousePosition = GlobalPos;
|
||||||
|
DragStartMousePosition = _this->mapFromGlobal(GlobalPos);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// struct DockWidgetTabPrivate
|
// struct DockWidgetTabPrivate
|
||||||
|
|
||||||
@@ -205,6 +215,8 @@ void DockWidgetTabPrivate::moveTab(QMouseEvent* ev)
|
|||||||
QPoint Distance = ev->globalPos() - GlobalDragStartMousePosition;
|
QPoint Distance = ev->globalPos() - GlobalDragStartMousePosition;
|
||||||
Distance.setY(0);
|
Distance.setY(0);
|
||||||
auto TargetPos = Distance + TabDragStartPosition;
|
auto TargetPos = Distance + TabDragStartPosition;
|
||||||
|
TargetPos.rx() = qMax(TargetPos.x(), 0);
|
||||||
|
TargetPos.rx() = qMin(_this->parentWidget()->rect().right() - _this->width() + 1, TargetPos.rx());
|
||||||
_this->move(TargetPos);
|
_this->move(TargetPos);
|
||||||
_this->raise();
|
_this->raise();
|
||||||
}
|
}
|
||||||
@@ -229,7 +241,6 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
|||||||
|
|
||||||
ADS_PRINT("startFloating");
|
ADS_PRINT("startFloating");
|
||||||
DragState = DraggingState;
|
DragState = DraggingState;
|
||||||
auto DragStartMousePosition = _this->mapFromGlobal(GlobalDragStartMousePosition);
|
|
||||||
QSize Size = DockArea->size();
|
QSize Size = DockArea->size();
|
||||||
IFloatingWidget* FloatingWidget = nullptr;
|
IFloatingWidget* FloatingWidget = nullptr;
|
||||||
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
|
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
|
||||||
@@ -287,7 +298,7 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
|
|||||||
if (ev->button() == Qt::LeftButton)
|
if (ev->button() == Qt::LeftButton)
|
||||||
{
|
{
|
||||||
ev->accept();
|
ev->accept();
|
||||||
d->GlobalDragStartMousePosition = ev->globalPos();
|
d->saveDragStartMousePosition(ev->globalPos());
|
||||||
d->DragState = DraggingMousePressed;
|
d->DragState = DraggingMousePressed;
|
||||||
emit clicked();
|
emit clicked();
|
||||||
return;
|
return;
|
||||||
@@ -304,6 +315,7 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
|
|||||||
{
|
{
|
||||||
auto CurrentDragState = d->DragState;
|
auto CurrentDragState = d->DragState;
|
||||||
d->GlobalDragStartMousePosition = QPoint();
|
d->GlobalDragStartMousePosition = QPoint();
|
||||||
|
d->DragStartMousePosition = QPoint();
|
||||||
d->DragState = DraggingInactive;
|
d->DragState = DraggingInactive;
|
||||||
|
|
||||||
switch (CurrentDragState)
|
switch (CurrentDragState)
|
||||||
@@ -354,9 +366,11 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
|||||||
d->moveTab(ev);
|
d->moveTab(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto MappedPos = mapToParent(ev->pos());
|
||||||
|
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
|
||||||
// Maybe a fixed drag distance is better here ?
|
// Maybe a fixed drag distance is better here ?
|
||||||
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - ev->globalPos().y());
|
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - ev->globalPos().y());
|
||||||
if (DragDistanceY >= CDockManager::startDragDistance())
|
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
|
||||||
{
|
{
|
||||||
// If this is the last dock area in a dock container with only
|
// If this is the last dock area in a dock container with only
|
||||||
// one single dock widget it does not make sense to move it to a new
|
// one single dock widget it does not make sense to move it to a new
|
||||||
@@ -368,14 +382,19 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floating is only allowed for widgets that are movable
|
|
||||||
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
// Floating is only allowed for widgets that are floatable
|
||||||
|
// If we do non opaque undocking, then can create the drag preview
|
||||||
|
// if the widget is movable.
|
||||||
|
auto Features = d->DockWidget->features();
|
||||||
|
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|
||||||
|
|| (Features.testFlag(CDockWidget::DockWidgetMovable) && !CDockManager::testConfigFlag(CDockManager::OpaqueUndocking)))
|
||||||
{
|
{
|
||||||
// If we undock, we need to restore the initial position of this
|
// If we undock, we need to restore the initial position of this
|
||||||
// tab because it looks strange if it remains on its dragged position
|
// tab because it looks strange if it remains on its dragged position
|
||||||
if (d->isDraggingState(DraggingTab) && !CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking))
|
if (d->isDraggingState(DraggingTab) && !CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking))
|
||||||
{
|
{
|
||||||
this->move(d->TabDragStartPosition);
|
parentWidget()->layout()->update();
|
||||||
}
|
}
|
||||||
d->startFloating();
|
d->startFloating();
|
||||||
}
|
}
|
||||||
@@ -407,7 +426,7 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->GlobalDragStartMousePosition = ev->globalPos();
|
d->saveDragStartMousePosition(ev->globalPos());
|
||||||
QMenu Menu(this);
|
QMenu Menu(this);
|
||||||
|
|
||||||
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
||||||
@@ -537,7 +556,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
||||||
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||||
{
|
{
|
||||||
d->GlobalDragStartMousePosition = event->globalPos();
|
d->saveDragStartMousePosition(event->globalPos());
|
||||||
d->startFloating(DraggingInactive);
|
d->startFloating(DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +599,8 @@ void CDockWidgetTab::detachDockWidget()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d->GlobalDragStartMousePosition = QCursor::pos();
|
|
||||||
|
d->saveDragStartMousePosition(QCursor::pos());
|
||||||
d->startFloating(DraggingInactive);
|
d->startFloating(DraggingInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,11 +94,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setActiveTab(bool active);
|
void setActiveTab(bool active);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the dock widget this title widget belongs to
|
|
||||||
*/
|
|
||||||
CDockWidget* dockWidget() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the dock area widget the dockWidget returned by dockWidget()
|
* Sets the dock area widget the dockWidget returned by dockWidget()
|
||||||
* function belongs to.
|
* function belongs to.
|
||||||
@@ -112,6 +107,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
CDockAreaWidget* dockAreaWidget() const;
|
CDockAreaWidget* dockAreaWidget() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dock widget this title widget belongs to
|
||||||
|
*/
|
||||||
|
CDockWidget* dockWidget() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the icon to show in title bar
|
* Sets the icon to show in title bar
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
#include "DockContainerWidget.h"
|
#include "DockContainerWidget.h"
|
||||||
#include "DockAreaWidget.h"
|
#include "DockAreaWidget.h"
|
||||||
@@ -66,6 +67,7 @@ struct FloatingDockContainerPrivate
|
|||||||
QPoint DragStartMousePosition;
|
QPoint DragStartMousePosition;
|
||||||
CDockContainerWidget *DropContainer = nullptr;
|
CDockContainerWidget *DropContainer = nullptr;
|
||||||
CDockAreaWidget *SingleDockArea = nullptr;
|
CDockAreaWidget *SingleDockArea = nullptr;
|
||||||
|
QPoint DragStartPos;
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
QWidget* MouseEventHandler = nullptr;
|
QWidget* MouseEventHandler = nullptr;
|
||||||
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
||||||
@@ -79,6 +81,14 @@ struct FloatingDockContainerPrivate
|
|||||||
void titleMouseReleaseEvent();
|
void titleMouseReleaseEvent();
|
||||||
void updateDropOverlays(const QPoint &GlobalPos);
|
void updateDropOverlays(const QPoint &GlobalPos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given config flag is set
|
||||||
|
*/
|
||||||
|
static bool testConfigFlag(CDockManager::eConfigFlag Flag)
|
||||||
|
{
|
||||||
|
return CDockManager::configFlags().testFlag(Flag);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests is a certain state is active
|
* Tests is a certain state is active
|
||||||
*/
|
*/
|
||||||
@@ -100,6 +110,40 @@ struct FloatingDockContainerPrivate
|
|||||||
_this->setWindowTitle(Text);
|
_this->setWindowTitle(Text);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reflect the current dock widget title in the floating widget windowTitle()
|
||||||
|
* depending on the CDockManager::FloatingContainerHasWidgetTitle flag
|
||||||
|
*/
|
||||||
|
void reflectCurrentWidget(CDockWidget* CurrentWidget)
|
||||||
|
{
|
||||||
|
// reflect CurrentWidget's title if configured to do so, otherwise display application name as window title
|
||||||
|
if (testConfigFlag(CDockManager::FloatingContainerHasWidgetTitle))
|
||||||
|
{
|
||||||
|
setWindowTitle(CurrentWidget->windowTitle());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setWindowTitle(qApp->applicationDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// reflect CurrentWidget's icon if configured to do so, otherwise display application icon as window icon
|
||||||
|
QIcon CurrentWidgetIcon = CurrentWidget->icon();
|
||||||
|
if (testConfigFlag(CDockManager::FloatingContainerHasWidgetIcon)
|
||||||
|
&& !CurrentWidgetIcon.isNull())
|
||||||
|
{
|
||||||
|
_this->setWindowIcon(CurrentWidget->icon());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_this->setWindowIcon(QApplication::windowIcon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles escape key press when dragging around the floating widget
|
||||||
|
*/
|
||||||
|
void handleEscapeKey();
|
||||||
};
|
};
|
||||||
// struct FloatingDockContainerPrivate
|
// struct FloatingDockContainerPrivate
|
||||||
|
|
||||||
@@ -231,6 +275,17 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void FloatingDockContainerPrivate::handleEscapeKey()
|
||||||
|
{
|
||||||
|
ADS_PRINT("FloatingDockContainerPrivate::handleEscapeKey()");
|
||||||
|
setState(DraggingInactive);
|
||||||
|
DockManager->containerOverlay()->hideOverlay();
|
||||||
|
DockManager->dockAreaOverlay()->hideOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
||||||
tFloatingWidgetBase(DockManager),
|
tFloatingWidgetBase(DockManager),
|
||||||
@@ -330,6 +385,9 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
switch (d->DraggingState)
|
switch (d->DraggingState)
|
||||||
{
|
{
|
||||||
case DraggingMousePressed:
|
case DraggingMousePressed:
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
qApp->installEventFilter(this);
|
||||||
|
#endif
|
||||||
d->setState(DraggingFloatingWidget);
|
d->setState(DraggingFloatingWidget);
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
break;
|
break;
|
||||||
@@ -347,6 +405,8 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@@ -410,6 +470,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
|
|||||||
Super::showEvent(event);
|
Super::showEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
bool CFloatingDockContainer::event(QEvent *e)
|
bool CFloatingDockContainer::event(QEvent *e)
|
||||||
{
|
{
|
||||||
@@ -425,21 +486,17 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
// It is really great to work around the whole NonClientMouseArea
|
// It is really great to work around the whole NonClientMouseArea
|
||||||
// bugs
|
// bugs
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
||||||
if (e->type()
|
if (e->type() == QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
||||||
== QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
|
||||||
{
|
|
||||||
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
|
||||||
d->setState(DraggingMousePressed);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
||||||
|
d->DragStartPos = pos();
|
||||||
d->setState(DraggingMousePressed);
|
d->setState(DraggingMousePressed);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DraggingMousePressed:
|
case DraggingMousePressed:
|
||||||
switch (e->type())
|
switch (e->type())
|
||||||
@@ -482,12 +539,49 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if (ADS_DEBUG_LEVEL > 0)
|
#if (ADS_DEBUG_LEVEL > 0)
|
||||||
qDebug() << "CFloatingDockContainer::event " << e->type();
|
qDebug() << QTime::currentTime() << "CFloatingDockContainer::event " << e->type();
|
||||||
#endif
|
#endif
|
||||||
return QWidget::event(e);
|
return QWidget::event(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(watched);
|
||||||
|
// I have not found a way to detect non client area key press events to
|
||||||
|
// handle escape key presses. On Windows, if the escape key is pressed while
|
||||||
|
// dragging around a widget, the widget position is reset to its start position
|
||||||
|
// which in turn generates a QEvent::NonClientAreaMouseButtonRelease event
|
||||||
|
// if the mouse is outside of the widget after the move to its initial position
|
||||||
|
// or a QEvent::MouseButtonRelease event, if the mouse is inside of teh widget
|
||||||
|
// after the position has been reset.
|
||||||
|
// So we can install an event filter on the application to get these events
|
||||||
|
// here to properly cancel dragging and hide the overlays.
|
||||||
|
// If we are in DraggingFloatingWidget state, it means the widget
|
||||||
|
// has been dragged already but if the position is the same like
|
||||||
|
// the start position, then this is an indication that the escape
|
||||||
|
// key has been pressed.
|
||||||
|
if (e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||||
|
{
|
||||||
|
ADS_PRINT("CFloatingDockContainer::eventFilter QEvent::MouseButtonRelease or"
|
||||||
|
"QEvent::NonClientAreaMouseButtonRelease" << "d->DragggingState " << d->DraggingState);
|
||||||
|
qApp->removeEventFilter(this);
|
||||||
|
if (d->DragStartPos == pos())
|
||||||
|
{
|
||||||
|
d->handleEscapeKey();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (ADS_DEBUG_LEVEL > 0)
|
||||||
|
qDebug() << QTime::currentTime() << "CFloatingDockContainer::eventFilter " << e->type();
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
||||||
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
||||||
@@ -537,8 +631,8 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
|
|||||||
if (TopLevelDockArea)
|
if (TopLevelDockArea)
|
||||||
{
|
{
|
||||||
d->SingleDockArea = TopLevelDockArea;
|
d->SingleDockArea = TopLevelDockArea;
|
||||||
d->setWindowTitle(
|
CDockWidget* CurrentWidget = d->SingleDockArea->currentDockWidget();
|
||||||
d->SingleDockArea->currentDockWidget()->windowTitle());
|
d->reflectCurrentWidget(CurrentWidget);
|
||||||
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
|
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
|
||||||
SLOT(onDockAreaCurrentChanged(int)));
|
SLOT(onDockAreaCurrentChanged(int)));
|
||||||
}
|
}
|
||||||
@@ -551,6 +645,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
|
|||||||
d->SingleDockArea = nullptr;
|
d->SingleDockArea = nullptr;
|
||||||
}
|
}
|
||||||
d->setWindowTitle(qApp->applicationDisplayName());
|
d->setWindowTitle(qApp->applicationDisplayName());
|
||||||
|
setWindowIcon(QApplication::windowIcon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,11 +655,13 @@ void CFloatingDockContainer::updateWindowTitle()
|
|||||||
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
|
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
|
||||||
if (TopLevelDockArea)
|
if (TopLevelDockArea)
|
||||||
{
|
{
|
||||||
d->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
|
CDockWidget* CurrentWidget = TopLevelDockArea->currentDockWidget();
|
||||||
|
d->reflectCurrentWidget(CurrentWidget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d->setWindowTitle(qApp->applicationDisplayName());
|
d->setWindowTitle(qApp->applicationDisplayName());
|
||||||
|
setWindowIcon(QApplication::windowIcon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +669,8 @@ void CFloatingDockContainer::updateWindowTitle()
|
|||||||
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
|
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
|
||||||
{
|
{
|
||||||
Q_UNUSED(Index);
|
Q_UNUSED(Index);
|
||||||
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
|
CDockWidget* CurrentWidget = d->SingleDockArea->currentDockWidget();
|
||||||
|
d->reflectCurrentWidget(CurrentWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ protected: // reimplements QWidget
|
|||||||
virtual void closeEvent(QCloseEvent *event) override;
|
virtual void closeEvent(QCloseEvent *event) override;
|
||||||
virtual void hideEvent(QHideEvent *event) override;
|
virtual void hideEvent(QHideEvent *event) override;
|
||||||
virtual void showEvent(QShowEvent *event) override;
|
virtual void showEvent(QShowEvent *event) override;
|
||||||
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Super = QWidget;
|
using Super = QWidget;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct FloatingDragPreviewPrivate
|
|||||||
qreal WindowOpacity;
|
qreal WindowOpacity;
|
||||||
bool Hidden = false;
|
bool Hidden = false;
|
||||||
QPixmap ContentPreviewPixmap;
|
QPixmap ContentPreviewPixmap;
|
||||||
|
bool Canceled = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,6 +60,7 @@ struct FloatingDragPreviewPrivate
|
|||||||
*/
|
*/
|
||||||
void cancelDragging()
|
void cancelDragging()
|
||||||
{
|
{
|
||||||
|
Canceled = true;
|
||||||
emit _this->draggingCanceled();
|
emit _this->draggingCanceled();
|
||||||
DockManager->containerOverlay()->hideOverlay();
|
DockManager->containerOverlay()->hideOverlay();
|
||||||
DockManager->dockAreaOverlay()->hideOverlay();
|
DockManager->dockAreaOverlay()->hideOverlay();
|
||||||
@@ -85,11 +87,6 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (DockContainer == ContainerWidget)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
||||||
if (ContainerWidget->rect().contains(MappedPos))
|
if (ContainerWidget->rect().contains(MappedPos))
|
||||||
{
|
{
|
||||||
@@ -148,6 +145,14 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DockAreaOverlay->hideOverlay();
|
DockAreaOverlay->hideOverlay();
|
||||||
|
// If there is only one single visible dock area in a container, then
|
||||||
|
// it does not make sense to show a dock overlay because the dock area
|
||||||
|
// would be removed and inserted at the same position
|
||||||
|
if (VisibleDockAreas <= 1)
|
||||||
|
{
|
||||||
|
ContainerOverlay->hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
|
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
|
||||||
{
|
{
|
||||||
DropContainer = nullptr;
|
DropContainer = nullptr;
|
||||||
@@ -207,9 +212,9 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
|||||||
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
|
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
|
||||||
SLOT(onApplicationStateChanged(Qt::ApplicationState)));
|
SLOT(onApplicationStateChanged(Qt::ApplicationState)));
|
||||||
|
|
||||||
// We need to install an event filter for the given Content
|
// The only safe way to receive escape key presses is to install an event
|
||||||
// widget to receive the escape key press
|
// filter for the application object
|
||||||
Content->installEventFilter(this);
|
qApp->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -281,35 +286,46 @@ void CFloatingDragPreview::moveEvent(QMoveEvent *event)
|
|||||||
void CFloatingDragPreview::finishDragging()
|
void CFloatingDragPreview::finishDragging()
|
||||||
{
|
{
|
||||||
ADS_PRINT("CFloatingDragPreview::finishDragging");
|
ADS_PRINT("CFloatingDragPreview::finishDragging");
|
||||||
auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor();
|
auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
|
||||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
|
||||||
bool DropPossible = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea);
|
if (d->DropContainer && (DockDropArea != InvalidDockWidgetArea))
|
||||||
if (d->DropContainer && DropPossible)
|
|
||||||
{
|
{
|
||||||
d->DropContainer->dropWidget(d->Content, QCursor::pos());
|
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||||
|
}
|
||||||
|
else if (d->DropContainer && (ContainerDropArea != InvalidDockWidgetArea))
|
||||||
|
{
|
||||||
|
d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content);
|
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(d->Content);
|
||||||
CFloatingDockContainer* FloatingWidget;
|
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||||
if (DockWidget)
|
|
||||||
|
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||||
{
|
{
|
||||||
FloatingWidget = new CFloatingDockContainer(DockWidget);
|
FloatingWidget = new CFloatingDockContainer(DockWidget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
|
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
|
||||||
FloatingWidget = new CFloatingDockContainer(DockArea);
|
if (DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||||
|
{
|
||||||
|
FloatingWidget = new CFloatingDockContainer(DockArea);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FloatingWidget->setGeometry(this->geometry());
|
|
||||||
FloatingWidget->show();
|
if (FloatingWidget)
|
||||||
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
|
||||||
{
|
{
|
||||||
QApplication::processEvents();
|
FloatingWidget->setGeometry(this->geometry());
|
||||||
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
|
FloatingWidget->show();
|
||||||
QRect FixedGeometry = this->geometry();
|
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||||
FixedGeometry.adjust(0, FrameHeight, 0, 0);
|
{
|
||||||
FloatingWidget->setGeometry(FixedGeometry);
|
QApplication::processEvents();
|
||||||
|
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
|
||||||
|
QRect FixedGeometry = this->geometry();
|
||||||
|
FixedGeometry.adjust(0, FrameHeight, 0, 0);
|
||||||
|
FloatingWidget->setGeometry(FixedGeometry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,12 +384,12 @@ void CFloatingDragPreview::onApplicationStateChanged(Qt::ApplicationState state)
|
|||||||
bool CFloatingDragPreview::eventFilter(QObject *watched, QEvent *event)
|
bool CFloatingDragPreview::eventFilter(QObject *watched, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(watched);
|
Q_UNUSED(watched);
|
||||||
if (event->type() == QEvent::KeyPress)
|
if (!d->Canceled && event->type() == QEvent::KeyPress)
|
||||||
{
|
{
|
||||||
QKeyEvent* e = static_cast<QKeyEvent*>(event);
|
QKeyEvent* e = static_cast<QKeyEvent*>(event);
|
||||||
if (e->key() == Qt::Key_Escape)
|
if (e->key() == Qt::Key_Escape)
|
||||||
{
|
{
|
||||||
d->Content->removeEventFilter(this);
|
watched->removeEventFilter(this);
|
||||||
d->cancelDragging();
|
d->cancelDragging();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,7 +399,6 @@ bool CFloatingDragPreview::eventFilter(QObject *watched, QEvent *event)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ads
|
} // namespace ads
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ HEADERS += \
|
|||||||
DockSplitter.h \
|
DockSplitter.h \
|
||||||
DockAreaTitleBar.h \
|
DockAreaTitleBar.h \
|
||||||
ElidingLabel.h \
|
ElidingLabel.h \
|
||||||
IconProvider.h
|
IconProvider.h \
|
||||||
|
DockComponentsFactory.h
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -61,7 +62,8 @@ SOURCES += \
|
|||||||
DockSplitter.cpp \
|
DockSplitter.cpp \
|
||||||
DockAreaTitleBar.cpp \
|
DockAreaTitleBar.cpp \
|
||||||
ElidingLabel.cpp \
|
ElidingLabel.cpp \
|
||||||
IconProvider.cpp
|
IconProvider.cpp \
|
||||||
|
DockComponentsFactory.cpp
|
||||||
|
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
|
|||||||
Reference in New Issue
Block a user