Added option to auto hide a DockWidget or a DockArea to a specific sidebar location

This commit is contained in:
Uwe Kindler 2022-11-03 15:28:01 +01:00
parent 1922395b4b
commit 04ea1c68a7
14 changed files with 161 additions and 80 deletions

View File

@ -46,7 +46,7 @@ CMainWindow::CMainWindow(QWidget *parent)
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->setMinimumSize(200,150);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::Left, TableDockWidget);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::SideBarLeft, TableDockWidget);
autoHideContainer->setSize(480);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
@ -58,7 +58,7 @@ CMainWindow::CMainWindow(QWidget *parent)
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addAutoHideDockWidget(SideBarLocation::Left, TableDockWidget);
DockManager->addAutoHideDockWidget(SideBarLocation::SideBarLeft, TableDockWidget);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
QTableWidget* propertiesTable = new QTableWidget();

View File

@ -57,10 +57,12 @@ bool static isHorizontalArea(SideBarLocation Area)
{
switch (Area)
{
case SideBarLocation::Top:
case SideBarLocation::Bottom: return true;
case SideBarLocation::Left:
case SideBarLocation::Right: return false;
case SideBarLocation::SideBarTop:
case SideBarLocation::SideBarBottom: return true;
case SideBarLocation::SideBarLeft:
case SideBarLocation::SideBarRight: return false;
default:
return true;
}
return true;
@ -72,10 +74,12 @@ Qt::Edge static edgeFromSideTabBarArea(SideBarLocation Area)
{
switch (Area)
{
case SideBarLocation::Top: return Qt::BottomEdge;
case SideBarLocation::Bottom: return Qt::TopEdge;
case SideBarLocation::Left: return Qt::RightEdge;
case SideBarLocation::Right: return Qt::LeftEdge;
case SideBarLocation::SideBarTop: return Qt::BottomEdge;
case SideBarLocation::SideBarBottom: return Qt::TopEdge;
case SideBarLocation::SideBarLeft: return Qt::RightEdge;
case SideBarLocation::SideBarRight: return Qt::LeftEdge;
default:
return Qt::LeftEdge;
}
return Qt::LeftEdge;
@ -87,11 +91,14 @@ int resizeHandleLayoutPosition(SideBarLocation Area)
{
switch (Area)
{
case SideBarLocation::Bottom:
case SideBarLocation::Right: return 0;
case SideBarLocation::SideBarBottom:
case SideBarLocation::SideBarRight: return 0;
case SideBarLocation::Top:
case SideBarLocation::Left: return 1;
case SideBarLocation::SideBarTop:
case SideBarLocation::SideBarLeft: return 1;
default:
return 0;
}
return 0;
@ -106,8 +113,8 @@ struct AutoHideDockContainerPrivate
CAutoHideDockContainer* _this;
CDockAreaWidget* DockArea{nullptr};
CDockWidget* DockWidget{nullptr};
SideBarLocation SideTabBarArea;
QBoxLayout* Layout;
SideBarLocation SideTabBarArea = SideBarNone;
QBoxLayout* Layout = nullptr;
CResizeHandle* ResizeHandle = nullptr;
QSize Size; // creates invalid size
QPointer<CAutoHideTab> SideTab;
@ -124,10 +131,12 @@ struct AutoHideDockContainerPrivate
{
switch (area)
{
case SideBarLocation::Left: return LeftDockWidgetArea;
case SideBarLocation::Right: return RightDockWidgetArea;
case SideBarLocation::Bottom: return BottomDockWidgetArea;
case SideBarLocation::Top: return TopDockWidgetArea;
case SideBarLocation::SideBarLeft: return LeftDockWidgetArea;
case SideBarLocation::SideBarRight: return RightDockWidgetArea;
case SideBarLocation::SideBarBottom: return BottomDockWidgetArea;
case SideBarLocation::SideBarTop: return TopDockWidgetArea;
default:
return LeftDockWidgetArea;
}
return LeftDockWidgetArea;
@ -232,17 +241,17 @@ void CAutoHideDockContainer::updateSize()
switch (sideBarLocation())
{
case SideBarLocation::Top:
case SideBarLocation::SideBarTop:
resize(rect.width(), qMin(rect.height() - ResizeMargin, d->Size.height()));
move(rect.topLeft());
break;
case SideBarLocation::Left:
case SideBarLocation::SideBarLeft:
resize(qMin(d->Size.width(), rect.width() - ResizeMargin), rect.height());
move(rect.topLeft());
break;
case SideBarLocation::Right:
case SideBarLocation::SideBarRight:
{
resize(qMin(d->Size.width(), rect.width() - ResizeMargin), rect.height());
QPoint p = rect.topRight();
@ -251,7 +260,7 @@ void CAutoHideDockContainer::updateSize()
}
break;
case SideBarLocation::Bottom:
case SideBarLocation::SideBarBottom:
{
resize(rect.width(), qMin(rect.height() - ResizeMargin, d->Size.height()));
QPoint p = rect.bottomLeft();
@ -259,6 +268,9 @@ void CAutoHideDockContainer::updateSize()
move(p);
}
break;
default:
break;
}
}

View File

@ -62,7 +62,7 @@ struct AutoHideSideBarPrivate
CTabsWidget* TabsContainerWidget;
QBoxLayout* TabsLayout;
Qt::Orientation Orientation;
SideBarLocation SideTabArea = SideBarLocation::Left;
SideBarLocation SideTabArea = SideBarLocation::SideBarLeft;
/**
* Convenience function to check if this is a horizontal side bar
@ -161,7 +161,7 @@ CAutoHideSideBar::CAutoHideSideBar(CDockContainerWidget* parent, SideBarLocation
{
d->SideTabArea = area;
d->ContainerWidget = parent;
d->Orientation = (area == SideBarLocation::Bottom || area == SideBarLocation::Top)
d->Orientation = (area == SideBarLocation::SideBarBottom || area == SideBarLocation::SideBarTop)
? Qt::Horizontal : Qt::Vertical;
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

View File

@ -74,7 +74,7 @@ AutoHideTabPrivate::AutoHideTabPrivate(CAutoHideTab* _public) :
void AutoHideTabPrivate::updateOrientation()
{
auto area = SideBar->sideBarLocation();
_this->setOrientation((area == Bottom || area == Top) ? Qt::Horizontal : Qt::Vertical);
_this->setOrientation((area == SideBarBottom || area == SideBarTop) ? Qt::Horizontal : Qt::Vertical);
if (_this->icon().isNull())
{
@ -84,21 +84,24 @@ void AutoHideTabPrivate::updateOrientation()
bool IconOnly = false;
switch (area)
{
case SideBarLocation::Left:
case SideBarLocation::SideBarLeft:
IconOnly = CDockManager::testAutoHideConfigFlag(CDockManager::LeftSideBarIconOnly);
break;
case SideBarLocation::Right:
case SideBarLocation::SideBarRight:
IconOnly = CDockManager::testAutoHideConfigFlag(CDockManager::RightSideBarIconOnly);
break;
case SideBarLocation::Top:
case SideBarLocation::SideBarTop:
IconOnly = CDockManager::testAutoHideConfigFlag(CDockManager::BottomSideBarIconOnly);
break;
case SideBarLocation::Bottom:
case SideBarLocation::SideBarBottom:
IconOnly = CDockManager::testAutoHideConfigFlag(CDockManager::TopSideBarIconOnly);
break;
default:
break;
}
if (IconOnly)
@ -133,7 +136,7 @@ void CAutoHideTab::removeFromSideBar()
//============================================================================
CAutoHideTab::CAutoHideTab(QWidget* parent) :
Super(parent),
CPushButton(parent),
d(new AutoHideTabPrivate(this))
{
setAttribute(Qt::WA_NoMousePropagation);
@ -165,7 +168,7 @@ SideBarLocation CAutoHideTab::sideBarLocation() const
return d->SideBar->sideBarLocation();
}
return Left;
return SideBarLeft;
}

View File

@ -53,11 +53,13 @@
#include "DockFocusController.h"
#include "ElidingLabel.h"
#include "AutoHideDockContainer.h"
#include "IconProvider.h"
#include <iostream>
namespace ads
{
static const char* const LocationProperty = "Location";
/**
* Private data class of CDockAreaTitleBar class (pimpl)
@ -146,6 +148,19 @@ struct DockAreaTitleBarPrivate
* Makes the dock area floating
*/
IFloatingWidget* makeAreaFloating(const QPoint& Offset, eDragState DragState);
/**
* Helper function to create and initialize the menu entries for
* the "Auto Hide Group To..." menu
*/
QAction* createAutoHideToAction(const QString& Title, SideBarLocation Location,
QMenu* Menu)
{
auto Action = Menu->addAction(Title);
Action->setProperty("Location", Location);
QObject::connect(Action, &QAction::triggered, _this, &CDockAreaTitleBar::onAutoHideToActionClicked);
return Action;
}
};// struct DockAreaTitleBarPrivate
//============================================================================
@ -511,6 +526,15 @@ void CDockAreaTitleBar::onAutoHideDockAreaActionClicked()
}
//============================================================================
void CDockAreaTitleBar::onAutoHideToActionClicked()
{
qDebug() << "CDockAreaTitleBar::onAutoHideToActionClicked()";
int Location = sender()->property(LocationProperty).toInt();
d->DockArea->toggleAutoHide((SideBarLocation)Location);
}
//============================================================================
QAbstractButton* CDockAreaTitleBar::button(TitleBarButton which) const
{
@ -677,7 +701,18 @@ void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
Action = Menu.addAction(IsAutoHide ? tr("Dock") : tr("Auto Hide Group"), this, SLOT(onAutoHideDockAreaActionClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable));
auto AreaIsPinnable = d->DockArea->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(AreaIsPinnable);
if (!IsAutoHide)
{
auto menu = Menu.addMenu(tr("Auto Hide Group To..."));
menu->setEnabled(AreaIsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
}
}
Menu.addSeparator();
}

View File

@ -63,6 +63,7 @@ private Q_SLOTS:
void onCurrentTabChanged(int Index);
void onAutoHideButtonClicked();
void onAutoHideDockAreaActionClicked();
void onAutoHideToActionClicked();
protected:
/**

View File

@ -1241,60 +1241,60 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
int BorderDistance[4];
int Distance = qAbs(ContentRect.topLeft().y() - DockAreaRect.topLeft().y());
BorderDistance[SideBarLocation::Top] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::Top])
BorderDistance[SideBarLocation::SideBarTop] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::SideBarTop])
{
borders |= BorderTop;
}
Distance = qAbs(ContentRect.bottomRight().y() - DockAreaRect.bottomRight().y());
BorderDistance[SideBarLocation::Bottom] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::Bottom])
BorderDistance[SideBarLocation::SideBarBottom] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::SideBarBottom])
{
borders |= BorderBottom;
}
Distance = qAbs(ContentRect.topLeft().x() - DockAreaRect.topLeft().x());
BorderDistance[SideBarLocation::Left] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::Left])
BorderDistance[SideBarLocation::SideBarLeft] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::SideBarLeft])
{
borders |= BorderLeft;
}
Distance = qAbs(ContentRect.bottomRight().x() - DockAreaRect.bottomRight().x());
BorderDistance[SideBarLocation::Right] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::Right])
BorderDistance[SideBarLocation::SideBarRight] = (Distance < MinBorderDistance) ? 0 : Distance;
if (!BorderDistance[SideBarLocation::SideBarRight])
{
borders |= BorderRight;
}
auto SideTab = SideBarLocation::Right;
auto SideTab = SideBarLocation::SideBarRight;
switch (borders)
{
// 1. It's touching all borders
case BorderAll: SideTab = HorizontalOrientation ? SideBarLocation::Bottom : SideBarLocation::Right; break;
case BorderAll: SideTab = HorizontalOrientation ? SideBarLocation::SideBarBottom : SideBarLocation::SideBarRight; break;
// 2. It's touching 3 borders
case BorderVerticalBottom : SideTab = SideBarLocation::Bottom; break;
case BorderVerticalTop : SideTab = SideBarLocation::Top; break;
case BorderHorizontalLeft: SideTab = SideBarLocation::Left; break;
case BorderHorizontalRight: SideTab = SideBarLocation::Right; break;
case BorderVerticalBottom : SideTab = SideBarLocation::SideBarBottom; break;
case BorderVerticalTop : SideTab = SideBarLocation::SideBarTop; break;
case BorderHorizontalLeft: SideTab = SideBarLocation::SideBarLeft; break;
case BorderHorizontalRight: SideTab = SideBarLocation::SideBarRight; break;
// 3. Its touching horizontal or vertical borders
case BorderVertical : SideTab = SideBarLocation::Bottom; break;
case BorderHorizontal: SideTab = SideBarLocation::Right; break;
case BorderVertical : SideTab = SideBarLocation::SideBarBottom; break;
case BorderHorizontal: SideTab = SideBarLocation::SideBarRight; break;
// 4. Its in a corner
case BorderTopLeft : SideTab = HorizontalOrientation ? SideBarLocation::Top : SideBarLocation::Left; break;
case BorderTopRight : SideTab = HorizontalOrientation ? SideBarLocation::Top : SideBarLocation::Right; break;
case BorderBottomLeft : SideTab = HorizontalOrientation ? SideBarLocation::Bottom : SideBarLocation::Left; break;
case BorderBottomRight : SideTab = HorizontalOrientation ? SideBarLocation::Bottom : SideBarLocation::Right; break;
case BorderTopLeft : SideTab = HorizontalOrientation ? SideBarLocation::SideBarTop : SideBarLocation::SideBarLeft; break;
case BorderTopRight : SideTab = HorizontalOrientation ? SideBarLocation::SideBarTop : SideBarLocation::SideBarRight; break;
case BorderBottomLeft : SideTab = HorizontalOrientation ? SideBarLocation::SideBarBottom : SideBarLocation::SideBarLeft; break;
case BorderBottomRight : SideTab = HorizontalOrientation ? SideBarLocation::SideBarBottom : SideBarLocation::SideBarRight; break;
// 5 Ists touching only one border
case BorderLeft: SideTab = SideBarLocation::Left; break;
case BorderRight: SideTab = SideBarLocation::Right; break;
case BorderTop: SideTab = SideBarLocation::Top; break;
case BorderBottom: SideTab = SideBarLocation::Bottom; break;
case BorderLeft: SideTab = SideBarLocation::SideBarLeft; break;
case BorderRight: SideTab = SideBarLocation::SideBarRight; break;
case BorderTop: SideTab = SideBarLocation::SideBarTop; break;
case BorderBottom: SideTab = SideBarLocation::SideBarBottom; break;
}
return SideTab;
@ -1302,7 +1302,7 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
//============================================================================
void CDockAreaWidget::setAutoHide(bool Enable)
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
{
if (!isAutoHideFeatureEnabled())
{
@ -1318,7 +1318,7 @@ void CDockAreaWidget::setAutoHide(bool Enable)
return;
}
auto area = calculateSideTabBarArea();
auto area = (SideBarNone == Location) ? calculateSideTabBarArea() : Location;
for (const auto DockWidget : openedDockWidgets())
{
if (Enable == isAutoHide())
@ -1337,14 +1337,14 @@ void CDockAreaWidget::setAutoHide(bool Enable)
//============================================================================
void CDockAreaWidget::toggleAutoHide()
void CDockAreaWidget::toggleAutoHide(SideBarLocation Location)
{
if (!isAutoHideFeatureEnabled())
{
return;
}
setAutoHide(!isAutoHide());
setAutoHide(!isAutoHide(), Location);
}

View File

@ -401,13 +401,13 @@ public Q_SLOTS:
* If the dock area is switched to auto hide mode, then all dock widgets
* that are pinable will be added to the sidebar
*/
void setAutoHide(bool Enable);
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
/**
* Switches the dock area to auto hide mode or vice versa depending on its
* current state.
*/
void toggleAutoHide();
void toggleAutoHide(SideBarLocation Location = SideBarNone);
/**
* This function closes all other areas except of this area

View File

@ -1842,25 +1842,25 @@ void CDockContainerWidget::createSideTabBarWidgets()
}
{
auto Area = SideBarLocation::Left;
auto Area = SideBarLocation::SideBarLeft;
d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
d->Layout->addWidget(d->SideTabBarWidgets[Area], 1, 0);
}
{
auto Area = SideBarLocation::Right;
auto Area = SideBarLocation::SideBarRight;
d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
d->Layout->addWidget(d->SideTabBarWidgets[Area], 1, 2);
}
{
auto Area = SideBarLocation::Bottom;
auto Area = SideBarLocation::SideBarBottom;
d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
d->Layout->addWidget(d->SideTabBarWidgets[Area], 2, 1);
}
{
auto Area = SideBarLocation::Top;
auto Area = SideBarLocation::SideBarTop;
d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
d->Layout->addWidget(d->SideTabBarWidgets[Area], 0, 1);
}

View File

@ -1157,7 +1157,7 @@ void CDockWidget::raise()
//============================================================================
void CDockWidget::setAutoHide(bool Enable)
void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location)
{
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
@ -1177,21 +1177,21 @@ void CDockWidget::setAutoHide(bool Enable)
}
else
{
auto area = DockArea->calculateSideTabBarArea();
auto area = (SideBarNone == Location) ? DockArea->calculateSideTabBarArea() : Location;
dockContainer()->createAndSetupAutoHideContainer(area, this);
}
}
//============================================================================
void CDockWidget::toggleAutoHide()
void CDockWidget::toggleAutoHide(SideBarLocation Location)
{
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
return;
}
setAutoHide(!isAutoHide());
setAutoHide(!isAutoHide(), Location);
}

View File

@ -596,13 +596,13 @@ public Q_SLOTS:
* Sets the dock widget into auto hide mode if this feature is enabled
* via CDockManager::setAutoHideFlags(CDockManager::AutoHideFeatureEnabled)
*/
void setAutoHide(bool Enable);
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
/**
* Switches the dock widget to auto hide mode or vice versa depending on its
* current state.
*/
void toggleAutoHide();
void toggleAutoHide(SideBarLocation Location = SideBarNone);
Q_SIGNALS:

View File

@ -56,7 +56,7 @@
namespace ads
{
static const char* const LocationProperty = "Location";
using tTabLabel = CElidingLabel;
/**
@ -217,6 +217,18 @@ struct DockWidgetTabPrivate
return DockWidget->dockManager()->dockFocusController();
}
/**
* Helper function to create and initialize the menu entries for
* the "Auto Hide Group To..." menu
*/
QAction* createAutoHideToAction(const QString& Title, SideBarLocation Location,
QMenu* Menu)
{
auto Action = Menu->addAction(Title);
Action->setProperty("Location", Location);
QObject::connect(Action, &QAction::triggered, _this, &CDockWidgetTab::onAutoHideToActionClicked);
return Action;
}
};
// struct DockWidgetTabPrivate
@ -518,7 +530,15 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
Action = Menu.addAction(tr("Auto Hide"), this, SLOT(autoHideDockWidget()));
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable));
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
Action->setEnabled(IsPinnable);
auto menu = Menu.addMenu(tr("Auto Hide To..."));
menu->setEnabled(IsPinnable);
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
}
Menu.addSeparator();
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
@ -712,6 +732,14 @@ void CDockWidgetTab::autoHideDockWidget()
}
//===========================================================================
void CDockWidgetTab::onAutoHideToActionClicked()
{
int Location = sender()->property(LocationProperty).toInt();
d->DockWidget->toggleAutoHide((SideBarLocation)Location);
}
//============================================================================
bool CDockWidgetTab::event(QEvent *e)
{

View File

@ -64,6 +64,7 @@ private:
private Q_SLOTS:
void detachDockWidget();
void autoHideDockWidget();
void onAutoHideToActionClicked();
protected:
virtual void mousePressEvent(QMouseEvent* ev) override;

View File

@ -136,10 +136,11 @@ enum eBitwiseOperator
*/
enum SideBarLocation
{
Top,
Left,
Right,
Bottom
SideBarTop,
SideBarLeft,
SideBarRight,
SideBarBottom,
SideBarNone
};
Q_ENUMS(SideBarLocation);