From a13ed7e4d6c8c115a24d61add01d71e6f446b522 Mon Sep 17 00:00:00 2001 From: TheBoje <47856523+TheBoje@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:36:53 +0200 Subject: [PATCH] Add AutoHideDragNDrop example --- CMakeLists.txt | 2 +- doc/user-guide.md | 2 +- examples/CMakeLists.txt | 3 +- examples/autohidedragndrop/CMakeLists.txt | 29 +++++ .../autohidedragndrop/autohidedragndrop.pro | 36 ++++++ examples/autohidedragndrop/droppableitem.cpp | 37 ++++++ examples/autohidedragndrop/droppableitem.h | 19 +++ examples/autohidedragndrop/main.cpp | 10 ++ examples/autohidedragndrop/main.py | 84 +++++++++++++ examples/autohidedragndrop/mainwindow.cpp | 116 ++++++++++++++++++ examples/autohidedragndrop/mainwindow.h | 43 +++++++ examples/autohidedragndrop/mainwindow.ui | 47 +++++++ 12 files changed, 425 insertions(+), 3 deletions(-) create mode 100644 examples/autohidedragndrop/CMakeLists.txt create mode 100644 examples/autohidedragndrop/autohidedragndrop.pro create mode 100644 examples/autohidedragndrop/droppableitem.cpp create mode 100644 examples/autohidedragndrop/droppableitem.h create mode 100644 examples/autohidedragndrop/main.cpp create mode 100644 examples/autohidedragndrop/main.py create mode 100644 examples/autohidedragndrop/mainwindow.cpp create mode 100644 examples/autohidedragndrop/mainwindow.h create mode 100644 examples/autohidedragndrop/mainwindow.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 29ca64f..00d0f0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) - +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (POLICY CMP0091) cmake_policy(SET CMP0091 NEW) endif (POLICY CMP0091) diff --git a/doc/user-guide.md b/doc/user-guide.md index 4edf7a6..024c5e4 100644 --- a/doc/user-guide.md +++ b/doc/user-guide.md @@ -712,7 +712,7 @@ If this flag is set (disabled by default), then holding a dragging cursor hover ![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif) -Said dock must be set to accept drops to hide when cursor leaves its scope. +Said dock must be set to accept drops to hide when cursor leaves its scope. See `AutoHideDragNDropExample` for more details. ## DockWidget Feature Flags diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ba2a064..8da1f33 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,5 +6,6 @@ add_subdirectory(sidebar) add_subdirectory(deleteonclose) add_subdirectory(centralwidget) add_subdirectory(autohide) +add_subdirectory(autohidedragndrop) add_subdirectory(emptydockarea) -add_subdirectory(dockindock) \ No newline at end of file +add_subdirectory(dockindock) diff --git a/examples/autohidedragndrop/CMakeLists.txt b/examples/autohidedragndrop/CMakeLists.txt new file mode 100644 index 0000000..3b8f077 --- /dev/null +++ b/examples/autohidedragndrop/CMakeLists.txt @@ -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" +) diff --git a/examples/autohidedragndrop/autohidedragndrop.pro b/examples/autohidedragndrop/autohidedragndrop.pro new file mode 100644 index 0000000..ce86127 --- /dev/null +++ b/examples/autohidedragndrop/autohidedragndrop.pro @@ -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 + diff --git a/examples/autohidedragndrop/droppableitem.cpp b/examples/autohidedragndrop/droppableitem.cpp new file mode 100644 index 0000000..390c1b8 --- /dev/null +++ b/examples/autohidedragndrop/droppableitem.cpp @@ -0,0 +1,37 @@ +#include "droppableitem.h" + +#include +#include +#include +#include +#include + +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) +{ + unsetCursor(); +} + +void DroppableItem::dropEvent(QDropEvent* event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + setText(event->mimeData()->text()); + } +} diff --git a/examples/autohidedragndrop/droppableitem.h b/examples/autohidedragndrop/droppableitem.h new file mode 100644 index 0000000..a8fcd91 --- /dev/null +++ b/examples/autohidedragndrop/droppableitem.h @@ -0,0 +1,19 @@ +#include +#include + +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; +}; diff --git a/examples/autohidedragndrop/main.cpp b/examples/autohidedragndrop/main.cpp new file mode 100644 index 0000000..fa4c4fd --- /dev/null +++ b/examples/autohidedragndrop/main.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CMainWindow w; + w.show(); + return a.exec(); +} diff --git a/examples/autohidedragndrop/main.py b/examples/autohidedragndrop/main.py new file mode 100644 index 0000000..4ec084b --- /dev/null +++ b/examples/autohidedragndrop/main.py @@ -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_() diff --git a/examples/autohidedragndrop/mainwindow.cpp b/examples/autohidedragndrop/mainwindow.cpp new file mode 100644 index 0000000..6443b35 --- /dev/null +++ b/examples/autohidedragndrop/mainwindow.cpp @@ -0,0 +1,116 @@ +#include "mainwindow.h" +#include "droppableitem.h" + +#include "ui_mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); + 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"); + 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()); + + 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); +} + + + diff --git a/examples/autohidedragndrop/mainwindow.h b/examples/autohidedragndrop/mainwindow.h new file mode 100644 index 0000000..75869da --- /dev/null +++ b/examples/autohidedragndrop/mainwindow.h @@ -0,0 +1,43 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +#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 diff --git a/examples/autohidedragndrop/mainwindow.ui b/examples/autohidedragndrop/mainwindow.ui new file mode 100644 index 0000000..f7d3b09 --- /dev/null +++ b/examples/autohidedragndrop/mainwindow.ui @@ -0,0 +1,47 @@ + + + CMainWindow + + + + 0 + 0 + 1284 + 757 + + + + MainWindow + + + + + + 0 + 0 + 1284 + 21 + + + + + View + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + +