From 7123410bb10d32bba13d5a9863d7e4089a4525da Mon Sep 17 00:00:00 2001 From: mfreiholz Date: Wed, 3 Feb 2016 10:50:34 +0100 Subject: [PATCH] Available drop areas for DropOverlay can be configured via constructor now. Better visualization for edge-drops, always shown entire rect as active drop area and only show a single drop icon. --- AdvancedDockingSystem/include/ads/API.h | 17 ++-- .../include/ads/DropOverlay.h | 10 ++- AdvancedDockingSystem/src/ContainerWidget.cpp | 6 +- AdvancedDockingSystem/src/DropOverlay.cpp | 83 +++++++++++++------ AdvancedDockingSystem/src/FloatingWidget.cpp | 3 +- .../src/SectionTitleWidget.cpp | 10 +-- 6 files changed, 86 insertions(+), 43 deletions(-) diff --git a/AdvancedDockingSystem/include/ads/API.h b/AdvancedDockingSystem/include/ads/API.h index 9054d25..c19db3b 100644 --- a/AdvancedDockingSystem/include/ads/API.h +++ b/AdvancedDockingSystem/include/ads/API.h @@ -26,13 +26,16 @@ ADS_NAMESPACE_BEGIN enum DropArea { - TopDropArea, - RightDropArea, - BottomDropArea, - LeftDropArea, - CenterDropArea, - InvalidDropArea + InvalidDropArea = 0, + TopDropArea = 1, + RightDropArea = 2, + BottomDropArea = 4, + LeftDropArea = 8, + CenterDropArea = 16, + + AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea }; +Q_DECLARE_FLAGS(DropAreas, DropArea) class InternalContentData { @@ -50,4 +53,4 @@ QSplitter* findParentSplitter(class QWidget* w); QSplitter* findImmediateSplitter(class QWidget* w); ADS_NAMESPACE_END -#endif \ No newline at end of file +#endif diff --git a/AdvancedDockingSystem/include/ads/DropOverlay.h b/AdvancedDockingSystem/include/ads/DropOverlay.h index 8e11687..e885b53 100644 --- a/AdvancedDockingSystem/include/ads/DropOverlay.h +++ b/AdvancedDockingSystem/include/ads/DropOverlay.h @@ -15,8 +15,9 @@ class DropOverlay : public QFrame Q_OBJECT public: - DropOverlay(QWidget* parent); + DropOverlay(DropAreas areas, QWidget* parent); virtual ~DropOverlay(); + void setFullAreaDropEnabled(bool enabled) { _fullAreaDrop = enabled; } DropArea cursorLocation() const; protected: @@ -26,6 +27,7 @@ protected: private: class DropSplitAreas* _splitAreas; + bool _fullAreaDrop; }; // AbstractDropAreas is used as base for drop area indicator widgets. @@ -42,7 +44,7 @@ class DropSplitAreas : public AbstractDropAreas Q_OBJECT public: - DropSplitAreas(QWidget* parent); + DropSplitAreas(DropAreas areas, QWidget* parent); virtual DropArea cursorLocation() const; private: @@ -54,8 +56,8 @@ private: }; -DropArea showDropOverlay(QWidget* parent); -void showDropOverlay(QWidget* parent, const QRect& areaRect); +DropArea showDropOverlay(QWidget* parent, DropAreas areas = DropArea::AllAreas); +void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas = DropArea::AllAreas); void hideDropOverlay(); ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index af87ddd..2a74f59 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -100,6 +100,8 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget case LeftDropArea: dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, false); break; + default: + return; } return; } @@ -190,6 +192,8 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget targetSection->addContent(data, true); break; } + default: + break; } } @@ -322,4 +326,4 @@ QMenu* ContainerWidget::createContextMenu() const return m; } -ADS_NAMESPACE_END \ No newline at end of file +ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/DropOverlay.cpp b/AdvancedDockingSystem/src/DropOverlay.cpp index f2d21cb..851bfbf 100644 --- a/AdvancedDockingSystem/src/DropOverlay.cpp +++ b/AdvancedDockingSystem/src/DropOverlay.cpp @@ -25,9 +25,10 @@ static QWidget* createDropWidget(const QString& img) /////////////////////////////////////////////////////////////////////// -DropOverlay::DropOverlay(QWidget *parent) : +DropOverlay::DropOverlay(DropAreas areas, QWidget *parent) : QFrame(parent), - _splitAreas(NULL) + _splitAreas(NULL), + _fullAreaDrop(false) { //setAttribute(Qt::WA_TransparentForMouseEvents); setWindowFlags(windowFlags() | Qt::Tool); @@ -39,7 +40,7 @@ DropOverlay::DropOverlay(QWidget *parent) : l->setSpacing(0); setLayout(l); - _splitAreas = new DropSplitAreas(parent); + _splitAreas = new DropSplitAreas(areas, parent); _splitAreas->move(pos()); _splitAreas->resize(size()); _splitAreas->setVisible(true); @@ -68,6 +69,16 @@ void DropOverlay::paintEvent(QPaintEvent*) { QPainter p(this); + // Always draw drop-rect over the entire rect() + if (_fullAreaDrop) + { + QRect r = rect(); + p.fillRect(r, QBrush(QColor(0, 100, 255), Qt::Dense4Pattern)); + p.setBrush(QBrush(QColor(0, 100, 255))); + p.drawRect(r); + return; + } + // Draw rect based on location QRect r = rect(); const DropArea da = cursorLocation(); @@ -128,27 +139,48 @@ void DropOverlay::moveEvent(QMoveEvent* e) /////////////////////////////////////////////////////////////////////// -DropSplitAreas::DropSplitAreas(QWidget* parent) : AbstractDropAreas(parent) +DropSplitAreas::DropSplitAreas(DropAreas areas, QWidget* parent) : + AbstractDropAreas(parent), + _top(0), + _right(0), + _bottom(0), + _left(0), + _center(0) { //setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::Tool); setWindowFlags(windowFlags() | Qt::FramelessWindowHint); - _top = createDropWidget(":/img/split-top.png"); - _right = createDropWidget(":/img/split-right.png"); - _bottom = createDropWidget(":/img/split-bottom.png"); - _left = createDropWidget(":/img/split-left.png"); - _center = createDropWidget(":/img/dock-center.png"); - QGridLayout* grid = new QGridLayout(); grid->setContentsMargins(0, 0, 0, 0); grid->setSpacing(6); - grid->addWidget(_top, 0, 1, Qt::AlignHCenter | Qt::AlignBottom); - grid->addWidget(_right, 1, 2, Qt::AlignLeft | Qt::AlignVCenter); - grid->addWidget(_bottom, 2, 1, Qt::AlignHCenter | Qt::AlignTop); - grid->addWidget(_left, 1, 0, Qt::AlignRight | Qt::AlignVCenter); - grid->addWidget(_center, 1, 1, Qt::AlignCenter); + + if (areas.testFlag(DropArea::TopDropArea)) + { + _top = createDropWidget(":/img/split-top.png"); + grid->addWidget(_top, 0, 1, Qt::AlignHCenter | Qt::AlignBottom); + } + if (areas.testFlag(DropArea::RightDropArea)) + { + _right = createDropWidget(":/img/split-right.png"); + grid->addWidget(_right, 1, 2, Qt::AlignLeft | Qt::AlignVCenter); + } + if (areas.testFlag(DropArea::BottomDropArea)) + { + _bottom = createDropWidget(":/img/split-bottom.png"); + grid->addWidget(_bottom, 2, 1, Qt::AlignHCenter | Qt::AlignTop); + } + if (areas.testFlag(DropArea::LeftDropArea)) + { + _left = createDropWidget(":/img/split-left.png"); + grid->addWidget(_left, 1, 0, Qt::AlignRight | Qt::AlignVCenter); + } + if (areas.testFlag(DropArea::CenterDropArea)) + { + _center = createDropWidget(":/img/dock-center.png"); + grid->addWidget(_center, 1, 1, Qt::AlignCenter); + } QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom); bl1->setContentsMargins(0, 0, 0, 0); @@ -171,23 +203,23 @@ DropArea DropSplitAreas::cursorLocation() const { auto loc = InvalidDropArea; auto pos = mapFromGlobal(QCursor::pos()); - if (_top->geometry().contains(pos)) + if (_top && _top->geometry().contains(pos)) { loc = TopDropArea; } - else if (_right->geometry().contains(pos)) + else if (_right && _right->geometry().contains(pos)) { loc = RightDropArea; } - else if (_bottom->geometry().contains(pos)) + else if (_bottom && _bottom->geometry().contains(pos)) { loc = BottomDropArea; } - else if (_left->geometry().contains(pos)) + else if (_left && _left->geometry().contains(pos)) { loc = LeftDropArea; } - else if (_center->geometry().contains(pos)) + else if (_center && _center->geometry().contains(pos)) { loc = CenterDropArea; } @@ -201,7 +233,7 @@ static QPointer MyOverlayParent; static QRect MyOverlayParentRect; static DropArea MyOverlayLastLocation = InvalidDropArea; -DropArea showDropOverlay(QWidget* parent) +DropArea showDropOverlay(QWidget* parent, DropAreas areas) { if (MyOverlay) { @@ -220,7 +252,7 @@ DropArea showDropOverlay(QWidget* parent) } // Create new overlay and move it directly over the "parent" widget. - MyOverlay = new DropOverlay(parent); + MyOverlay = new DropOverlay(areas, parent); MyOverlay->resize(parent->size()); MyOverlay->move(parent->mapToGlobal(parent->rect().topLeft())); MyOverlay->show(); @@ -228,7 +260,7 @@ DropArea showDropOverlay(QWidget* parent) return MyOverlay->cursorLocation(); } -void showDropOverlay(QWidget* parent, const QRect& areaRect) +void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas) { if (MyOverlay) { @@ -240,7 +272,8 @@ void showDropOverlay(QWidget* parent, const QRect& areaRect) } // Create overlay and move it to the parent's areaRect - MyOverlay = new DropOverlay(parent); + MyOverlay = new DropOverlay(areas, parent); + MyOverlay->setFullAreaDropEnabled(true); MyOverlay->resize(areaRect.size()); MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y()))); MyOverlay->show(); @@ -261,4 +294,4 @@ void hideDropOverlay() } } -ADS_NAMESPACE_END \ No newline at end of file +ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/FloatingWidget.cpp b/AdvancedDockingSystem/src/FloatingWidget.cpp index 541f826..a62c276 100644 --- a/AdvancedDockingSystem/src/FloatingWidget.cpp +++ b/AdvancedDockingSystem/src/FloatingWidget.cpp @@ -40,6 +40,7 @@ FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPt auto closeButton = new QPushButton(); closeButton->setObjectName("closeButton"); + closeButton->setFlat(true); closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); closeButton->setToolTip(tr("Close")); closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -79,4 +80,4 @@ void FloatingWidget::closeEvent(QCloseEvent*) { } -ADS_NAMESPACE_END \ No newline at end of file +ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/SectionTitleWidget.cpp b/AdvancedDockingSystem/src/SectionTitleWidget.cpp index 1c97035..9975d5e 100644 --- a/AdvancedDockingSystem/src/SectionTitleWidget.cpp +++ b/AdvancedDockingSystem/src/SectionTitleWidget.cpp @@ -186,19 +186,19 @@ void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev) // Top, Right, Bottom, Left else if (cw->outerTopDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) { - showDropOverlay(cw, cw->outerTopDropRect()); + showDropOverlay(cw, cw->outerTopDropRect(), DropArea::TopDropArea); } else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) { - showDropOverlay(cw, cw->outerRightDropRect()); + showDropOverlay(cw, cw->outerRightDropRect(), DropArea::RightDropArea); } else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) { - showDropOverlay(cw, cw->outerBottomDropRect()); + showDropOverlay(cw, cw->outerBottomDropRect(), DropArea::BottomDropArea); } else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) { - showDropOverlay(cw, cw->outerLeftDropRect()); + showDropOverlay(cw, cw->outerLeftDropRect(), DropArea::LeftDropArea); } else { @@ -263,4 +263,4 @@ void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev) QFrame::mouseMoveEvent(ev); } -ADS_NAMESPACE_END \ No newline at end of file +ADS_NAMESPACE_END