Compare commits

...

24 Commits

Author SHA1 Message Date
Uwe Kindler
224676836d Improved CDockAreaTabBar::wheelEvent to use pixelDelta() if available (i.e. on Mac) and fall back to angleDelta() if not 2024-12-05 13:11:48 +01:00
Federico Fuga
f2378636e2 Add ability to customize the DockArea Title Bar and DockWidget Tab context menu 2024-11-20 15:38:39 +01:00
Federico Fuga
509b2356d1 Fix missing declarations 2024-11-20 15:38:21 +01:00
Uwe Kindler
30b802bd10 Fixed Qt5 build issues 2024-11-20 15:31:31 +01:00
Uwe Kindler
e857421fdf Added all build* subfolders to .gitignore 2024-10-28 15:41:46 +01:00
Uwe Kindler
8dcdc8fad2 Improved autohidedragndrop example to check, if it also works when dragging with multiple auto hide tabs 2024-10-28 15:40:32 +01:00
Uwe Kindler
f964ce2c68 Refactored, fixed and improved drag hover functionality 2024-10-28 15:39:29 +01:00
Uwe Kindler
eb9b439d11 Added support for setting config parameters to CDockManager 2024-10-28 15:30:29 +01:00
TheBoje
a13ed7e4d6 Add AutoHideDragNDrop example 2024-10-22 22:36:53 +02:00
TheBoje
8cfa5c8e0e Fix formatting#2 (#663) 2024-10-04 22:27:15 +02:00
TheBoje
2878559ee6 Fix formatting (#663) 2024-10-04 22:23:40 +02:00
TheBoje
6ff39bccf8 Add open auto-hide dock on hover from drag and drop (#663) 2024-10-04 22:17:42 +02:00
gavininfinity
952131a1e9 Make startDragging public (#658) 2024-08-19 07:37:51 +02:00
Uwe Kindler
5edbcc1970 Fixed issue #654 - Wheel event on DockAreaTabBar 2024-07-25 08:42:30 +02:00
Uwe Kindler
04f6d9168e Fixed #642 - The floating window can not back to normal size after maximizing it 2024-07-08 14:32:33 +02:00
Uwe Kindler
cea1327dac Fixed #653 - DisablingTabTextEliding not letting DockAreaDynamicTabsMenuButtonVisibility to function and program crashes 2024-07-08 12:15:00 +02:00
Uwe Kindler
1c41cbff82 Fixed issue #641 - Unexpected behaviour with tab drag on scrollable tab bar 2024-07-08 10:43:02 +02:00
invisibleGG
06e8451fc0 Update DockAreaTabBar.cpp (#640)
This fix seems to have introduced a regression when _this is deleted before the lambda slot occurred, for example deleting the DockManager (and consequently _this) immediately after the execution of updateTabs function (we encountered this problem in linux)
2024-06-03 08:29:59 +02:00
Uwe Kindler
3ff6918b1f Added configflags example to test use of CDockManager config flags 2024-05-21 08:37:35 +02:00
Uwe Kindler
ac3af4c6cd Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2024-05-08 14:44:44 +02:00
Uwe Kindler
41bb861417 Fixed problem in AutoHideSideBar that prevented the dock container, that contained a vertical sidebar with many tabs, from shrinking vertically 2024-05-08 14:43:53 +02:00
Stefan Gerlach
6e63418798 Fix "extra ;" warning (#624) 2024-04-08 11:40:06 +02:00
Nicolas Elie
65781b7cac Include GNUInstallDirs for CMAKE_INSTALL_* vars to be defined (#621) 2024-04-03 23:49:37 +02:00
Nicolas Elie
d7e6c613c6 Update PyQt bindings to 4.3.0 (#622) 2024-04-03 23:49:08 +02:00
50 changed files with 1091 additions and 139 deletions

2
.gitignore vendored
View File

@@ -9,7 +9,7 @@ ui_*
Makefile Makefile
*.dll *.dll
*.a *.a
build-* build*
# IDEs # IDEs
.idea .idea

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (POLICY CMP0091) if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091) endif (POLICY CMP0091)

View File

@@ -75,18 +75,17 @@
#endif #endif
#endif #endif
#include "DockManager.h"
#include "DockWidget.h"
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h" #include "DockAreaTabBar.h"
#include "FloatingDockContainer.h" #include "DockAreaTitleBar.h"
#include "DockAreaWidget.h"
#include "DockComponentsFactory.h" #include "DockComponentsFactory.h"
#include "StatusDialog.h" #include "DockManager.h"
#include "DockSplitter.h" #include "DockSplitter.h"
#include "DockWidget.h"
#include "FloatingDockContainer.h"
#include "ImageViewer.h" #include "ImageViewer.h"
#include "MyDockAreaTitleBar.h"
#include "StatusDialog.h"
/** /**
* Returns a random number from 0 to highest - 1 * Returns a random number from 0 to highest - 1
@@ -147,7 +146,7 @@ public:
using Super = ads::CDockComponentsFactory; using Super = ads::CDockComponentsFactory;
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
{ {
auto TitleBar = new ads::CDockAreaTitleBar(DockArea); auto TitleBar = new MyDockAreaTitleBar(DockArea);
auto CustomButton = new QToolButton(DockArea); auto CustomButton = new QToolButton(DockArea);
CustomButton->setToolTip(QObject::tr("Help")); CustomButton->setToolTip(QObject::tr("Help"));
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg")); CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));

34
demo/MyDockAreaTitleBar.h Normal file
View File

@@ -0,0 +1,34 @@
//
// Created by fuga on 08 nov 2024.
//
#ifndef QTADS_MYDOCKAREATITLEBAR_H
#define QTADS_MYDOCKAREATITLEBAR_H
#include <DockAreaTitleBar.h>
class MyDockAreaTitleBar : public ads::CDockAreaTitleBar {
public:
explicit MyDockAreaTitleBar(ads::CDockAreaWidget* parent)
: CDockAreaTitleBar(parent)
{}
QMenu* buildContextMenu(QMenu*) override
{
auto menu = ads::CDockAreaTitleBar::buildContextMenu(nullptr);
menu->addSeparator();
auto action = menu->addAction(tr("Format HardDrive"));
connect(action, &QAction::triggered, this, [this](){
QMessageBox msgBox;
msgBox.setText("No, just kidding");
msgBox.setStandardButtons(QMessageBox::Abort);
msgBox.setDefaultButton(QMessageBox::Abort);
msgBox.exec();
});
return menu;
}
};
#endif // QTADS_MYDOCKAREATITLEBAR_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@@ -49,6 +49,7 @@
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock) - [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton) - [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton) - [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
- [DockWidget Feature Flags](#dockwidget-feature-flags) - [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable) - [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable) - [`DockWidgetMovable`](#dockwidgetmovable)
@@ -704,6 +705,15 @@ If this flag is set (disabled by default), then each auto hide widget has a mini
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png) ![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
### `AutoHideOpenOnDragHover`
If this flag is set (disabled by default), then holding a dragging cursor hover an auto-hide collapsed dock's tab will open said dock:
![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif)
Said dock must be set to accept drops to hide when cursor leaves its scope. See `AutoHideDragNDropExample` for more details.
## DockWidget Feature Flags ## DockWidget Feature Flags
### `DockWidgetClosable` ### `DockWidgetClosable`

View File

@@ -6,5 +6,6 @@ add_subdirectory(sidebar)
add_subdirectory(deleteonclose) add_subdirectory(deleteonclose)
add_subdirectory(centralwidget) add_subdirectory(centralwidget)
add_subdirectory(autohide) add_subdirectory(autohide)
add_subdirectory(autohidedragndrop)
add_subdirectory(emptydockarea) add_subdirectory(emptydockarea)
add_subdirectory(dockindock) add_subdirectory(dockindock)

View File

@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_autohide_dragndrop VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(AutoHideDragNDropExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
droppableitem.cpp
)
target_include_directories(AutoHideDragNDropExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(AutoHideDragNDropExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(AutoHideDragNDropExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(AutoHideDragNDropExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Auto Hide With Drag N Drop Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,36 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = AutoHideDragNDropExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp \
droppableitem.cpp
HEADERS += \
mainwindow.h \
droppableitem.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,38 @@
#include "droppableitem.h"
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <qsizepolicy.h>
DroppableItem::DroppableItem(const QString& text, QWidget* parent)
: QPushButton(text, parent)
{
setAcceptDrops(true);
setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
}
void DroppableItem::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasText())
{
event->acceptProposedAction();
setCursor(Qt::DragMoveCursor);
}
}
void DroppableItem::dragLeaveEvent(QDragLeaveEvent* event)
{
Q_UNUSED(event);
unsetCursor();
}
void DroppableItem::dropEvent(QDropEvent* event)
{
if (event->mimeData()->hasText())
{
event->acceptProposedAction();
setText(event->mimeData()->text());
}
}

View File

@@ -0,0 +1,19 @@
#include <QObject>
#include <QPushButton>
class QDragEnterEvent;
class QDragLeaveEvent;
class QDropEvent;
class DroppableItem : public QPushButton
{
Q_OBJECT;
public:
DroppableItem(const QString& text = QString(), QWidget* parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent* event) override;
void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override;
};

View File

@@ -0,0 +1,10 @@
#include <mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,84 @@
import os
import sys
from PyQt5 import uic
from PyQt5.QtCore import Qt, QTimer, QDir, QSignalBlocker
from PyQt5.QtGui import QCloseEvent, QIcon
from PyQt5.QtWidgets import (QApplication, QLabel, QCalendarWidget, QFrame, QTreeView,
QTableWidget, QFileSystemModel, QPlainTextEdit, QToolBar,
QWidgetAction, QComboBox, QAction, QSizePolicy, QInputDialog)
import PyQtAds as 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)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.OpaqueSplitterResize, True)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.XmlCompressionEnabled, False)
QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FocusHighlighting, True)
QtAds.CDockManager.setAutoHideConfigFlag(QtAds.CDockManager.AutoHideOpenOnDragHover, True);
self.dock_manager = QtAds.CDockManager(self)
# Set central widget
text_edit = QPlainTextEdit()
text_edit.setPlaceholderText("This is the central editor. Enter your text here.")
central_dock_widget = QtAds.CDockWidget("CentralWidget")
central_dock_widget.setWidget(text_edit)
central_dock_area = self.dock_manager.setCentralWidget(central_dock_widget)
central_dock_area.setAllowedAreas(QtAds.DockWidgetArea.OuterDockAreas)
droppable_item = DroppableItem("Drop text here.")
drop_dock_widget = QtAds.CDockWidget("Tab")
drop_dock_widget.setWidget(droppable_item)
drop_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
drop_dock_widget.setMinimumSize(200, 150)
drop_dock_widget.setAcceptDrops(True)
drop_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.LeftDockWidgetArea, drop_dock_widget)
drop_area.setAcceptDrops(True)
self.menuView.addAction(drop_dock_widget.toggleViewAction())
self.create_perspective_ui()
def create_perspective_ui(self):
save_perspective_action = QAction("Create Perspective", self)
save_perspective_action.triggered.connect(self.save_perspective)
perspective_list_action = QWidgetAction(self)
self.perspective_combobox = QComboBox(self)
self.perspective_combobox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
self.perspective_combobox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.perspective_combobox.activated[str].connect(self.dock_manager.openPerspective)
perspective_list_action.setDefaultWidget(self.perspective_combobox)
self.toolBar.addSeparator()
self.toolBar.addAction(perspective_list_action)
self.toolBar.addAction(save_perspective_action)
def save_perspective(self):
perspective_name, ok = QInputDialog.getText(self, "Save Perspective", "Enter Unique name:")
if not ok or not perspective_name:
return
self.dock_manager.addPerspective(perspective_name)
blocker = QSignalBlocker(self.perspective_combobox)
self.perspective_combobox.clear()
self.perspective_combobox.addItems(self.dock_manager.perspectiveNames())
self.perspective_combobox.setCurrentText(perspective_name)
def closeEvent(self, event: QCloseEvent):
self.dock_manager.deleteLater()
super().closeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()

View File

@@ -0,0 +1,131 @@
#include "mainwindow.h"
#include "droppableitem.h"
#include "ui_mainwindow.h"
#include <QWidgetAction>
#include <QFileSystemModel>
#include <QTableWidget>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QFileDialog>
#include <QSettings>
#include <QPlainTextEdit>
#include <QToolBar>
#include "AutoHideDockContainer.h"
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
using namespace ads;
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
CDockManager::setAutoHideConfigFlags(CDockManager::DefaultAutoHideConfig);
CDockManager::setAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover, true);
CDockManager::setConfigParam(CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500);
DockManager = new CDockManager(this);
// Set central widget
QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here.");
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(w);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
{
DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 1");
dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150);
dropDockWidget->setAcceptDrops(true);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::SideBarLeft, dropDockWidget);
autoHideContainer->setSize(480);
autoHideContainer->setAcceptDrops(true);
ui->menuView->addAction(dropDockWidget->toggleViewAction());
}
{
DroppableItem* droppableItem = new DroppableItem("Drop text here.");
CDockWidget* dropDockWidget = new CDockWidget("Tab 2");
dropDockWidget->setWidget(droppableItem);
dropDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
dropDockWidget->setMinimumSize(200,150);
dropDockWidget->setAcceptDrops(true);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::SideBarRight, dropDockWidget);
autoHideContainer->setSize(480);
autoHideContainer->setAcceptDrops(true);
ui->menuView->addAction(dropDockWidget->toggleViewAction());
}
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
PropertiesDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea);
ui->menuView->addAction(PropertiesDockWidget->toggleViewAction());
createPerspectiveUi();
}
CMainWindow::~CMainWindow()
{
delete ui;
}
void CMainWindow::createPerspectiveUi()
{
SavePerspectiveAction = new QAction("Create Perspective", this);
connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
PerspectiveListAction = new QWidgetAction(this);
PerspectiveComboBox = new QComboBox(this);
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
connect(PerspectiveComboBox, SIGNAL(currentTextChanged(const QString&)),
DockManager, SLOT(openPerspective(const QString&)));
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
ui->toolBar->addSeparator();
ui->toolBar->addAction(PerspectiveListAction);
ui->toolBar->addAction(SavePerspectiveAction);
}
void CMainWindow::savePerspective()
{
QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:");
if (PerspectiveName.isEmpty())
{
return;
}
DockManager->addPerspective(PerspectiveName);
QSignalBlocker Blocker(PerspectiveComboBox);
PerspectiveComboBox->clear();
PerspectiveComboBox->addItems(DockManager->perspectiveNames());
PerspectiveComboBox->setCurrentText(PerspectiveName);
}
//============================================================================
void CMainWindow::closeEvent(QCloseEvent* event)
{
// Delete dock manager here to delete all floating widgets. This ensures
// that all top level windows of the dock manager are properly closed
DockManager->deleteLater();
QMainWindow::closeEvent(event);
}

View File

@@ -0,0 +1,43 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QWidgetAction>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
protected:
virtual void closeEvent(QCloseEvent* event) override;
private:
QAction* SavePerspectiveAction = nullptr;
QWidgetAction* PerspectiveListAction = nullptr;
QComboBox* PerspectiveComboBox = nullptr;
Ui::CMainWindow *ui;
ads::CDockManager* DockManager;
ads::CDockAreaWidget* StatusDockArea;
ads::CDockWidget* TimelineDockWidget;
void createPerspectiveUi();
private slots:
void savePerspective();
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(configFlagsExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
)
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qt${QT_VERSION_MAJOR}advanceddocking)
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(CentralWidgetExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Central Widget Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,34 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = ConfigFlagsExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,10 @@
#include <mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,65 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QToolBar>
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
using namespace ads;
CMainWindow::CMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CMainWindow)
{
ui->setupUi(this);
// Add the toolbar
auto toolbar_ = addToolBar("Top Toolbar");
// Create the dock manager
ads::CDockManager::setConfigFlags(ads::CDockManager::DefaultOpaqueConfig);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasCloseButton,
false);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasUndockButton,
false);
ads::CDockManager::setConfigFlag(
ads::CDockManager::DockAreaHasTabsMenuButton, false);
auto DockManager = new ads::CDockManager(this);
// Create a dockable widget
QLabel *l1 = new QLabel();
l1->setWordWrap(true);
l1->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l1->setText("Docking widget 1");
ads::CDockWidget *dockWidget1 = new ads::CDockWidget("Dock 1");
dockWidget1->setWidget(l1);
DockManager->addDockWidget(ads::LeftDockWidgetArea, dockWidget1);
QLabel *l2 = new QLabel();
l2->setWordWrap(true);
l2->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l2->setText("Docking widget 2");
ads::CDockWidget *dockWidget2 = new ads::CDockWidget("Dock 2");
dockWidget2->setWidget(l2);
DockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget2);
// Add menu actions
ui->menuView->addAction(dockWidget1->toggleViewAction());
ui->menuView->addAction(dockWidget2->toggleViewAction());
toolbar_->addAction(dockWidget1->toggleViewAction());
toolbar_->addAction(dockWidget2->toggleViewAction());
}
CMainWindow::~CMainWindow()
{
delete ui;
}

View File

@@ -0,0 +1,27 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QWidgetAction>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
private:
Ui::CMainWindow *ui;
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -2,10 +2,12 @@ TEMPLATE = subdirs
SUBDIRS = \ SUBDIRS = \
autohide \ autohide \
autohidedragndrop \
centralwidget \ centralwidget \
simple \ simple \
hideshow \ hideshow \
sidebar \ sidebar \
deleteonclose \ deleteonclose \
emptydockarea \ emptydockarea \
dockindock dockindock \
configflags

View File

@@ -12,10 +12,14 @@ class CTitleBarButton : QToolButton
%End %End
public: public:
CTitleBarButton(bool visible = true, QWidget* parent /TransferThis/ = Q_NULLPTR ); CTitleBarButton(bool ShowInTitleBar, bool HideWhenDisabled, TitleBarButton ButtonId,
QWidget* /TransferThis/ = Q_NULLPTR );
virtual void setVisible(bool); virtual void setVisible(bool);
void setShowInTitleBar(bool); void setShowInTitleBar(bool);
TitleBarButton buttonId() const;
ads::CDockAreaTitleBar* titleBar() const;
bool isInAutoHideArea() const;
protected: protected:
bool event(QEvent *ev); bool event(QEvent *ev);
@@ -44,13 +48,15 @@ public:
ads::CDockAreaTabBar* tabBar() const; ads::CDockAreaTabBar* tabBar() const;
ads::CTitleBarButton* button(ads::TitleBarButton which) const; ads::CTitleBarButton* button(ads::TitleBarButton which) const;
ads::CElidingLabel* autoHideTitleLabel() const; ads::CElidingLabel* autoHideTitleLabel() const;
ads::CDockAreaWidget* dockAreaWidget() const;
void updateDockWidgetActionsButtons(); void updateDockWidgetActionsButtons();
virtual void setVisible(bool Visible); virtual void setVisible(bool Visible);
void insertWidget(int index, QWidget *widget /Transfer/ ); void insertWidget(int index, QWidget *widget /Transfer/ );
int indexOf(QWidget *widget) const; int indexOf(QWidget *widget) const;
QString titleBarButtonToolTip(ads::TitleBarButton Button) const; QString titleBarButtonToolTip(ads::TitleBarButton Button) const;
void setAreaFloating(); void setAreaFloating();
void showAutoHideControls(bool Show);
bool isAutoHide() const;
signals: signals:
void tabBarClicked(int index); void tabBarClicked(int index);

View File

@@ -41,6 +41,7 @@ public:
ads::CDockManager* dockManager() const; ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const; ads::CDockContainerWidget* dockContainer() const;
ads::CAutoHideDockContainer* autoHideDockContainer() const; ads::CAutoHideDockContainer* autoHideDockContainer() const;
ads::CDockSplitter* parentSplitter() const;
bool isAutoHide() const; bool isAutoHide() const;
void setAutoHideDockContainer(CAutoHideDockContainer*); void setAutoHideDockContainer(CAutoHideDockContainer*);
virtual QSize minimumSizeHint() const; virtual QSize minimumSizeHint() const;

View File

@@ -20,13 +20,14 @@ class CDockContainerWidget : QFrame
protected: protected:
virtual bool event(QEvent *e); virtual bool event(QEvent *e);
QSplitter* rootSplitter() const; ads::CDockSplitter* rootSplitter() const;
ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/, int TabIndex = -1); ads::CAutoHideDockContainer* createAndSetupAutoHideContainer(ads::SideBarLocation area, ads::CDockWidget* DockWidget /Transfer/, int TabIndex = -1);
void createRootSplitter(); void createRootSplitter();
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos); void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget, int TabIndex = -1); void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget, int TabIndex = -1);
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 /TransferBack/); void removeDockArea(ads::CDockAreaWidget* area /TransferBack/);
/*QList<QPointer<ads::CDockAreaWidget>> removeAllDockAreas();*/
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;

View File

@@ -172,6 +172,8 @@ public:
FloatingContainerForceNativeTitleBar, FloatingContainerForceNativeTitleBar,
FloatingContainerForceQWidgetTitleBar, FloatingContainerForceQWidgetTitleBar,
MiddleMouseButtonClosesTab, MiddleMouseButtonClosesTab,
DisableTabTextEliding,
ShowTabTextOnlyForActiveTab,
DefaultDockAreaButtons, DefaultDockAreaButtons,
DefaultBaseConfig, DefaultBaseConfig,
DefaultOpaqueConfig, DefaultOpaqueConfig,
@@ -188,6 +190,8 @@ public:
AutoHideSideBarsIconOnly, AutoHideSideBarsIconOnly,
AutoHideShowOnMouseOver, AutoHideShowOnMouseOver,
AutoHideCloseButtonCollapsesDock, AutoHideCloseButtonCollapsesDock,
AutoHideHasCloseButton,
AutoHideHasMinimizeButton,
DefaultAutoHideConfig, DefaultAutoHideConfig,
}; };
typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags; typedef QFlags<ads::CDockManager::eAutoHideFlag> AutoHideFlags;
@@ -245,6 +249,12 @@ public:
void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes); void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes);
static void setFloatingContainersTitle(const QString& Title); static void setFloatingContainersTitle(const QString& Title);
static QString floatingContainersTitle(); static QString floatingContainersTitle();
void setDockWidgetToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
Qt::ToolButtonStyle dockWidgetToolBarStyle(ads::CDockWidget::eState State) const;
void setDockWidgetToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
QSize dockWidgetToolBarIconSize(ads::CDockWidget::eState State) const;
ads::CDockWidget::DockWidgetFeatures globallyLockedDockWidgetFeatures() const;
void lockDockWidgetFeaturesGlobally(ads::CDockWidget::DockWidgetFeatures Features = ads::CDockWidget::GloballyLockableFeatures);
public slots: public slots:
void endLeavingMinimizedState(); void endLeavingMinimizedState();

View File

@@ -39,6 +39,7 @@ public:
DefaultDockWidgetFeatures, DefaultDockWidgetFeatures,
AllDockWidgetFeatures, AllDockWidgetFeatures,
DockWidgetAlwaysCloseAndDelete, DockWidgetAlwaysCloseAndDelete,
GloballyLockableFeatures,
NoDockWidgetFeatures NoDockWidgetFeatures
}; };
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures; typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
@@ -50,6 +51,12 @@ public:
StateFloating StateFloating
}; };
enum eToolBarStyleSource
{
ToolBarStyleFromDockManager,
ToolBarStyleFromDockWidget
};
enum eInsertMode enum eInsertMode
{ {
AutoScrollArea, AutoScrollArea,
@@ -72,7 +79,7 @@ public:
}; };
CDockWidget(const QString &title, QWidget* parent /TransferThis/ = 0); CDockWidget(const QString &title, QWidget* parent /TransferThis/ = Q_NULLPTR);
virtual ~CDockWidget(); virtual ~CDockWidget();
virtual QSize minimumSizeHint() const; virtual QSize minimumSizeHint() const;
void setWidget(QWidget* widget /Transfer/, ads::CDockWidget::eInsertMode InsertMode = AutoScrollArea); void setWidget(QWidget* widget /Transfer/, ads::CDockWidget::eInsertMode InsertMode = AutoScrollArea);
@@ -82,6 +89,7 @@ public:
void setFeatures(ads::CDockWidget::DockWidgetFeatures features); void setFeatures(ads::CDockWidget::DockWidgetFeatures features);
void setFeature(ads::CDockWidget::DockWidgetFeature flag, bool on); void setFeature(ads::CDockWidget::DockWidgetFeature flag, bool on);
ads::CDockWidget::DockWidgetFeatures features() const; ads::CDockWidget::DockWidgetFeatures features() const;
void notifyFeaturesChanged();
ads::CDockManager* dockManager() const; ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const; ads::CDockContainerWidget* dockContainer() const;
ads::CFloatingDockContainer* floatingDockContainer() const; ads::CFloatingDockContainer* floatingDockContainer() const;
@@ -95,6 +103,7 @@ public:
bool isInFloatingContainer() const; bool isInFloatingContainer() const;
bool isClosed() const; bool isClosed() const;
QAction* toggleViewAction() const; QAction* toggleViewAction() const;
void setToggleViewAction(QAction* action);
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode); void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode); void setMinimumSizeHintMode(ads::CDockWidget::eMinimumSizeHintMode Mode);
ads::CDockWidget::eMinimumSizeHintMode minimumSizeHintMode() const; ads::CDockWidget::eMinimumSizeHintMode minimumSizeHintMode() const;
@@ -104,6 +113,8 @@ public:
QToolBar* toolBar() const; QToolBar* toolBar() const;
QToolBar* createDefaultToolBar(); QToolBar* createDefaultToolBar();
void setToolBar(QToolBar* ToolBar /Transfer/ ); void setToolBar(QToolBar* ToolBar /Transfer/ );
void setToolBarStyleSource(ads::CDockWidget::eToolBarStyleSource Source);
ads::CDockWidget::eToolBarStyleSource toolBarStyleSource() const;
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);

View File

@@ -17,8 +17,8 @@ protected:
virtual void mouseDoubleClickEvent( QMouseEvent *ev ); virtual void mouseDoubleClickEvent( QMouseEvent *ev );
public: public:
CElidingLabel(QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0); CElidingLabel(QWidget* parent /TransferThis/ = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0); CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags ());
virtual ~CElidingLabel(); virtual ~CElidingLabel();
Qt::TextElideMode elideMode() const; Qt::TextElideMode elideMode() const;
void setElideMode(Qt::TextElideMode mode); void setElideMode(Qt::TextElideMode mode);

View File

@@ -44,6 +44,7 @@ protected:
void startDragging(const QPoint& DragStartMousePos, const QSize& Size, void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler); QWidget* MouseEventHandler);
virtual void finishDragging(); virtual void finishDragging();
void deleteContent();
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size); void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size);
void moveFloating(); void moveFloating();
bool restoreState(ads::CDockingStateReader& Stream, bool Testing); bool restoreState(ads::CDockingStateReader& Stream, bool Testing);
@@ -82,6 +83,7 @@ public:
bool hasTopLevelDockWidget() const; bool hasTopLevelDockWidget() const;
ads::CDockWidget* topLevelDockWidget() const; ads::CDockWidget* topLevelDockWidget() const;
QList<ads::CDockWidget*> dockWidgets() const; QList<ads::CDockWidget*> dockWidgets() const;
void finishDropOperation();
%If (WS_X11) %If (WS_X11)
void onMaximizeRequest(); void onMaximizeRequest();

View File

@@ -73,7 +73,8 @@ namespace ads
TitleBarButtonTabsMenu, TitleBarButtonTabsMenu,
TitleBarButtonUndock, TitleBarButtonUndock,
TitleBarButtonClose, TitleBarButtonClose,
TitleBarButtonAutoHide TitleBarButtonAutoHide,
TitleBarButtonMinimize
}; };
enum eDragState enum eDragState

View File

@@ -657,6 +657,14 @@ bool CAutoHideDockContainer::event(QEvent* event)
return Super::event(event); return Super::event(event);
} }
//============================================================================
void CAutoHideDockContainer::dragLeaveEvent(QDragLeaveEvent*)
{
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
collapseView(true);
}
}
//============================================================================ //============================================================================
Qt::Orientation CAutoHideDockContainer::orientation() const Qt::Orientation CAutoHideDockContainer::orientation() const
@@ -709,4 +717,3 @@ int CAutoHideDockContainer::tabIndex() const
} }
} }

View File

@@ -65,6 +65,7 @@ protected:
virtual void resizeEvent(QResizeEvent* event) override; virtual void resizeEvent(QResizeEvent* event) override;
virtual void leaveEvent(QEvent *event) override; virtual void leaveEvent(QEvent *event) override;
virtual bool event(QEvent* event) override; virtual bool event(QEvent* event) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
/** /**
* Updates the size considering the size limits and the resize margins * Updates the size considering the size limits and the resize margins

View File

@@ -414,7 +414,14 @@ void CAutoHideSideBar::saveState(QXmlStreamWriter& s) const
QSize CAutoHideSideBar::minimumSizeHint() const QSize CAutoHideSideBar::minimumSizeHint() const
{ {
QSize Size = sizeHint(); QSize Size = sizeHint();
Size.setWidth(10); if (d->isHorizontal())
{
Size.setWidth(0);
}
else
{
Size.setHeight(0);
}
return Size; return Size;
} }

View File

@@ -33,6 +33,8 @@
#include <QApplication> #include <QApplication>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMenu> #include <QMenu>
#include <QEvent>
#include <QTimer>
#include "AutoHideDockContainer.h" #include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h" #include "AutoHideSideBar.h"
@@ -41,6 +43,7 @@
#include "DockWidget.h" #include "DockWidget.h"
#include "FloatingDragPreview.h" #include "FloatingDragPreview.h"
#include "DockOverlay.h" #include "DockOverlay.h"
#include "ads_globals.h"
namespace ads namespace ads
{ {
@@ -55,6 +58,7 @@ struct AutoHideTabPrivate
CAutoHideSideBar* SideBar = nullptr; CAutoHideSideBar* SideBar = nullptr;
Qt::Orientation Orientation{Qt::Vertical}; Qt::Orientation Orientation{Qt::Vertical};
QElapsedTimer TimeSinceHoverMousePress; QElapsedTimer TimeSinceHoverMousePress;
QTimer DragOverTimer;
bool MousePressed = false; bool MousePressed = false;
eDragState DragState = DraggingInactive; eDragState DragState = DraggingInactive;
QPoint GlobalDragStartMousePosition; QPoint GlobalDragStartMousePosition;
@@ -252,6 +256,14 @@ CAutoHideTab::CAutoHideTab(QWidget* parent) :
{ {
setAttribute(Qt::WA_NoMousePropagation); setAttribute(Qt::WA_NoMousePropagation);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
setAcceptDrops(true);
}
d->DragOverTimer.setInterval(CDockManager::configParam(
CDockManager::AutoHideOpenOnDragHoverDelay_ms, 500).toInt());
d->DragOverTimer.setSingleShot(true);
connect(&d->DragOverTimer, &QTimer::timeout, this, &CAutoHideTab::onDragHoverDelayExpired);
} }
@@ -355,7 +367,6 @@ bool CAutoHideTab::event(QEvent* event)
case QEvent::Leave: case QEvent::Leave:
d->forwardEventToDockContainer(event); d->forwardEventToDockContainer(event);
break; break;
default: default:
break; break;
} }
@@ -493,48 +504,74 @@ void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
//============================================================================ //============================================================================
void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev) void CAutoHideTab::mouseMoveEvent(QMouseEvent *ev)
{ {
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive)) if (!(ev->buttons() & Qt::LeftButton)
{ || d->isDraggingState(DraggingInactive))
d->DragState = DraggingInactive;
Super::mouseMoveEvent(ev);
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
Super::mouseMoveEvent(ev);
return;
}
// move tab
if (d->isDraggingState(DraggingTab))
{
// Moving the tab is always allowed because it does not mean moving the
// dock widget around
//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 ?
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - internal::globalPositionOf(ev).y());
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
{ {
// Floating is only allowed for widgets that are floatable d->DragState = DraggingInactive;
// We can create the drag preview if the widget is movable. Super::mouseMoveEvent(ev);
auto Features = d->DockWidget->features(); return;
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
d->startFloating();
}
return;
} }
Super::mouseMoveEvent(ev); // move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
Super::mouseMoveEvent(ev);
return;
}
// move tab
if (d->isDraggingState(DraggingTab))
{
// Moving the tab is always allowed because it does not mean moving the
// dock widget around
//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 ?
int DragDistanceY = qAbs(
d->GlobalDragStartMousePosition.y()
- internal::globalPositionOf(ev).y());
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
{
// Floating is only allowed for widgets that are floatable
// We can create the drag preview if the widget is movable.
auto Features = d->DockWidget->features();
if (Features.testFlag(CDockWidget::DockWidgetFloatable)
|| (Features.testFlag(CDockWidget::DockWidgetMovable)))
{
d->startFloating();
}
return;
}
Super::mouseMoveEvent(ev);
}
//============================================================================
void CAutoHideTab::dragEnterEvent(QDragEnterEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.start();
ev->accept();
}
}
//============================================================================
void CAutoHideTab::dragLeaveEvent(QDragLeaveEvent *ev)
{
Q_UNUSED(ev);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover))
{
d->DragOverTimer.stop();
}
} }
@@ -544,7 +581,6 @@ void CAutoHideTab::requestCloseDockWidget()
d->DockWidget->requestCloseDockWidget(); d->DockWidget->requestCloseDockWidget();
} }
//============================================================================ //============================================================================
int CAutoHideTab::tabIndex() const int CAutoHideTab::tabIndex() const
{ {
@@ -557,4 +593,28 @@ int CAutoHideTab::tabIndex() const
} }
//============================================================================
void CAutoHideTab::onDragHoverDelayExpired()
{
static const char* const PropertyId = "ActiveDragOverAutoHideContainer";
// First we check if there is an active auto hide container that is visible
// In this case, we collapse it before we open the new one
auto v = d->DockWidget->dockManager()->property(PropertyId);
if (v.isValid())
{
auto ActiveAutoHideContainer = v.value<QPointer<CAutoHideDockContainer>>();
if (ActiveAutoHideContainer)
{
ActiveAutoHideContainer->collapseView(true);
}
}
auto AutoHideContainer = d->DockWidget->autoHideDockContainer();
AutoHideContainer->collapseView(false);
d->DockWidget->dockManager()->setProperty(PropertyId,
QVariant::fromValue(QPointer<CAutoHideDockContainer>(AutoHideContainer)));
}
} }

View File

@@ -67,6 +67,7 @@ private:
private Q_SLOTS: private Q_SLOTS:
void onAutoHideToActionClicked(); void onAutoHideToActionClicked();
void onDragHoverDelayExpired();
protected: protected:
void setSideBar(CAutoHideSideBar *SideTabBar); void setSideBar(CAutoHideSideBar *SideTabBar);
@@ -76,6 +77,8 @@ protected:
virtual void mousePressEvent(QMouseEvent* ev) override; virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override; virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override; virtual void mouseMoveEvent(QMouseEvent* ev) override;
virtual void dragEnterEvent(QDragEnterEvent* ev) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
public: public:
using Super = CPushButton; using Super = CPushButton;

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT}) project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
include(GNUInstallDirs)
if (${QT_VERSION_MAJOR}) if (${QT_VERSION_MAJOR})
message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}") message(STATUS "Forced to use Qt version ${QT_VERSION_MAJOR}")
find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)

View File

@@ -111,7 +111,7 @@ void DockAreaTabBarPrivate::updateTabs()
// Sometimes the synchronous calculation of the rectangular area fails // Sometimes the synchronous calculation of the rectangular area fails
// Therefore we use QTimer::singleShot here to execute the call // Therefore we use QTimer::singleShot here to execute the call
// within the event loop - see #520 // within the event loop - see #520
QTimer::singleShot(0, TabWidget, [&, TabWidget] QTimer::singleShot(0, _this, [&, TabWidget]
{ {
_this->ensureWidgetVisible(TabWidget); _this->ensureWidgetVisible(TabWidget);
}); });
@@ -161,15 +161,13 @@ CDockAreaTabBar::~CDockAreaTabBar()
void CDockAreaTabBar::wheelEvent(QWheelEvent* Event) void CDockAreaTabBar::wheelEvent(QWheelEvent* Event)
{ {
Event->accept(); Event->accept();
const int direction = Event->angleDelta().y(); int numPixels = Event->pixelDelta().y();
if (direction < 0) if (!numPixels)
{ {
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20); numPixels = Event->angleDelta().y() / 5;
} }
else
{ horizontalScrollBar()->setValue(horizontalScrollBar()->value() - numPixels);
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
}
} }
@@ -390,15 +388,18 @@ 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() = qMax(0, MousePos.x());
MousePos.rx() = qMin(d->lastTab()->geometry().right(), MousePos.x()); MousePos.rx() = qMin(width(), 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)
{ {
CDockWidgetTab* DropTab = tab(i); CDockWidgetTab* DropTab = tab(i);
auto TabGeometry = DropTab->geometry();
TabGeometry.setTopLeft(d->TabsContainerWidget->mapToParent(TabGeometry.topLeft()));
TabGeometry.setBottomRight(d->TabsContainerWidget->mapToParent(TabGeometry.bottomRight()));
if (DropTab == MovingTab || !DropTab->isVisibleTo(this) if (DropTab == MovingTab || !DropTab->isVisibleTo(this)
|| !DropTab->geometry().contains(MousePos)) || !TabGeometry.contains(MousePos))
{ {
continue; continue;
} }
@@ -470,6 +471,15 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
updateGeometry(); updateGeometry();
break; break;
// Manage wheel event
case QEvent::Wheel:
// Ignore wheel events if tab is currently dragged
if (Tab->dragState() == DraggingInactive)
{
wheelEvent((QWheelEvent* )event);
}
break;
default: default:
break; break;
} }
@@ -545,6 +555,13 @@ int CDockAreaTabBar::tabInsertIndexAt(const QPoint& Pos) const
} }
} }
//===========================================================================
bool CDockAreaTabBar::areTabsOverflowing() const
{
return d->TabsContainerWidget->width() > width();
}
} // namespace ads } // namespace ads

View File

@@ -153,6 +153,12 @@ public:
*/ */
virtual QSize sizeHint() const override; virtual QSize sizeHint() const override;
/**
* This function returns true, if the tabs need more space than the size
* of the tab bar.
*/
bool areTabsOverflowing() const;
public Q_SLOTS: public Q_SLOTS:
/** /**
* This property sets the index of the tab bar's visible tab * This property sets the index of the tab bar's visible tab

View File

@@ -377,27 +377,48 @@ CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
return d->TabBar; return d->TabBar;
} }
//============================================================================
void CDockAreaTitleBar::resizeEvent(QResizeEvent *event)
{
Super::resizeEvent(event);
if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility)
&& CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{
markTabsMenuOutdated();
}
}
//============================================================================ //============================================================================
void CDockAreaTitleBar::markTabsMenuOutdated() void CDockAreaTitleBar::markTabsMenuOutdated()
{ {
if(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility)) if (CDockManager::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
{ {
bool hasElidedTabTitle = false; bool TabsMenuButtonVisible = false;
for (int i = 0; i < d->TabBar->count(); ++i) if (CDockManager::testConfigFlag(CDockManager::DisableTabTextEliding))
{ {
if (!d->TabBar->isTabOpen(i)) TabsMenuButtonVisible = d->TabBar->areTabsOverflowing();
{
continue;
}
CDockWidgetTab* Tab = d->TabBar->tab(i);
if(Tab->isTitleElided())
{
hasElidedTabTitle = true;
break;
}
} }
bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1)); else
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible)); {
bool hasElidedTabTitle = false;
for (int i = 0; i < d->TabBar->count(); ++i)
{
if (!d->TabBar->isTabOpen(i))
{
continue;
}
CDockWidgetTab* Tab = d->TabBar->tab(i);
if(Tab->isTitleElided())
{
hasElidedTabTitle = true;
break;
}
}
TabsMenuButtonVisible = (hasElidedTabTitle && (d->TabBar->count() > 1));
}
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, TabsMenuButtonVisible));
} }
d->MenuOutdated = true; d->MenuOutdated = true;
} }
@@ -744,24 +765,35 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
return; return;
} }
const bool isAutoHide = d->DockArea->isAutoHide(); auto Menu = buildContextMenu(nullptr);
Menu->exec(ev->globalPos());
delete Menu;
}
QMenu* CDockAreaTitleBar::buildContextMenu(QMenu *Menu)
{
const bool isAutoHide = d->DockArea->isAutoHide();
const bool isTopLevelArea = d->DockArea->isTopLevelArea(); const bool isTopLevelArea = d->DockArea->isTopLevelArea();
QAction* Action; QAction* Action;
QMenu Menu(this); if (Menu == nullptr)
if (!isTopLevelArea) {
Menu = new QMenu(this);
}
if (!isTopLevelArea)
{ {
Action = Menu.addAction(isAutoHide ? tr("Detach") : tr("Detach Group"), Action = Menu->addAction(isAutoHide ? tr("Detach") : tr("Detach Group"),
this, SLOT(onUndockButtonClicked())); this, SLOT(onUndockButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)); Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled)) if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{ {
Action = Menu.addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked())); Action = Menu->addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable); auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(AreaIsPinnable); Action->setEnabled(AreaIsPinnable);
if (!isAutoHide) if (!isAutoHide)
{ {
auto menu = Menu.addMenu(tr("Pin Group To...")); auto menu = Menu->addMenu(tr("Pin Group To..."));
menu->setEnabled(AreaIsPinnable); menu->setEnabled(AreaIsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu); d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu); d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
@@ -769,28 +801,27 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu); d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
} }
} }
Menu.addSeparator(); Menu->addSeparator();
} }
if (isAutoHide) if (isAutoHide)
{ {
Action = Menu.addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer())); Action = Menu->addAction(tr("Minimize"), this, SLOT(minimizeAutoHideContainer()));
Action = Menu.addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered())); Action = Menu->addAction(tr("Close"), this, SLOT(onAutoHideCloseActionTriggered()));
} }
else else
{ {
Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked())); Action = Menu->addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
} }
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable)); Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
if (!isAutoHide && !isTopLevelArea) if (!isAutoHide && !isTopLevelArea)
{ {
Action = Menu.addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas())); Action = Menu->addAction(tr("Close Other Groups"), d->DockArea, SLOT(closeOtherAreas()));
} }
Menu.exec(ev->globalPos()); return Menu;
} }
//============================================================================ //============================================================================
void CDockAreaTitleBar::insertWidget(int index, QWidget *widget) void CDockAreaTitleBar::insertWidget(int index, QWidget *widget)
{ {

View File

@@ -152,6 +152,11 @@ protected:
*/ */
virtual void contextMenuEvent(QContextMenuEvent *event) override; virtual void contextMenuEvent(QContextMenuEvent *event) override;
/**
* Handle resize events
*/
virtual void resizeEvent(QResizeEvent *event) override;
public Q_SLOTS: public Q_SLOTS:
/** /**
* Call this slot to tell the title bar that it should update the tabs menu * Call this slot to tell the title bar that it should update the tabs menu
@@ -244,6 +249,20 @@ public:
*/ */
bool isAutoHide() const; bool isAutoHide() const;
/**
* Fills the provided menu with standard entries. If a nullptr is passed, a
* new menu is created and filled with standard entries.
* This function is called from the actual version of contextMenuEvent, but
* can be called from any code. Caller is responsible of deleting the created
* object.
*
* @param menu The QMenu to fill with standard entries. If nullptr, a new
* QMenu will be created.
* @return The filled QMenu, either the provided one or a newly created one if
* nullptr was passed.
*/
virtual QMenu *buildContextMenu(QMenu *);
Q_SIGNALS: Q_SIGNALS:
/** /**
* This signal is emitted if a tab in the tab bar is clicked by the user * This signal is emitted if a tab in the tab bar is clicked by the user

View File

@@ -34,7 +34,6 @@
#include <QStackedLayout> #include <QStackedLayout>
#include <QScrollBar> #include <QScrollBar>
#include <QWheelEvent>
#include <QStyle> #include <QStyle>
#include <QPushButton> #include <QPushButton>
#include <QDebug> #include <QDebug>

View File

@@ -38,6 +38,7 @@
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter) QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
QT_FORWARD_DECLARE_CLASS(QAbstractButton) QT_FORWARD_DECLARE_CLASS(QAbstractButton)
QT_FORWARD_DECLARE_CLASS(QMenu)
namespace ads namespace ads
{ {

View File

@@ -48,6 +48,7 @@
#include <QApplication> #include <QApplication>
#include <QWindow> #include <QWindow>
#include <QWindowStateChangeEvent> #include <QWindowStateChangeEvent>
#include <QVector>
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockOverlay.h" #include "DockOverlay.h"
@@ -94,6 +95,7 @@ enum eStateFileVersion
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig; static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
static CDockManager::AutoHideFlags StaticAutoHideConfigFlags; // auto hide feature is disabled by default static CDockManager::AutoHideFlags StaticAutoHideConfigFlags; // auto hide feature is disabled by default
static QVector<QVariant> StaticConfigParams(CDockManager::ConfigParamCount);
static QString FloatingContainersTitle; static QString FloatingContainersTitle;
@@ -1475,6 +1477,20 @@ CDockWidget::DockWidgetFeatures CDockManager::globallyLockedDockWidgetFeatures()
} }
//===========================================================================
void CDockManager::setConfigParam(CDockManager::eConfigParam Param, QVariant Value)
{
StaticConfigParams[Param] = Value;
}
//===========================================================================
QVariant CDockManager::configParam(eConfigParam Param, QVariant Default)
{
return StaticConfigParams[Param].isValid() ? StaticConfigParams[Param] : Default;
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -254,6 +254,7 @@ public:
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button
AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget
AutoHideOpenOnDragHover = 0x200, ///< if this flag is set, dragging hover the tab bar will open the dock
DefaultAutoHideConfig = AutoHideFeatureEnabled DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton | DockAreaHasAutoHideButton
@@ -262,6 +263,15 @@ public:
}; };
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag) Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
/**
* Global configuration parameters that you can set via setConfigParam()
*/
enum eConfigParam
{
AutoHideOpenOnDragHoverDelay_ms, ///< Delay in ms before the dock opens on drag hover if AutoHideOpenOnDragHover flag is set
ConfigParamCount // just a delimiter to count number of config params
};
/** /**
* Default Constructor. * Default Constructor.
@@ -323,6 +333,17 @@ public:
*/ */
static bool testAutoHideConfigFlag(eAutoHideFlag Flag); static bool testAutoHideConfigFlag(eAutoHideFlag Flag);
/**
* Sets the value for the given config parameter
*/
static void setConfigParam(eConfigParam Param, QVariant Value);
/**
* Returns the value for the given config parameter or the default value
* if the parameter is not set.
*/
static QVariant configParam(eConfigParam Param, QVariant Default);
/** /**
* Returns the global icon provider. * Returns the global icon provider.
* The icon provider enables the use of custom icons in case using * The icon provider enables the use of custom icons in case using

View File

@@ -529,26 +529,34 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
return; return;
} }
auto Menu = buildContextMenu(nullptr);
d->saveDragStartMousePosition(ev->globalPos()); d->saveDragStartMousePosition(ev->globalPos());
Menu->exec(ev->globalPos());
}
QMenu* CDockWidgetTab::buildContextMenu(QMenu *Menu)
{
if (Menu == nullptr) {
Menu = new QMenu(this);
}
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable); const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget(); const bool isNotOnlyTabInContainer = !d->DockArea->dockContainer()->hasTopLevelDockWidget();
const bool isTopLevelArea = d->DockArea->isTopLevelArea(); const bool isTopLevelArea = d->DockArea->isTopLevelArea();
const bool isDetachable = isFloatable && isNotOnlyTabInContainer; const bool isDetachable = isFloatable && isNotOnlyTabInContainer;
QAction* Action; QAction* Action;
QMenu Menu(this);
if (!isTopLevelArea) if (!isTopLevelArea)
{ {
Action = Menu.addAction(tr("Detach"), this, SLOT(detachDockWidget())); Action = Menu->addAction(tr("Detach"), this, SLOT(detachDockWidget()));
Action->setEnabled(isDetachable); Action->setEnabled(isDetachable);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled)) if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{ {
Action = Menu.addAction(tr("Pin"), this, SLOT(autoHideDockWidget())); Action = Menu->addAction(tr("Pin"), this, SLOT(autoHideDockWidget()));
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable); auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(IsPinnable); Action->setEnabled(IsPinnable);
auto menu = Menu.addMenu(tr("Pin To...")); auto menu = Menu->addMenu(tr("Pin To..."));
menu->setEnabled(IsPinnable); menu->setEnabled(IsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu); d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu); d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
@@ -557,17 +565,16 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
} }
} }
Menu.addSeparator(); Menu->addSeparator();
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested())); Action = Menu->addAction(tr("Close"), this, SIGNAL(closeRequested()));
Action->setEnabled(isClosable()); Action->setEnabled(isClosable());
if (d->DockArea->openDockWidgetsCount() > 1) if (d->DockArea->openDockWidgetsCount() > 1)
{ {
Action = Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested())); Action = Menu->addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
} }
Menu.exec(ev->globalPos());
return Menu;
} }
//============================================================================ //============================================================================
bool CDockWidgetTab::isActiveTab() const bool CDockWidgetTab::isActiveTab() const
{ {
@@ -789,6 +796,13 @@ bool CDockWidgetTab::event(QEvent *e)
} }
//============================================================================
eDragState CDockWidgetTab::dragState() const
{
return d->DragState;
}
//============================================================================ //============================================================================
void CDockWidgetTab::onDockWidgetFeaturesChanged() void CDockWidgetTab::onDockWidgetFeaturesChanged()
{ {

View File

@@ -35,6 +35,8 @@
#include "ads_globals.h" #include "ads_globals.h"
QT_FORWARD_DECLARE_CLASS(QMenu)
namespace ads namespace ads
{ {
class CDockWidget; class CDockWidget;
@@ -178,6 +180,26 @@ public:
*/ */
void setIconSize(const QSize& Size); void setIconSize(const QSize& Size);
/**
* Returns the current drag state of this tab.
* Use this function to determine if the tab is currently being dragged
*/
eDragState dragState() const;
/**
* Fills the provided menu with standard entries. If a nullptr is passed, a
* new menu is created and filled with standard entries.
* This function is called from the actual version of contextMenuEvent, but
* can be called from any code. Caller is responsible of deleting the created
* object.
*
* @param menu The QMenu to fill with standard entries. If nullptr, a new
* QMenu will be created.
* @return The filled QMenu, either the provided one or a newly created one if
* nullptr was passed.
*/
virtual QMenu *buildContextMenu(QMenu *);
public Q_SLOTS: public Q_SLOTS:
virtual void setVisible(bool visible) override; virtual void setVisible(bool visible) override;

View File

@@ -1331,7 +1331,8 @@ void CFloatingDockContainer::onMaximizeRequest()
//============================================================================ //============================================================================
void CFloatingDockContainer::showNormal(bool fixGeometry) void CFloatingDockContainer::showNormal(bool fixGeometry)
{ {
if (windowState() == Qt::WindowMaximized) if ( (windowState() & Qt::WindowMaximized) != 0 ||
(windowState() & Qt::WindowFullScreen) != 0)
{ {
QRect oldNormal = normalGeometry(); QRect oldNormal = normalGeometry();
Super::showNormal(); Super::showNormal();

View File

@@ -131,15 +131,6 @@ protected:
virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size, virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState, QWidget* MouseEventHandler) override; eDragState DragState, QWidget* MouseEventHandler) override;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/** /**
* Call this function if you explicitly want to signal that dragging has * Call this function if you explicitly want to signal that dragging has
* finished * finished
@@ -236,6 +227,15 @@ public:
*/ */
CDockContainerWidget* dockContainer() const; CDockContainerWidget* dockContainer() const;
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/** /**
* This function returns true, if it can be closed. * This function returns true, if it can be closed.
* It can be closed, if all dock widgets in all dock areas can be closed * It can be closed, if all dock widgets in all dock areas can be closed

View File

@@ -158,7 +158,7 @@ enum SideBarLocation
SideBarBottom, SideBarBottom,
SideBarNone SideBarNone
}; };
Q_ENUMS(SideBarLocation); Q_ENUMS(SideBarLocation)
namespace internal namespace internal