diff --git a/AdvancedDockingSystem/include/ads/API.h b/AdvancedDockingSystem/include/ads/API.h index 8a89a9d..71d7a6c 100644 --- a/AdvancedDockingSystem/include/ads/API.h +++ b/AdvancedDockingSystem/include/ads/API.h @@ -60,12 +60,8 @@ enum DropArea LeftDropArea = 8, CenterDropArea = 16, - TopBorderDropArea = 32, - RightBorderDropArea = 64, - BottomBorderDropArea = 128, - LeftBorderDropArea = 256, - - AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea + OuterAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea, + AllAreas = OuterAreas | CenterDropArea }; Q_DECLARE_FLAGS(DropAreas, DropArea) diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget.h b/AdvancedDockingSystem/include/ads/ContainerWidget.h index c73e124..b39da43 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget.h @@ -141,11 +141,15 @@ private: void moveFloatingWidget(const QPoint& TargetPos); FloatingWidget* startFloating(SectionWidget* sectionwidget, int ContentUid, const QPoint& TargetPos); + void hideContainerOverlay(); + SectionWidget* insertNewSectionWidget(const InternalContentData& data, + SectionWidget* targetSection, SectionWidget* ret, Qt::Orientation Orientation, int InsertIndexOffset); private slots: void onActiveTabChanged(); void onActionToggleSectionContentVisibility(bool visible); + signals: void orientationChanged(); diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget_p.h b/AdvancedDockingSystem/include/ads/ContainerWidget_p.h index 21b0eeb..e218424 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget_p.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget_p.h @@ -27,6 +27,9 @@ class FloatingWidget; class HiddenSectionItem; +/** + * Container widget private data + */ struct ContainerWidgetPrivate { // Elements inside container. @@ -42,15 +45,16 @@ struct ContainerWidgetPrivate // Layout stuff - QGridLayout* mainLayout = nullptr; + QGridLayout* MainLayout = nullptr; Qt::Orientation orientation = Qt::Horizontal; QPointer splitter; // $mfreiholz: I'd like to remove this variable entirely, // because it changes during user interaction anyway. // Drop overlay stuff. - QPointer dropOverlay; - QWidget* LeftBorderDropArea; -}; + QPointer SectionDropOverlay; + QPointer ContainerDropOverlay; + //QWidget* LeftBorderDropArea; +}; // struct ContainerWidgetPrivate } // namespace ads //--------------------------------------------------------------------------- diff --git a/AdvancedDockingSystem/include/ads/DropOverlay.h b/AdvancedDockingSystem/include/ads/DropOverlay.h index 3240231..22d2f96 100644 --- a/AdvancedDockingSystem/include/ads/DropOverlay.h +++ b/AdvancedDockingSystem/include/ads/DropOverlay.h @@ -22,7 +22,13 @@ class ADS_EXPORT_API DropOverlay : public QFrame friend class DropOverlayCross; public: - DropOverlay(QWidget* parent); + enum eMode + { + ModeSectionOverlay, + ModeContainerOverlay + }; + + DropOverlay(QWidget* parent, eMode Mode = ModeSectionOverlay); virtual ~DropOverlay(); void setAllowedAreas(DropAreas areas); @@ -67,19 +73,22 @@ public: DropOverlayCross(DropOverlay* overlay); virtual ~DropOverlayCross(); - void setAreaWidgets(const QHash& widgets); DropArea cursorLocation() const; + void setupOverlayCross(DropOverlay::eMode Mode); protected: virtual void showEvent(QShowEvent* e); + void setAreaWidgets(const QHash& widgets); private: void reset(); + QPoint areaGridPosition(const DropArea area); private: - DropOverlay* _overlay; - QHash _widgets; - QGridLayout* _grid; + DropOverlay::eMode m_Mode = DropOverlay::ModeSectionOverlay; + DropOverlay* m_DropOverlay; + QHash m_DropIndicatorWidgets; + QGridLayout* m_GridLayout; }; ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index 30aaa5b..7ec6436 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -41,22 +41,22 @@ ContainerWidget::ContainerWidget(QWidget *parent) : QFrame(parent), d(new ContainerWidgetPrivate()) { - d->LeftBorderDropArea = DropOverlay::createDropIndicatorWidget(LeftBorderDropArea); - d->LeftBorderDropArea->setVisible(false); - d->LeftBorderDropArea->setWindowTitle("LeftBorderDropArea"); + d->SectionDropOverlay = new DropOverlay(this, DropOverlay::ModeSectionOverlay); + d->ContainerDropOverlay = new DropOverlay(this, DropOverlay::ModeContainerOverlay); + d->ContainerDropOverlay->setAttribute(Qt::WA_TransparentForMouseEvents); + d->ContainerDropOverlay->setWindowFlags(d->ContainerDropOverlay->windowFlags() | Qt::WindowTransparentForInput); - d->dropOverlay = new DropOverlay(this); - d->mainLayout = new QGridLayout(); - d->mainLayout->setContentsMargins(4, 4, 4, 4); - d->mainLayout->setSpacing(0); - setLayout(d->mainLayout); + d->MainLayout = new QGridLayout(); + d->MainLayout->setContentsMargins(0, 1, 0, 0); + d->MainLayout->setSpacing(0); + setLayout(d->MainLayout); } ContainerWidget::~ContainerWidget() { // Note: It's required to delete in 2 steps // Remove from list, and then delete. - // Because the destrcutor of objects wants to modfiy the current + // Because the destrcutor of objects wants to modify the current // iterating list as well... :-/ while (!d->sections.isEmpty()) { @@ -430,7 +430,7 @@ QList ContainerWidget::contents() const QPointer ContainerWidget::dropOverlay() const { - return d->dropOverlay; + return d->SectionDropOverlay; } /////////////////////////////////////////////////////////////////////// @@ -444,14 +444,38 @@ SectionWidget* ContainerWidget::newSectionWidget() return sw; } +SectionWidget* ContainerWidget::insertNewSectionWidget( + const InternalContentData& data, SectionWidget* targetSection, SectionWidget* ret, + Qt::Orientation Orientation, int InsertIndexOffset) +{ + QSplitter* targetSectionSplitter = findParentSplitter(targetSection); + SectionWidget* sw = newSectionWidget(); + sw->addContent(data, true); + if (targetSectionSplitter->orientation() == Orientation) + { + const int index = targetSectionSplitter->indexOf(targetSection); + targetSectionSplitter->insertWidget(index + InsertIndexOffset, sw); + } + else + { + const int index = targetSectionSplitter->indexOf(targetSection); + QSplitter* s = newSplitter(Orientation); + s->addWidget(sw); + s->addWidget(targetSection); + targetSectionSplitter->insertWidget(index, s); + } + ret = sw; + return ret; +} + SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, SectionWidget* targetSection, DropArea area, bool autoActive) { ADS_Expects(targetSection != NULL); - SectionWidget* ret = NULL; + SectionWidget* section_widget = nullptr; // If no sections exists yet, create a default one and always drop into it. - if (d->sections.count() <= 0) + if (d->sections.isEmpty()) { targetSection = newSectionWidget(); addSection(targetSection); @@ -463,120 +487,32 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec { switch (area) { - case TopDropArea: - ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, false); - break; - case RightDropArea: - ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, true); - break; + case TopDropArea:return dropContentOuterHelper(d->MainLayout, data, Qt::Vertical, false); + case RightDropArea: return dropContentOuterHelper(d->MainLayout, data, Qt::Horizontal, true); case CenterDropArea: - case BottomDropArea: - ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, true); - break; - case LeftDropArea: - ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, false); - break; + case BottomDropArea:return dropContentOuterHelper(d->MainLayout, data, Qt::Vertical, true); + case LeftDropArea: return dropContentOuterHelper(d->MainLayout, data, Qt::Horizontal, false); default: - return NULL; + return nullptr; } - return ret; + return section_widget; } - QSplitter* targetSectionSplitter = findParentSplitter(targetSection); - // Drop logic based on area. switch (area) { - case TopDropArea: - { - SectionWidget* sw = newSectionWidget(); - sw->addContent(data, true); - if (targetSectionSplitter->orientation() == Qt::Vertical) - { - const int index = targetSectionSplitter->indexOf(targetSection); - targetSectionSplitter->insertWidget(index, sw); - } - else - { - const int index = targetSectionSplitter->indexOf(targetSection); - QSplitter* s = newSplitter(Qt::Vertical); - s->addWidget(sw); - s->addWidget(targetSection); - targetSectionSplitter->insertWidget(index, s); - } - ret = sw; - break; - } - case RightDropArea: - { - SectionWidget* sw = newSectionWidget(); - sw->addContent(data, true); - if (targetSectionSplitter->orientation() == Qt::Horizontal) - { - const int index = targetSectionSplitter->indexOf(targetSection); - targetSectionSplitter->insertWidget(index + 1, sw); - } - else - { - const int index = targetSectionSplitter->indexOf(targetSection); - QSplitter* s = newSplitter(Qt::Horizontal); - s->addWidget(targetSection); - s->addWidget(sw); - targetSectionSplitter->insertWidget(index, s); - } - ret = sw; - break; - } - case BottomDropArea: - { - SectionWidget* sw = newSectionWidget(); - sw->addContent(data, true); - if (targetSectionSplitter->orientation() == Qt::Vertical) - { - int index = targetSectionSplitter->indexOf(targetSection); - targetSectionSplitter->insertWidget(index + 1, sw); - } - else - { - int index = targetSectionSplitter->indexOf(targetSection); - QSplitter* s = newSplitter(Qt::Vertical); - s->addWidget(targetSection); - s->addWidget(sw); - targetSectionSplitter->insertWidget(index, s); - } - ret = sw; - break; - } - case LeftDropArea: - { - SectionWidget* sw = newSectionWidget(); - sw->addContent(data, true); - if (targetSectionSplitter->orientation() == Qt::Horizontal) - { - int index = targetSectionSplitter->indexOf(targetSection); - targetSectionSplitter->insertWidget(index, sw); - } - else - { - QSplitter* s = newSplitter(Qt::Horizontal); - s->addWidget(sw); - int index = targetSectionSplitter->indexOf(targetSection); - targetSectionSplitter->insertWidget(index, s); - s->addWidget(targetSection); - } - ret = sw; - break; - } + case TopDropArea:return insertNewSectionWidget(data, targetSection, section_widget, Qt::Vertical, 0); + case RightDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Horizontal, 1); + case BottomDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Vertical, 1); + case LeftDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Horizontal, 0); case CenterDropArea: - { - targetSection->addContent(data, autoActive); - ret = targetSection; - break; - } + targetSection->addContent(data, autoActive); + return targetSection; + default: break; } - return ret; + return section_widget; } void ContainerWidget::addSection(SectionWidget* section) @@ -587,7 +523,7 @@ void ContainerWidget::addSection(SectionWidget* section) if (!d->splitter) { d->splitter = newSplitter(d->orientation); - d->mainLayout->addWidget(d->splitter, 0, 0); + d->MainLayout->addWidget(d->splitter, 0, 0); } if (d->splitter->indexOf(section) != -1) { @@ -712,7 +648,7 @@ QByteArray ContainerWidget::saveHierarchy() const saveFloatingWidgets(out); // Save state of sections and contents - if (d->mainLayout->count() <= 0 || d->sections.isEmpty()) + if (d->MainLayout->count() <= 0 || d->sections.isEmpty()) { // Looks like the user has hidden all contents and no more sections // are available. We can simply write a list of all hidden contents. @@ -726,12 +662,12 @@ QByteArray ContainerWidget::saveHierarchy() const out << iter.value().data.content->uniqueName(); } } - else if (d->mainLayout->count() == 1) + else if (d->MainLayout->count() == 1) { out << 1; // Mode // There should only be one! - QLayoutItem* li = d->mainLayout->itemAt(0); + QLayoutItem* li = d->MainLayout->itemAt(0); if (!li->widget()) qFatal("Not a widget in d->mainLayout, this shouldn't happen."); @@ -1023,8 +959,8 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data) d->sections = sections; // Delete old objects - QLayoutItem* old = d->mainLayout->takeAt(0); - d->mainLayout->addWidget(d->splitter); + QLayoutItem* old = d->MainLayout->takeAt(0); + d->MainLayout->addWidget(d->splitter); delete old; qDeleteAll(oldFloatings); qDeleteAll(oldSections); @@ -1236,19 +1172,26 @@ void ContainerWidget::onActionToggleSectionContentVisibility(bool visible) } +void ContainerWidget::hideContainerOverlay() +{ + d->ContainerDropOverlay->hideDropOverlay(); +} + + void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos) { + std::cout << "moveFloatingWidget" << std::endl; // Mouse is over the container widget if (rect().contains(mapFromGlobal(QCursor::pos()))) { std::cout << "over Container" << std::endl; - d->LeftBorderDropArea->show(); - d->LeftBorderDropArea->raise(); + d->ContainerDropOverlay->showDropOverlay(this); + d->ContainerDropOverlay->raise(); } else { std::cout << "-----------------" << std::endl; - d->LeftBorderDropArea->hide(); + d->ContainerDropOverlay->hideDropOverlay(); } // Mouse is over a SectionWidget @@ -1256,12 +1199,12 @@ void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos) if (sectionwidget) { qInfo() << "over sectionWidget"; - d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas); - d->dropOverlay->showDropOverlay(sectionwidget); + d->SectionDropOverlay->setAllowedAreas(ADS_NS::AllAreas); + d->SectionDropOverlay->showDropOverlay(sectionwidget); } else { - d->dropOverlay->hideDropOverlay(); + d->SectionDropOverlay->hideDropOverlay(); } } @@ -1290,9 +1233,9 @@ FloatingWidget* ContainerWidget::startFloating(SectionWidget* sectionwidget, int } deleteEmptySplitter(this); - QRect Rect = rect(); - QPoint Pos(Rect.left(), Rect.center().y()); - d->LeftBorderDropArea->move(mapToGlobal(Pos)); + d->ContainerDropOverlay->setAllowedAreas(OuterAreas); + d->ContainerDropOverlay->showDropOverlay(this); + d->ContainerDropOverlay->raise(); return fw; } diff --git a/AdvancedDockingSystem/src/DropOverlay.cpp b/AdvancedDockingSystem/src/DropOverlay.cpp index 48dc19f..308f38a 100644 --- a/AdvancedDockingSystem/src/DropOverlay.cpp +++ b/AdvancedDockingSystem/src/DropOverlay.cpp @@ -35,72 +35,61 @@ static QPixmap createDropIndicatorPixmap(const QPalette& pal, const QSizeF& size p.fillRect(baseRect, backgroundColor); // Drop area rect. - if (true) + p.save(); + QRectF areaRect; + QLineF areaLine; + QLinearGradient gradient; + switch (dropArea) { - p.save(); - QRectF areaRect; - QLineF areaLine; - QLinearGradient gradient; - switch (dropArea) - { - case TopDropArea: - case TopBorderDropArea: - areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f); - areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight()); - gradient.setStart(areaRect.topLeft()); - gradient.setFinalStop(areaRect.bottomLeft()); - break; - case RightDropArea: - case RightBorderDropArea: - areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height()); - areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft()); - gradient.setStart(areaRect.topLeft()); - gradient.setFinalStop(areaRect.topRight()); - break; - case BottomDropArea: - case BottomBorderDropArea: - areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f); - areaLine = QLineF(areaRect.topLeft(), areaRect.topRight()); - gradient.setStart(areaRect.topLeft()); - gradient.setFinalStop(areaRect.bottomLeft()); - break; - case LeftDropArea: - case LeftBorderDropArea: - areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height()); - areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight()); - gradient.setStart(areaRect.topLeft()); - gradient.setFinalStop(areaRect.topRight()); - break; - default: - break; - } - if (areaRect.isValid()) - { - gradient.setColorAt(0.f, areaBackgroundColor); - gradient.setColorAt(1.f, areaBackgroundColor.lighter(120)); - p.fillRect(areaRect, gradient); - - pen = p.pen(); - pen.setColor(borderColor); - pen.setStyle(Qt::DashLine); - p.setPen(pen); - p.drawLine(areaLine); - } - p.restore(); + case TopDropArea: + areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f); + areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight()); + gradient.setStart(areaRect.topLeft()); + gradient.setFinalStop(areaRect.bottomLeft()); + break; + case RightDropArea: + areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height()); + areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft()); + gradient.setStart(areaRect.topLeft()); + gradient.setFinalStop(areaRect.topRight()); + break; + case BottomDropArea: + areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f); + areaLine = QLineF(areaRect.topLeft(), areaRect.topRight()); + gradient.setStart(areaRect.topLeft()); + gradient.setFinalStop(areaRect.bottomLeft()); + break; + case LeftDropArea: + areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height()); + areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight()); + gradient.setStart(areaRect.topLeft()); + gradient.setFinalStop(areaRect.topRight()); + break; + default: + break; } - - // Border - if (true) + if (areaRect.isValid()) { - p.save(); + gradient.setColorAt(0.f, areaBackgroundColor); + gradient.setColorAt(1.f, areaBackgroundColor.lighter(120)); + p.fillRect(areaRect, gradient); + pen = p.pen(); pen.setColor(borderColor); - pen.setWidth(1); - + pen.setStyle(Qt::DashLine); p.setPen(pen); - p.drawRect(baseRect.adjusted(0, 0, -pen.width(), -pen.width())); - p.restore(); + p.drawLine(areaLine); } + p.restore(); + + p.save(); + pen = p.pen(); + pen.setColor(borderColor); + pen.setWidth(1); + + p.setPen(pen); + p.drawRect(baseRect.adjusted(0, 0, -pen.width(), -pen.width())); + p.restore(); return pm; } @@ -120,7 +109,7 @@ QWidget* DropOverlay::createDropIndicatorWidget(DropArea dropArea) /////////////////////////////////////////////////////////////////////// -DropOverlay::DropOverlay(QWidget* parent) : +DropOverlay::DropOverlay(QWidget* parent, eMode Mode) : QFrame(parent), _allowedAreas(InvalidDropArea), _cross(new DropOverlayCross(this)), @@ -129,21 +118,14 @@ DropOverlay::DropOverlay(QWidget* parent) : setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); setWindowOpacity(0.2); setWindowTitle("DropOverlay"); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_TranslucentBackground); QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom); - l->setContentsMargins(0, 0, 0, 0); l->setSpacing(0); setLayout(l); - // Cross with default drop area widgets. - QHash areaWidgets; - areaWidgets.insert(ADS_NS::TopDropArea, createDropIndicatorWidget(TopDropArea)); //createDropWidget(":/img/split-top.png")); - areaWidgets.insert(ADS_NS::RightDropArea, createDropIndicatorWidget(RightDropArea));//createDropWidget(":/img/split-right.png")); - areaWidgets.insert(ADS_NS::BottomDropArea, createDropIndicatorWidget(BottomDropArea));//createDropWidget(":/img/split-bottom.png")); - areaWidgets.insert(ADS_NS::LeftDropArea, createDropIndicatorWidget(LeftDropArea));//createDropWidget(":/img/split-left.png")); - areaWidgets.insert(ADS_NS::CenterDropArea, createDropIndicatorWidget(CenterDropArea));//createDropWidget(":/img/dock-center.png")); - - _cross->setAreaWidgets(areaWidgets); + _cross->setupOverlayCross(Mode); _cross->setVisible(false); setVisible(false); } @@ -291,84 +273,136 @@ void DropOverlay::moveEvent(QMoveEvent* e) _cross->move(e->pos()); } -/////////////////////////////////////////////////////////////////////// - -static QPair gridPosForArea(const DropArea area) +static int areaAlignment(const DropArea area) { switch (area) { - case ADS_NS::TopDropArea: - return qMakePair(QPoint(0, 1), (int) Qt::AlignHCenter | Qt::AlignBottom); - case ADS_NS::RightDropArea: - return qMakePair(QPoint(1, 2), (int) Qt::AlignLeft | Qt::AlignVCenter); - case ADS_NS::BottomDropArea: - return qMakePair(QPoint(2, 1), (int) Qt::AlignHCenter | Qt::AlignTop); - case ADS_NS::LeftDropArea: - return qMakePair(QPoint(1, 0), (int) Qt::AlignRight | Qt::AlignVCenter); - case ADS_NS::CenterDropArea: - return qMakePair(QPoint(1, 1), (int) Qt::AlignCenter); - default: - return QPair(); + case ADS_NS::TopDropArea: return (int) Qt::AlignHCenter | Qt::AlignBottom; + case ADS_NS::RightDropArea: return (int) Qt::AlignLeft | Qt::AlignVCenter; + case ADS_NS::BottomDropArea: return (int) Qt::AlignHCenter | Qt::AlignTop; + case ADS_NS::LeftDropArea: return (int) Qt::AlignRight | Qt::AlignVCenter; + case ADS_NS::CenterDropArea: return (int) Qt::AlignCenter; + default: return Qt::AlignCenter; } } + +QPoint DropOverlayCross::areaGridPosition(const DropArea area) +{ + if (DropOverlay::ModeSectionOverlay == m_Mode) + { + switch (area) + { + case ADS_NS::TopDropArea: return QPoint(1, 2); + case ADS_NS::RightDropArea: return QPoint(2, 3); + case ADS_NS::BottomDropArea: return QPoint(3, 2); + case ADS_NS::LeftDropArea: return QPoint(2, 1); + case ADS_NS::CenterDropArea: return QPoint(2, 2); + default: return QPoint(); + } + } + else + { + switch (area) + { + case ADS_NS::TopDropArea: return QPoint(0, 2); + case ADS_NS::RightDropArea: return QPoint(2, 4); + case ADS_NS::BottomDropArea: return QPoint(4, 2); + case ADS_NS::LeftDropArea: return QPoint(2, 0); + case ADS_NS::CenterDropArea: return QPoint(2, 2); + default: return QPoint(); + } + } +} + + DropOverlayCross::DropOverlayCross(DropOverlay* overlay) : QWidget(overlay->parentWidget()), - _overlay(overlay), - _widgets() + m_DropOverlay(overlay) { setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); setWindowTitle("DropOverlayCross"); setAttribute(Qt::WA_TranslucentBackground); - _grid = new QGridLayout(); - _grid->setContentsMargins(0, 0, 0, 0); - _grid->setSpacing(6); - - QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom); - bl1->setContentsMargins(0, 0, 0, 0); - bl1->setSpacing(0); - setLayout(bl1); - - QBoxLayout* bl2 = new QBoxLayout(QBoxLayout::LeftToRight); - bl2->setContentsMargins(0, 0, 0, 0); - bl2->setSpacing(0); - - bl1->addStretch(1); - bl1->addLayout(bl2); - bl2->addStretch(1); - bl2->addLayout(_grid, 0); - bl2->addStretch(1); - bl1->addStretch(1); + m_GridLayout = new QGridLayout(); + m_GridLayout->setSpacing(6); + setLayout(m_GridLayout); } DropOverlayCross::~DropOverlayCross() { } + +void DropOverlayCross::setupOverlayCross(DropOverlay::eMode Mode) +{ + m_Mode = Mode; + + QHash areaWidgets; + areaWidgets.insert(TopDropArea, DropOverlay::createDropIndicatorWidget(TopDropArea)); + areaWidgets.insert(RightDropArea, DropOverlay::createDropIndicatorWidget(RightDropArea)); + areaWidgets.insert(BottomDropArea, DropOverlay::createDropIndicatorWidget(BottomDropArea)); + areaWidgets.insert(LeftDropArea, DropOverlay::createDropIndicatorWidget(LeftDropArea)); + areaWidgets.insert(CenterDropArea, DropOverlay::createDropIndicatorWidget(CenterDropArea)); + + setAreaWidgets(areaWidgets); +} + + void DropOverlayCross::setAreaWidgets(const QHash& widgets) { // Delete old widgets. - QMutableHashIterator i(_widgets); + QMutableHashIterator i(m_DropIndicatorWidgets); while (i.hasNext()) { i.next(); QWidget* widget = i.value(); - _grid->removeWidget(widget); + m_GridLayout->removeWidget(widget); delete widget; i.remove(); } // Insert new widgets into grid. - _widgets = widgets; - QHashIterator i2(_widgets); + m_DropIndicatorWidgets = widgets; + QHashIterator i2(m_DropIndicatorWidgets); while (i2.hasNext()) { i2.next(); const DropArea area = i2.key(); QWidget* widget = i2.value(); - const QPair opts = gridPosForArea(area); - _grid->addWidget(widget, opts.first.x(), opts.first.y(), (Qt::Alignment) opts.second); + QPoint p = areaGridPosition(area); + m_GridLayout->addWidget(widget, p.x(), p.y(), (Qt::Alignment) areaAlignment(area)); + } + + if (DropOverlay::ModeSectionOverlay == m_Mode) + { + m_GridLayout->setContentsMargins(0, 0, 0, 0); + m_GridLayout->setRowStretch(0, 1); + m_GridLayout->setRowStretch(1, 0); + m_GridLayout->setRowStretch(2, 0); + m_GridLayout->setRowStretch(3, 0); + m_GridLayout->setRowStretch(4, 1); + + m_GridLayout->setColumnStretch(0, 1); + m_GridLayout->setColumnStretch(1, 0); + m_GridLayout->setColumnStretch(2, 0); + m_GridLayout->setColumnStretch(3, 0); + m_GridLayout->setColumnStretch(4, 1); + } + else + { + m_GridLayout->setContentsMargins(4, 4, 4, 4); + m_GridLayout->setRowStretch(0, 0); + m_GridLayout->setRowStretch(1, 1); + m_GridLayout->setRowStretch(2, 1); + m_GridLayout->setRowStretch(3, 1); + m_GridLayout->setRowStretch(4, 0); + + m_GridLayout->setColumnStretch(0, 0); + m_GridLayout->setColumnStretch(1, 1); + m_GridLayout->setColumnStretch(2, 1); + m_GridLayout->setColumnStretch(3, 1); + m_GridLayout->setColumnStretch(4, 0); } reset(); } @@ -376,11 +410,11 @@ void DropOverlayCross::setAreaWidgets(const QHash& widgets) DropArea DropOverlayCross::cursorLocation() const { const QPoint pos = mapFromGlobal(QCursor::pos()); - QHashIterator i(_widgets); + QHashIterator i(m_DropIndicatorWidgets); while (i.hasNext()) { i.next(); - if (_overlay->allowedAreas().testFlag(i.key()) + if (m_DropOverlay->allowedAreas().testFlag(i.key()) && i.value() && i.value()->isVisible() && i.value()->geometry().contains(pos)) @@ -393,24 +427,24 @@ DropArea DropOverlayCross::cursorLocation() const void DropOverlayCross::showEvent(QShowEvent*) { - resize(_overlay->size()); - move(_overlay->pos()); + resize(m_DropOverlay->size()); + move(m_DropOverlay->pos()); } void DropOverlayCross::reset() { QList allAreas; - allAreas << ADS_NS::TopDropArea << ADS_NS::RightDropArea << ADS_NS::BottomDropArea << ADS_NS::LeftDropArea << ADS_NS::CenterDropArea; - const DropAreas allowedAreas = _overlay->allowedAreas(); + allAreas << ADS_NS::TopDropArea << ADS_NS::RightDropArea + << ADS_NS::BottomDropArea << ADS_NS::LeftDropArea << ADS_NS::CenterDropArea; + const DropAreas allowedAreas = m_DropOverlay->allowedAreas(); // Update visibility of area widgets based on allowedAreas. for (int i = 0; i < allAreas.count(); ++i) { - const QPair opts = gridPosForArea(allAreas.at(i)); - - QLayoutItem* item = _grid->itemAtPosition(opts.first.x(), opts.first.y()); - QWidget* w = NULL; - if (item && (w = item->widget()) != NULL) + QPoint p = areaGridPosition(allAreas.at(i)); + QLayoutItem* item = m_GridLayout->itemAtPosition(p.x(), p.y()); + QWidget* w = nullptr; + if (item && (w = item->widget()) != nullptr) { w->setVisible(allowedAreas.testFlag(allAreas.at(i))); } diff --git a/AdvancedDockingSystem/src/SectionTitleWidget.cpp b/AdvancedDockingSystem/src/SectionTitleWidget.cpp index 3e1bae3..a1227aa 100644 --- a/AdvancedDockingSystem/src/SectionTitleWidget.cpp +++ b/AdvancedDockingSystem/src/SectionTitleWidget.cpp @@ -22,6 +22,8 @@ #include "ads/FloatingWidget.h" #include "ads/ContainerWidget.h" +#include + ADS_NAMESPACE_BEGIN SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) : @@ -77,14 +79,15 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev) SectionWidget* section = NULL; ContainerWidget* cw = findParentContainerWidget(this); - // Drop contents of FloatingWidget into SectionWidget. - if (m_FloatingWidget) + // Drop contents of FloatingWidget into container or section widget + if (m_FloatingWidget && cw->rect().contains(cw->mapFromGlobal(ev->globalPos()))) { SectionWidget* sw = cw->sectionAt(cw->mapFromGlobal(ev->globalPos())); + DropArea loc = InvalidDropArea; if (sw) { - cw->d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas); - DropArea loc = cw->d->dropOverlay->showDropOverlay(sw); + cw->d->SectionDropOverlay->setAllowedAreas(ADS_NS::AllAreas); + DropArea loc = cw->d->SectionDropOverlay->showDropOverlay(sw); if (loc != InvalidDropArea) { InternalContentData data; @@ -94,27 +97,20 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev) cw->dropContent(data, sw, loc, true); } } - // Mouse is over a outer-edge drop area - else - { - /*DropArea dropArea = ADS_NS::InvalidDropArea; - if (cw->outerTopDropRect().contains(cw->mapFromGlobal(ev->globalPos()))) - dropArea = ADS_NS::TopDropArea; - if (cw->outerRightDropRect().contains(cw->mapFromGlobal(ev->globalPos()))) - dropArea = ADS_NS::RightDropArea; - if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(ev->globalPos()))) - dropArea = ADS_NS::BottomDropArea; - if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(ev->globalPos()))) - dropArea = ADS_NS::LeftDropArea; - if (dropArea != ADS_NS::InvalidDropArea) + // mouse is over container + if (InvalidDropArea == loc) + { + DropArea loc = cw->d->ContainerDropOverlay->cursorLocation(); + std::cout << "Cursor location: " << loc << std::endl; + if (loc != InvalidDropArea) { InternalContentData data; m_FloatingWidget->takeContent(data); m_FloatingWidget->deleteLater(); m_FloatingWidget.clear(); - cw->dropContent(data, NULL, dropArea, true); - }*/ + cw->dropContent(data, nullptr, loc, true); + } } } // End of tab moving, change order now @@ -135,12 +131,15 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev) } if (!m_DragStartPosition.isNull()) + { emit clicked(); + } // Reset m_DragStartPosition = QPoint(); m_TabMoving = false; - cw->d->dropOverlay->hideDropOverlay(); + cw->d->SectionDropOverlay->hideDropOverlay(); + cw->hideContainerOverlay(); QFrame::mouseReleaseEvent(ev); }