Improved logic for finding the auto hide side location

This commit is contained in:
Uwe Kindler 2022-10-17 14:22:12 +02:00
parent 14312442db
commit ffe6eccb05
4 changed files with 112 additions and 55 deletions

View File

@ -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());
}
}

View File

@ -61,7 +61,7 @@ private Q_SLOTS:
void onUndockButtonClicked();
void onTabsMenuActionTriggered(QAction* Action);
void onCurrentTabChanged(int Index);
void onAutoHideButtonClicked(bool Checked);
void onAutoHideButtonClicked();
protected:
/**

View File

@ -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
//---------------------------------------------------------------------------

View File

@ -328,6 +328,11 @@ public:
*/
QList<CAutoHideDockContainer*> 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