diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index a86e82d..ff0ce6e 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -195,13 +195,11 @@ void DockAreaTitleBarPrivate::createButtons() AutoHideButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasAutoHideButton) && autoHideEnabled); AutoHideButton->setObjectName("dockAreaAutoHideButton"); AutoHideButton->setAutoRaise(true); - AutoHideButton->setCheckable(true); - AutoHideButton->setChecked(false); internal::setToolTip(AutoHideButton, QObject::tr("Toggle Auto Hide")); internal::setButtonIcon(AutoHideButton, QStyle::SP_DialogOkButton, ads::AutoHideIcon); AutoHideButton->setSizePolicy(ButtonSizePolicy); Layout->addWidget(AutoHideButton, 0); - _this->connect(AutoHideButton, SIGNAL(toggled(bool)), SLOT(onAutoHideButtonClicked(bool))); + _this->connect(AutoHideButton, SIGNAL(clicked()), SLOT(onAutoHideButtonClicked())); // Close button CloseButton = new CTitleBarButton(testConfigFlag(CDockManager::DockAreaHasCloseButton)); @@ -486,11 +484,12 @@ void CDockAreaTitleBar::onCurrentTabChanged(int Index) //============================================================================ -void CDockAreaTitleBar::onAutoHideButtonClicked(bool Checked) +void CDockAreaTitleBar::onAutoHideButtonClicked() { + qDebug() << "CDockAreaTitleBar::onAutoHideButtonClicked()"; if (d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable)) { - d->DockArea->toggleAutoHideArea(Checked); + d->DockArea->toggleAutoHideArea(!d->DockArea->isAutoHide()); } } diff --git a/src/DockAreaTitleBar.h b/src/DockAreaTitleBar.h index 0650ae8..5ccdc4a 100644 --- a/src/DockAreaTitleBar.h +++ b/src/DockAreaTitleBar.h @@ -61,7 +61,7 @@ private Q_SLOTS: void onUndockButtonClicked(); void onTabsMenuActionTriggered(QAction* Action); void onCurrentTabChanged(int Index); - void onAutoHideButtonClicked(bool Checked); + void onAutoHideButtonClicked(); protected: /** diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 9d7c537..70e481d 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -1521,62 +1521,103 @@ CAutoHideDockContainer* CDockContainerWidget::createAndInitializeAutoHideDockWid } +enum eBorderLocation +{ + BorderNone = 0, + BorderLeft = 0x01, + BorderRight = 0x02, + BorderTop = 0x04, + BorderBottom = 0x08, + BorderVertical = BorderLeft | BorderRight, + BorderHorizontal = BorderTop | BorderBottom, + BorderTopLeft = BorderTop | BorderLeft, + BorderTopRight = BorderTop | BorderRight, + BorderBottomLeft = BorderBottom | BorderLeft, + BorderBottomRight = BorderBottom | BorderRight, + BorderVerticalBottom = BorderVertical | BorderBottom, + BorderVerticalTop = BorderVertical | BorderTop, + BorderHorizontalLeft = BorderHorizontal | BorderLeft, + BorderHorizontalRight = BorderHorizontal | BorderRight, + BorderAll = BorderVertical | BorderHorizontal +}; + + //============================================================================ CDockWidgetSideTab::SideTabBarArea CDockContainerWidget::calculateSideTabBarArea(CDockAreaWidget* DockAreaWidget) { - // Handle bottom case and top case - // It's bottom if the width is wider than the height, and if it's below 50% of the window - const auto dockWidgetFrameGeometry = DockAreaWidget->frameGeometry(); - const auto splitterCenter = rootSplitter()->mapToGlobal(rootSplitter()->frameGeometry().center()); - if (dockWidgetFrameGeometry.width() > dockWidgetFrameGeometry.height()) + auto DockMgrRect = d->DockManager->contentRect(); + int borders = BorderNone; // contains all borders that are touched by the dock ware + auto DockAreaTopLeft = DockAreaWidget->mapTo(d->DockManager, DockAreaWidget->rect().topLeft()); + auto DockAreaRect = DockAreaWidget->rect(); + DockAreaRect.moveTo(DockAreaTopLeft); + const qreal aspectRatio = DockAreaRect.width() / (qMax(1, DockAreaRect.height()) * 1.0); + const qreal sizeRatio = (qreal)DockMgrRect.width() / DockAreaRect.width(); + static const int MinBorderDistance = 16; + bool HorizontalOrientation = (aspectRatio > 1.0) && (sizeRatio < 3.0); + + // measure border distances - a distance less than 16 px means we touch the + // border + int BorderDistance[4]; + int Distance = qAbs(DockMgrRect.topLeft().y() - DockAreaRect.topLeft().y()); + BorderDistance[CDockWidgetSideTab::Top] = (Distance < MinBorderDistance) ? 0 : Distance; + if (!BorderDistance[CDockWidgetSideTab::Top]) { - if (DockAreaWidget->mapToGlobal(dockWidgetFrameGeometry.topLeft()).y() > splitterCenter.y() && CDockManager::testConfigFlag(CDockManager::DockContainerHasBottomSideBar)) - { - return CDockWidgetSideTab::Bottom; - } - if (CDockManager::testConfigFlag(CDockManager::DockContainerHasTopSideBar)) - { - return CDockWidgetSideTab::Top; - } + borders |= BorderTop; + } + qDebug() << "BorderDistance[CDockWidgetSideTab::Top] " << BorderDistance[CDockWidgetSideTab::Top]; + Distance = qAbs(DockMgrRect.bottomRight().y() - DockAreaRect.bottomRight().y()); + BorderDistance[CDockWidgetSideTab::Bottom] = (Distance < MinBorderDistance) ? 0 : Distance; + if (!BorderDistance[CDockWidgetSideTab::Bottom]) + { + borders |= BorderBottom; + } + qDebug() << "BorderDistance[CDockWidgetSideTab::Bottom] " << BorderDistance[CDockWidgetSideTab::Bottom]; + Distance = qAbs(DockMgrRect.topLeft().x() - DockAreaRect.topLeft().x()); + BorderDistance[CDockWidgetSideTab::Left] = (Distance < MinBorderDistance) ? 0 : Distance; + if (!BorderDistance[CDockWidgetSideTab::Left]) + { + borders |= BorderLeft; + } + qDebug() << "BorderDistance[CDockWidgetSideTab::Left] " << BorderDistance[CDockWidgetSideTab::Left]; + Distance = qAbs(DockMgrRect.bottomRight().x() - DockAreaRect.bottomRight().x()); + BorderDistance[CDockWidgetSideTab::Right] = (Distance < MinBorderDistance) ? 0 : Distance; + if (!BorderDistance[CDockWidgetSideTab::Right]) + { + borders |= BorderRight; + } + qDebug() << "BorderDistance[CDockWidgetSideTab::Right] " << BorderDistance[CDockWidgetSideTab::Right]; + + auto SideTab = CDockWidgetSideTab::Right; + switch (borders) + { + // 1. It's touching all borders + case BorderAll: SideTab = HorizontalOrientation ? CDockWidgetSideTab::Bottom : CDockWidgetSideTab::Right; break; + + // 2. It's touching 3 borders + case BorderVerticalBottom : SideTab = CDockWidgetSideTab::Bottom; break; + case BorderVerticalTop : SideTab = CDockWidgetSideTab::Top; break; + case BorderHorizontalLeft: SideTab = CDockWidgetSideTab::Left; break; + case BorderHorizontalRight: SideTab = CDockWidgetSideTab::Right; break; + + // 3. Its touching horizontal or vertical borders + case BorderVertical : SideTab = CDockWidgetSideTab::Bottom; break; + case BorderHorizontal: SideTab = CDockWidgetSideTab::Right; break; + + // 4. Its in a corner + case BorderTopLeft : SideTab = HorizontalOrientation ? CDockWidgetSideTab::Top : CDockWidgetSideTab::Left; break; + case BorderTopRight : SideTab = HorizontalOrientation ? CDockWidgetSideTab::Top : CDockWidgetSideTab::Right; break; + case BorderBottomLeft : SideTab = HorizontalOrientation ? CDockWidgetSideTab::Bottom : CDockWidgetSideTab::Left; break; + case BorderBottomRight : SideTab = HorizontalOrientation ? CDockWidgetSideTab::Bottom : CDockWidgetSideTab::Right; break; + + // 5 Ists touching only one border + case BorderLeft: SideTab = CDockWidgetSideTab::Left; break; + case BorderRight: SideTab = CDockWidgetSideTab::Right; break; + case BorderTop: SideTab = CDockWidgetSideTab::Top; break; + case BorderBottom: SideTab = CDockWidgetSideTab::Bottom; break; } - // Then handle left and right - const auto dockWidgetCenter = DockAreaWidget->mapToGlobal(dockWidgetFrameGeometry.center()); - const auto calculatedPosition = dockWidgetCenter.x() <= splitterCenter.x() ? CDockWidgetSideTab::Left : CDockWidgetSideTab::Right; - if (calculatedPosition == CDockWidgetSideTab::Right) - { - if (CDockManager::testConfigFlag(CDockManager::DockContainerHasRightSideBar)) - { - return CDockWidgetSideTab::Right; - } - - if (CDockManager::testConfigFlag(CDockManager::DockContainerHasLeftSideBar)) - { - return CDockWidgetSideTab::Left; - } - - return CDockWidgetSideTab::Bottom; - } - - if (calculatedPosition == CDockWidgetSideTab::Left) - { - if (CDockManager::testConfigFlag(CDockManager::DockContainerHasLeftSideBar)) - { - return CDockWidgetSideTab::Left; - } - - if (CDockManager::testConfigFlag(CDockManager::DockContainerHasRightSideBar)) - { - return CDockWidgetSideTab::Right; - } - - return CDockWidgetSideTab::Bottom; - } - - Q_ASSERT_X(false, "CDockContainerWidget::getDockAreaPosition", "Unhandled branch. All positions should be accounted for."); - return CDockWidgetSideTab::Left; - + return SideTab; } //============================================================================ @@ -2233,6 +2274,18 @@ CSideTabBar* CDockContainerWidget::sideTabBar(CDockWidgetSideTab::SideTabBarArea { return d->SideTabBarWidgets[area]; } + + +//============================================================================ +QRect CDockContainerWidget::contentRect() +{ + if (!d->RootSplitter) + { + return QRect(); + } + + return d->RootSplitter->geometry(); +} } // namespace ads //--------------------------------------------------------------------------- diff --git a/src/DockContainerWidget.h b/src/DockContainerWidget.h index a26e7e2..005d37a 100644 --- a/src/DockContainerWidget.h +++ b/src/DockContainerWidget.h @@ -328,6 +328,11 @@ public: */ QList autoHideWidgets() const; + /** + * Returns the content rectangle without the autohide side bars + */ + QRect contentRect(); + Q_SIGNALS: /** * This signal is emitted if one or multiple dock areas has been added to