Added option ShowAutoHideOnMouseOver that enables showing of auto hide widgets by hovering over auto hide tab

This commit is contained in:
Uwe Kindler 2022-11-04 08:51:17 +01:00
parent 27d71eecac
commit c0247fc02a
7 changed files with 202 additions and 15 deletions

View File

@ -147,7 +147,7 @@ struct AutoHideDockContainerPrivate
*/
void updateResizeHandleSizeLimitMax()
{
auto Rect = _this->parentContainer()->contentRect();
auto Rect = _this->dockContainer()->contentRect();
const auto maxResizeHandleSize = ResizeHandle->orientation() == Qt::Horizontal
? Rect.width() : Rect.height();
ResizeHandle->setMaxResizeSize(maxResizeHandleSize - ResizeMargin);
@ -161,6 +161,18 @@ struct AutoHideDockContainerPrivate
return isHorizontalArea(SideTabBarArea);
}
/**
* Forward this event to the dock container
*/
void forwardEventToDockContainer(QEvent* event)
{
auto DockContainer = _this->dockContainer();
if (DockContainer)
{
DockContainer->handleAutoHideWidgetEvent(event, _this);
}
}
}; // struct AutoHideDockContainerPrivate
@ -174,7 +186,7 @@ AutoHideDockContainerPrivate::AutoHideDockContainerPrivate(
//============================================================================
CDockContainerWidget* CAutoHideDockContainer::parentContainer() const
CDockContainerWidget* CAutoHideDockContainer::dockContainer() const
{
if (d->DockArea)
{
@ -231,7 +243,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
//============================================================================
void CAutoHideDockContainer::updateSize()
{
auto dockContainerParent = parentContainer();
auto dockContainerParent = dockContainer();
if (!dockContainerParent)
{
return;
@ -281,9 +293,9 @@ CAutoHideDockContainer::~CAutoHideDockContainer()
// Remove event filter in case there are any queued messages
qApp->removeEventFilter(this);
if (parentContainer())
if (dockContainer())
{
parentContainer()->removeAutoHideWidget(this);
dockContainer()->removeAutoHideWidget(this);
}
if (d->SideTab)
@ -297,7 +309,7 @@ CAutoHideDockContainer::~CAutoHideDockContainer()
//============================================================================
CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
{
return parentContainer()->sideTabBar(d->SideTabBarArea);
return dockContainer()->sideTabBar(d->SideTabBarArea);
}
@ -366,7 +378,7 @@ void CAutoHideDockContainer::moveContentsToParent()
// location like it had as a auto hide widget. This brings the least surprise
// to the user and he does not have to search where the widget was inserted.
d->DockWidget->setDockArea(nullptr);
parentContainer()->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea), d->DockWidget);
dockContainer()->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea), d->DockWidget);
}
@ -479,7 +491,7 @@ bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
}
else if (event->type() == QEvent::MouseButtonPress)
{
auto Container = parentContainer();
auto Container = dockContainer();
// First we check, if the mouse button press is inside the container
// widget. If it is not, i.e. if someone resizes the main window or
// clicks into the application menu or toolbar, then we ignore the
@ -543,5 +555,29 @@ void CAutoHideDockContainer::resizeEvent(QResizeEvent* event)
}
}
//============================================================================
void CAutoHideDockContainer::leaveEvent(QEvent *event)
{
d->forwardEventToDockContainer(event);
Super::leaveEvent(event);
}
//============================================================================
void CAutoHideDockContainer::enterEvent(QEvent *event)
{
d->forwardEventToDockContainer(event);
Super::enterEvent(event);
}
//============================================================================
void CAutoHideDockContainer::hideEvent(QHideEvent *event)
{
d->forwardEventToDockContainer(event);
Super::hideEvent(event);
}
}

View File

@ -61,8 +61,12 @@ private:
friend SideTabBarPrivate;
protected:
bool eventFilter(QObject* watched, QEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
virtual bool eventFilter(QObject* watched, QEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void leaveEvent(QEvent *event) override;
virtual void enterEvent(QEvent *event) override;
virtual void hideEvent(QHideEvent *event) override;
/**
* Updates the size considering the size limits and the resize margins
@ -126,7 +130,7 @@ public:
/**
* Returns the parent container that hosts this auto hide container
*/
CDockContainerWidget* parentContainer() const;
CDockContainerWidget* dockContainer() const;
/**
* Moves the contents to the parent container widget

View File

@ -30,6 +30,7 @@
#include "AutoHideTab.h"
#include <QBoxLayout>
#include <QApplication>
#include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h"
@ -59,6 +60,26 @@ struct AutoHideTabPrivate
* the side bar
*/
void updateOrientation();
/**
* Convenience function to ease dock container access
*/
CDockContainerWidget* dockContainer() const
{
return DockWidget ? DockWidget->dockContainer() : nullptr;
}
/**
* Forward this event to the dock container
*/
void forwardEventToDockContainer(QEvent* event)
{
auto DockContainer = dockContainer();
if (DockContainer)
{
DockContainer->handleAutoHideWidgetEvent(event, _this);
}
}
}; // struct DockWidgetTabPrivate
@ -228,4 +249,28 @@ void CAutoHideTab::setDockWidget(CDockWidget* DockWidget)
setIcon(d->DockWidget->icon());
}
//============================================================================
void CAutoHideTab::enterEvent(QEvent *event)
{
d->forwardEventToDockContainer(event);
Super::enterEvent(event);
}
//============================================================================
void CAutoHideTab::leaveEvent(QEvent *event)
{
d->forwardEventToDockContainer(event);
Super::leaveEvent(event);
}
//============================================================================
void CAutoHideTab::mousePressEvent(QMouseEvent* event)
{
d->forwardEventToDockContainer(event);
Super::mousePressEvent(event);
}
}

View File

@ -67,6 +67,9 @@ protected:
void setSideBar(CAutoHideSideBar *SideTabBar);
void removeFromSideBar();
virtual void enterEvent(QEvent *event) override;
virtual void leaveEvent(QEvent *event) override;
virtual void mousePressEvent(QMouseEvent* event) override;
public:
using Super = CPushButton;

View File

@ -28,9 +28,6 @@
//============================================================================
// INCLUDES
//============================================================================
#include <AutoHideDockContainer.h>
#include <AutoHideSideBar.h>
#include <AutoHideTab.h>
#include "DockContainerWidget.h"
#include <QEvent>
@ -42,6 +39,10 @@
#include <QXmlStreamWriter>
#include <QAbstractButton>
#include <QLabel>
#include <QTimer>
#include <QMetaObject>
#include <QMetaType>
#include <QApplication>
#include "DockManager.h"
#include "DockAreaWidget.h"
@ -54,6 +55,9 @@
#include "DockWidgetTab.h"
#include "DockAreaTitleBar.h"
#include "DockFocusController.h"
#include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h"
#include "AutoHideTab.h"
#include <functional>
#include <iostream>
@ -146,6 +150,9 @@ public:
CDockAreaWidget* LastAddedAreaCache[5];
int VisibleDockAreaCount = -1;
CDockAreaWidget* TopLevelDockArea = nullptr;
QTimer DelayedAutoHideTimer;
CAutoHideTab* DelayedAutoHideTab;
bool DelayedAutoHideShow = false;
/**
* Private data constructor
@ -371,6 +378,14 @@ DockContainerWidgetPrivate::DockContainerWidgetPrivate(CDockContainerWidget* _pu
_this(_public)
{
std::fill(std::begin(LastAddedAreaCache),std::end(LastAddedAreaCache), nullptr);
DelayedAutoHideTimer.setSingleShot(true);
DelayedAutoHideTimer.setInterval(500);
QObject::connect(&DelayedAutoHideTimer, &QTimer::timeout, [this](){
qDebug() << "DelayedAutoHideTimer timeout";
auto GlobalPos = DelayedAutoHideTab->mapToGlobal(QPoint(0, 0));
qApp->sendEvent(DelayedAutoHideTab, new QMouseEvent(QEvent::MouseButtonPress,
QPoint(0, 0), GlobalPos, Qt::LeftButton, {Qt::LeftButton}, Qt::NoModifier));
});
}
@ -2045,6 +2060,78 @@ CDockManager* CDockContainerWidget::dockManager() const
{
return d->DockManager;
}
//===========================================================================
void CDockContainerWidget::handleAutoHideWidgetEvent(QEvent* e, QWidget* w)
{
if (!CDockManager::testAutoHideConfigFlag(CDockManager::ShowAutoHideOnMouseOver))
{
return;
}
if (dockManager()->isRestoringState())
{
return;
}
auto AutoHideTab = qobject_cast<CAutoHideTab*>(w);
if (AutoHideTab)
{
qDebug() << "Event AutoHideTab " << e;
switch (e->type())
{
case QEvent::Enter:
if (!AutoHideTab->dockWidget()->isVisible())
{
d->DelayedAutoHideTab = AutoHideTab;
d->DelayedAutoHideShow = true;
d->DelayedAutoHideTimer.start();
}
else
{
d->DelayedAutoHideTimer.stop();
}
break;
case QEvent::Leave:
case QEvent::MouseButtonPress:
d->DelayedAutoHideTimer.stop();
break;
default:
break;
}
return;
}
auto AutoHideContainer = qobject_cast<CAutoHideDockContainer*>(w);
if (AutoHideContainer)
{
qDebug() << "Event AutoHideContainer " << e;
switch (e->type())
{
case QEvent::Enter:
case QEvent::Hide:
d->DelayedAutoHideTimer.stop();
break;
case QEvent::Leave:
if (AutoHideContainer->isVisible())
{
d->DelayedAutoHideTab = AutoHideContainer->autoHideTab();
d->DelayedAutoHideShow = false;
d->DelayedAutoHideTimer.start();
}
break;
default:
break;
}
return;
return;
}
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -52,6 +52,9 @@ class CFloatingDragPreview;
struct FloatingDragPreviewPrivate;
class CDockingStateReader;
class CAutoHideSideBar;
class CAutoHideTab;
struct AutoHideTabPrivate;
struct AutoHideDockContainerPrivate;
/**
@ -76,7 +79,10 @@ private:
friend class CDockWidget;
friend class CFloatingDragPreview;
friend struct FloatingDragPreviewPrivate;
friend class CAutoHideDockContainer;
friend CAutoHideDockContainer;
friend CAutoHideTab;
friend AutoHideTabPrivate;
friend AutoHideDockContainerPrivate;
protected:
/**
@ -190,6 +196,11 @@ protected:
*/
void removeAutoHideWidget(CAutoHideDockContainer* AutoHideWidget);
/**
* Handles widget events of auto hide widgets to trigger delayed show
* or hide actions for auto hide container on auto hide tab mouse over
*/
void handleAutoHideWidgetEvent(QEvent* e, QWidget* w);
public:
/**

View File

@ -243,6 +243,7 @@ public:
BottomSideBarIconOnly = 0x40,//!< If the flag is set bottom side show only icon if a the dock widget has an icon assigned
TopSideBarIconOnly = 0x80, //!< If the flag is set top side bar show only icon if a the dock widget has an icon assigned
AutoHideSideBarsIconOnly = LeftSideBarIconOnly | RightSideBarIconOnly | BottomSideBarIconOnly | TopSideBarIconOnly,
ShowAutoHideOnMouseOver = 0x100, ///< show the auto hide window on mouse over tab and hide it if mouse leaves auto hide container
DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton ///< the default configuration for left and right side bars