Add open auto-hide dock on hover from drag and drop (#663)

This commit is contained in:
TheBoje 2024-10-04 22:17:42 +02:00
parent 952131a1e9
commit 6ff39bccf8
7 changed files with 585 additions and 552 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -49,6 +49,7 @@
- [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock) - [`AutoHideCloseButtonCollapsesDock`](#autohideclosebuttoncollapsesdock)
- [`AutoHideHasCloseButton`](#autohidehasclosebutton) - [`AutoHideHasCloseButton`](#autohidehasclosebutton)
- [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton) - [`AutoHideHasMinimizeButton`](#autohidehasminimizebutton)
- [`AutoHideOpenOnDragHover`](#autohideopenondraghover)
- [DockWidget Feature Flags](#dockwidget-feature-flags) - [DockWidget Feature Flags](#dockwidget-feature-flags)
- [`DockWidgetClosable`](#dockwidgetclosable) - [`DockWidgetClosable`](#dockwidgetclosable)
- [`DockWidgetMovable`](#dockwidgetmovable) - [`DockWidgetMovable`](#dockwidgetmovable)
@ -704,6 +705,15 @@ If this flag is set (disabled by default), then each auto hide widget has a mini
![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png) ![AutoHideHasMinimizeButton](cfg_flag_AutoHideHasMinimizeButton.png)
### `AutoHideOpenOnDragHover`
If this flag is set (disabled by default), then holding a dragging cursor hover an auto-hide collapsed dock's tab will open said dock:
![AutoHideOpenOnDragHover](cfg_flag_AutoHideOpenOnDragHover.gif)
Said dock must be set to accept drops to hide when cursor leaves its scope.
## DockWidget Feature Flags ## DockWidget Feature Flags
### `DockWidgetClosable` ### `DockWidgetClosable`

View File

@ -16,7 +16,6 @@
** License along with this library; If not, see <http://www.gnu.org/licenses/>. ** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/ ******************************************************************************/
//============================================================================ //============================================================================
/// \file AutoHideDockContainer.cpp /// \file AutoHideDockContainer.cpp
/// \author Syarif Fakhri /// \author Syarif Fakhri
@ -29,24 +28,24 @@
//============================================================================ //============================================================================
#include "AutoHideDockContainer.h" #include "AutoHideDockContainer.h"
#include <QXmlStreamWriter>
#include <QBoxLayout>
#include <QPainter>
#include <QSplitter>
#include <QPointer>
#include <QApplication> #include <QApplication>
#include <QBoxLayout>
#include <QCursor> #include <QCursor>
#include <QPainter>
#include "DockManager.h" #include <QPointer>
#include "DockAreaWidget.h" #include <QSplitter>
#include "ResizeHandle.h" #include <QXmlStreamWriter>
#include "DockComponentsFactory.h"
#include "AutoHideSideBar.h"
#include "AutoHideTab.h"
#include <iostream> #include <iostream>
#include "AutoHideSideBar.h"
#include "AutoHideTab.h"
#include "DockAreaWidget.h"
#include "DockComponentsFactory.h"
#include "DockManager.h"
#include "ResizeHandle.h"
#include "ads_globals.h"
namespace ads namespace ads
{ {
static const int ResizeMargin = 30; static const int ResizeMargin = 30;
@ -60,14 +59,12 @@ bool static isHorizontalArea(SideBarLocation Area)
case SideBarLocation::SideBarBottom: return true; case SideBarLocation::SideBarBottom: return true;
case SideBarLocation::SideBarLeft: case SideBarLocation::SideBarLeft:
case SideBarLocation::SideBarRight: return false; case SideBarLocation::SideBarRight: return false;
default: default: return true;
return true;
} }
return true; return true;
} }
//============================================================================ //============================================================================
Qt::Edge static edgeFromSideTabBarArea(SideBarLocation Area) Qt::Edge static edgeFromSideTabBarArea(SideBarLocation Area)
{ {
@ -77,14 +74,12 @@ Qt::Edge static edgeFromSideTabBarArea(SideBarLocation Area)
case SideBarLocation::SideBarBottom: return Qt::TopEdge; case SideBarLocation::SideBarBottom: return Qt::TopEdge;
case SideBarLocation::SideBarLeft: return Qt::RightEdge; case SideBarLocation::SideBarLeft: return Qt::RightEdge;
case SideBarLocation::SideBarRight: return Qt::LeftEdge; case SideBarLocation::SideBarRight: return Qt::LeftEdge;
default: default: return Qt::LeftEdge;
return Qt::LeftEdge;
} }
return Qt::LeftEdge; return Qt::LeftEdge;
} }
//============================================================================ //============================================================================
int resizeHandleLayoutPosition(SideBarLocation Area) int resizeHandleLayoutPosition(SideBarLocation Area)
{ {
@ -96,14 +91,12 @@ int resizeHandleLayoutPosition(SideBarLocation Area)
case SideBarLocation::SideBarTop: case SideBarLocation::SideBarTop:
case SideBarLocation::SideBarLeft: return 1; case SideBarLocation::SideBarLeft: return 1;
default: default: return 0;
return 0;
} }
return 0; return 0;
} }
/** /**
* Private data of CAutoHideDockContainer - pimpl * Private data of CAutoHideDockContainer - pimpl
*/ */
@ -122,7 +115,7 @@ struct AutoHideDockContainerPrivate
/** /**
* Private data constructor * Private data constructor
*/ */
AutoHideDockContainerPrivate(CAutoHideDockContainer *_public); AutoHideDockContainerPrivate(CAutoHideDockContainer* _public);
/** /**
* Convenience function to get a dock widget area * Convenience function to get a dock widget area
@ -135,8 +128,7 @@ struct AutoHideDockContainerPrivate
case SideBarLocation::SideBarRight: return RightDockWidgetArea; case SideBarLocation::SideBarRight: return RightDockWidgetArea;
case SideBarLocation::SideBarBottom: return BottomDockWidgetArea; case SideBarLocation::SideBarBottom: return BottomDockWidgetArea;
case SideBarLocation::SideBarTop: return TopDockWidgetArea; case SideBarLocation::SideBarTop: return TopDockWidgetArea;
default: default: return LeftDockWidgetArea;
return LeftDockWidgetArea;
} }
return LeftDockWidgetArea; return LeftDockWidgetArea;
@ -148,18 +140,16 @@ struct AutoHideDockContainerPrivate
void updateResizeHandleSizeLimitMax() void updateResizeHandleSizeLimitMax()
{ {
auto Rect = _this->dockContainer()->contentRect(); auto Rect = _this->dockContainer()->contentRect();
const auto maxResizeHandleSize = ResizeHandle->orientation() == Qt::Horizontal const auto maxResizeHandleSize =
? Rect.width() : Rect.height(); ResizeHandle->orientation() == Qt::Horizontal ? Rect.width() :
Rect.height();
ResizeHandle->setMaxResizeSize(maxResizeHandleSize - ResizeMargin); ResizeHandle->setMaxResizeSize(maxResizeHandleSize - ResizeMargin);
} }
/** /**
* Convenience function to check, if this is an horizontal area * Convenience function to check, if this is an horizontal area
*/ */
bool isHorizontal() const bool isHorizontal() const { return isHorizontalArea(SideTabBarArea); }
{
return isHorizontalArea(SideTabBarArea);
}
/** /**
* Forward this event to the dock container * Forward this event to the dock container
@ -175,15 +165,11 @@ struct AutoHideDockContainerPrivate
}; // struct AutoHideDockContainerPrivate }; // struct AutoHideDockContainerPrivate
//============================================================================ //============================================================================
AutoHideDockContainerPrivate::AutoHideDockContainerPrivate( AutoHideDockContainerPrivate::AutoHideDockContainerPrivate(
CAutoHideDockContainer *_public) : CAutoHideDockContainer* _public)
_this(_public) : _this(_public)
{ {}
}
//============================================================================ //============================================================================
CDockContainerWidget* CAutoHideDockContainer::dockContainer() const CDockContainerWidget* CAutoHideDockContainer::dockContainer() const
@ -191,29 +177,32 @@ CDockContainerWidget* CAutoHideDockContainer::dockContainer() const
return internal::findParent<CDockContainerWidget*>(this); return internal::findParent<CDockContainerWidget*>(this);
} }
//============================================================================ //============================================================================
CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarLocation area, CDockContainerWidget* parent) : CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget,
Super(parent), SideBarLocation area,
d(new AutoHideDockContainerPrivate(this)) CDockContainerWidget* parent)
: Super(parent), d(new AutoHideDockContainerPrivate(this))
{ {
hide(); // auto hide dock container is initially always hidden hide(); // auto hide dock container is initially always hidden
d->SideTabBarArea = area; d->SideTabBarArea = area;
d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr); d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr);
connect(d->SideTab, &CAutoHideTab::pressed, this, &CAutoHideDockContainer::toggleCollapseState); connect(d->SideTab, &CAutoHideTab::pressed, this,
&CAutoHideDockContainer::toggleCollapseState);
d->DockArea = new CDockAreaWidget(DockWidget->dockManager(), parent); d->DockArea = new CDockAreaWidget(DockWidget->dockManager(), parent);
d->DockArea->setObjectName("autoHideDockArea"); d->DockArea->setObjectName("autoHideDockArea");
d->DockArea->setAutoHideDockContainer(this); d->DockArea->setAutoHideDockContainer(this);
setObjectName("autoHideDockContainer"); setObjectName("autoHideDockContainer");
d->Layout = new QBoxLayout(isHorizontalArea(area) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); d->Layout = new QBoxLayout(isHorizontalArea(area) ? QBoxLayout::TopToBottom :
QBoxLayout::LeftToRight);
d->Layout->setContentsMargins(0, 0, 0, 0); d->Layout->setContentsMargins(0, 0, 0, 0);
d->Layout->setSpacing(0); d->Layout->setSpacing(0);
setLayout(d->Layout); setLayout(d->Layout);
d->ResizeHandle = new CResizeHandle(edgeFromSideTabBarArea(area), this); d->ResizeHandle = new CResizeHandle(edgeFromSideTabBarArea(area), this);
d->ResizeHandle->setMinResizeSize(64); d->ResizeHandle->setMinResizeSize(64);
bool OpaqueResize = CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize); bool OpaqueResize =
CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize);
d->ResizeHandle->setOpaqueResize(OpaqueResize); d->ResizeHandle->setOpaqueResize(OpaqueResize);
d->Size = d->DockArea->size(); d->Size = d->DockArea->size();
d->SizeCache = DockWidget->size(); d->SizeCache = DockWidget->size();
@ -223,12 +212,12 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
// The dock area should not be added to the layout before it contains the // The dock area should not be added to the layout before it contains the
// dock widget. If you add it to the layout before it contains the dock widget // dock widget. If you add it to the layout before it contains the dock widget
// then you will likely see this warning for OpenGL widgets or QAxWidgets: // then you will likely see this warning for OpenGL widgets or QAxWidgets:
// setGeometry: Unable to set geometry XxY+Width+Height on QWidgetWindow/'WidgetClassWindow // setGeometry: Unable to set geometry XxY+Width+Height on
// QWidgetWindow/'WidgetClassWindow
d->Layout->addWidget(d->DockArea); d->Layout->addWidget(d->DockArea);
d->Layout->insertWidget(resizeHandleLayoutPosition(area), d->ResizeHandle); d->Layout->insertWidget(resizeHandleLayoutPosition(area), d->ResizeHandle);
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::updateSize() void CAutoHideDockContainer::updateSize()
{ {
@ -242,7 +231,8 @@ void CAutoHideDockContainer::updateSize()
switch (sideBarLocation()) switch (sideBarLocation())
{ {
case SideBarLocation::SideBarTop: case SideBarLocation::SideBarTop:
resize(rect.width(), qMin(rect.height() - ResizeMargin, d->Size.height())); resize(rect.width(),
qMin(rect.height() - ResizeMargin, d->Size.height()));
move(rect.topLeft()); move(rect.topLeft());
break; break;
@ -262,15 +252,15 @@ void CAutoHideDockContainer::updateSize()
case SideBarLocation::SideBarBottom: case SideBarLocation::SideBarBottom:
{ {
resize(rect.width(), qMin(rect.height() - ResizeMargin, d->Size.height())); resize(rect.width(),
qMin(rect.height() - ResizeMargin, d->Size.height()));
QPoint p = rect.bottomLeft(); QPoint p = rect.bottomLeft();
p.ry() -= (height() - 1); p.ry() -= (height() - 1);
move(p); move(p);
} }
break; break;
default: default: break;
break;
} }
if (orientation() == Qt::Horizontal) if (orientation() == Qt::Horizontal)
@ -313,18 +303,17 @@ CAutoHideSideBar* CAutoHideDockContainer::autoHideSideBar() const
else else
{ {
auto DockContainer = dockContainer(); auto DockContainer = dockContainer();
return DockContainer ? DockContainer->autoHideSideBar(d->SideTabBarArea) : nullptr; return DockContainer ? DockContainer->autoHideSideBar(d->SideTabBarArea) :
nullptr;
} }
} }
//============================================================================ //============================================================================
CAutoHideTab* CAutoHideDockContainer::autoHideTab() const CAutoHideTab* CAutoHideDockContainer::autoHideTab() const
{ {
return d->SideTab; return d->SideTab;
} }
//============================================================================ //============================================================================
CDockWidget* CAutoHideDockContainer::dockWidget() const CDockWidget* CAutoHideDockContainer::dockWidget() const
{ {
@ -360,14 +349,12 @@ void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
d->DockArea->resize(size()); d->DockArea->resize(size());
} }
//============================================================================ //============================================================================
SideBarLocation CAutoHideDockContainer::sideBarLocation() const SideBarLocation CAutoHideDockContainer::sideBarLocation() const
{ {
return d->SideTabBarArea; return d->SideTabBarArea;
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::setSideBarLocation(SideBarLocation SideBarLocation) void CAutoHideDockContainer::setSideBarLocation(SideBarLocation SideBarLocation)
{ {
@ -378,13 +365,15 @@ void CAutoHideDockContainer::setSideBarLocation(SideBarLocation SideBarLocation)
d->SideTabBarArea = SideBarLocation; d->SideTabBarArea = SideBarLocation;
d->Layout->removeWidget(d->ResizeHandle); d->Layout->removeWidget(d->ResizeHandle);
d->Layout->setDirection(isHorizontalArea(SideBarLocation) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); d->Layout->setDirection(isHorizontalArea(SideBarLocation) ?
d->Layout->insertWidget(resizeHandleLayoutPosition(SideBarLocation), d->ResizeHandle); QBoxLayout::TopToBottom :
QBoxLayout::LeftToRight);
d->Layout->insertWidget(resizeHandleLayoutPosition(SideBarLocation),
d->ResizeHandle);
d->ResizeHandle->setHandlePosition(edgeFromSideTabBarArea(SideBarLocation)); d->ResizeHandle->setHandlePosition(edgeFromSideTabBarArea(SideBarLocation));
internal::repolishStyle(this, internal::RepolishDirectChildren); internal::repolishStyle(this, internal::RepolishDirectChildren);
} }
//============================================================================ //============================================================================
CDockAreaWidget* CAutoHideDockContainer::dockAreaWidget() const CDockAreaWidget* CAutoHideDockContainer::dockAreaWidget() const
{ {
@ -400,17 +389,16 @@ void CAutoHideDockContainer::moveContentsToParent()
// to the user and he does not have to search where the widget was inserted. // to the user and he does not have to search where the widget was inserted.
d->DockWidget->setDockArea(nullptr); d->DockWidget->setDockArea(nullptr);
auto DockContainer = dockContainer(); auto DockContainer = dockContainer();
DockContainer->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea), d->DockWidget); DockContainer->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea),
d->DockWidget);
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::cleanupAndDelete() void CAutoHideDockContainer::cleanupAndDelete()
{ {
const auto dockWidget = d->DockWidget; const auto dockWidget = d->DockWidget;
if (dockWidget) if (dockWidget)
{ {
auto SideTab = d->SideTab; auto SideTab = d->SideTab;
SideTab->removeFromSideBar(); SideTab->removeFromSideBar();
SideTab->setParent(nullptr); SideTab->setParent(nullptr);
@ -421,18 +409,19 @@ void CAutoHideDockContainer::cleanupAndDelete()
deleteLater(); deleteLater();
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::saveState(QXmlStreamWriter& s) void CAutoHideDockContainer::saveState(QXmlStreamWriter& s)
{ {
s.writeStartElement("Widget"); s.writeStartElement("Widget");
s.writeAttribute("Name", d->DockWidget->objectName()); s.writeAttribute("Name", d->DockWidget->objectName());
s.writeAttribute("Closed", QString::number(d->DockWidget->isClosed() ? 1 : 0)); s.writeAttribute("Closed",
s.writeAttribute("Size", QString::number(d->isHorizontal() ? d->Size.height() : d->Size.width())); QString::number(d->DockWidget->isClosed() ? 1 : 0));
s.writeAttribute(
"Size",
QString::number(d->isHorizontal() ? d->Size.height() : d->Size.width()));
s.writeEndElement(); s.writeEndElement();
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::toggleView(bool Enable) void CAutoHideDockContainer::toggleView(bool Enable)
{ {
@ -454,7 +443,6 @@ void CAutoHideDockContainer::toggleView(bool Enable)
} }
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::collapseView(bool Enable) void CAutoHideDockContainer::collapseView(bool Enable)
{ {
@ -477,14 +465,12 @@ void CAutoHideDockContainer::collapseView(bool Enable)
d->SideTab->updateStyle(); d->SideTab->updateStyle();
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::toggleCollapseState() void CAutoHideDockContainer::toggleCollapseState()
{ {
collapseView(isVisible()); collapseView(isVisible());
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::setSize(int Size) void CAutoHideDockContainer::setSize(int Size)
{ {
@ -500,7 +486,6 @@ void CAutoHideDockContainer::setSize(int Size)
updateSize(); updateSize();
} }
//============================================================================ //============================================================================
/** /**
* Returns true if the object given in ancestor is an ancestor of the object * Returns true if the object given in ancestor is an ancestor of the object
@ -523,13 +508,12 @@ static bool objectIsAncestorOf(const QObject* descendant, const QObject* ancesto
return false; return false;
} }
//============================================================================ //============================================================================
/** /**
* Returns true if the object given in ancestor is the object given in descendant * Returns true if the object given in ancestor is the object given in descendant
* or if it is an ancestor of the object given in descendant * or if it is an ancestor of the object given in descendant
*/ */
static bool isObjectOrAncestor(const QObject *descendant, const QObject *ancestor) static bool isObjectOrAncestor(const QObject* descendant, const QObject* ancestor)
{ {
if (ancestor && (descendant == ancestor)) if (ancestor && (descendant == ancestor))
{ {
@ -541,7 +525,6 @@ static bool isObjectOrAncestor(const QObject *descendant, const QObject *ancesto
} }
} }
//============================================================================ //============================================================================
bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event) bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
{ {
@ -565,8 +548,8 @@ bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
// Now check, if the user clicked into the side tab and ignore this event, // Now check, if the user clicked into the side tab and ignore this event,
// because the side tab click handler will call collapseView(). If we // because the side tab click handler will call collapseView(). If we
// do not ignore this here, then we will collapse the container and the side tab // do not ignore this here, then we will collapse the container and the
// click handler will uncollapse it // side tab click handler will uncollapse it
if (widget == d->SideTab.data()) if (widget == d->SideTab.data())
{ {
return Super::eventFilter(watched, event); return Super::eventFilter(watched, event);
@ -574,8 +557,8 @@ bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
// Now we check, if the user clicked inside of this auto hide container. // Now we check, if the user clicked inside of this auto hide container.
// If the click is inside of this auto hide container, then we can // If the click is inside of this auto hide container, then we can
// ignore the event, because the auto hide overlay should not get collapsed if // ignore the event, because the auto hide overlay should not get
// user works in it // collapsed if user works in it
if (isObjectOrAncestor(widget, this)) if (isObjectOrAncestor(widget, this))
{ {
return Super::eventFilter(watched, event); return Super::eventFilter(watched, event);
@ -608,7 +591,6 @@ bool CAutoHideDockContainer::eventFilter(QObject* watched, QEvent* event)
return Super::eventFilter(watched, event); return Super::eventFilter(watched, event);
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::resizeEvent(QResizeEvent* event) void CAutoHideDockContainer::resizeEvent(QResizeEvent* event)
{ {
@ -620,9 +602,8 @@ void CAutoHideDockContainer::resizeEvent(QResizeEvent* event)
} }
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::leaveEvent(QEvent *event) void CAutoHideDockContainer::leaveEvent(QEvent* event)
{ {
// Resizing of the dock container via the resize handle in non opaque mode // Resizing of the dock container via the resize handle in non opaque mode
// mays cause a leave event that is not really a leave event. Therefore // mays cause a leave event that is not really a leave event. Therefore
@ -635,37 +616,40 @@ void CAutoHideDockContainer::leaveEvent(QEvent *event)
Super::leaveEvent(event); Super::leaveEvent(event);
} }
//============================================================================ //============================================================================
bool CAutoHideDockContainer::event(QEvent* event) bool CAutoHideDockContainer::event(QEvent* event)
{ {
switch (event->type()) switch (event->type())
{ {
case QEvent::Enter: case QEvent::Enter:
case QEvent::Hide: case QEvent::Hide: d->forwardEventToDockContainer(event); break;
d->forwardEventToDockContainer(event);
break;
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress: return true; break;
return true;
break;
default: default: break;
break;
} }
return Super::event(event); return Super::event(event);
} }
//============================================================================
void CAutoHideDockContainer::dragLeaveEvent(QDragLeaveEvent*)
{
if (CDockManager::testAutoHideConfigFlag(
CDockManager::AutoHideOpenOnDragHover))
{
collapseView(true);
}
}
//============================================================================ //============================================================================
Qt::Orientation CAutoHideDockContainer::orientation() const Qt::Orientation CAutoHideDockContainer::orientation() const
{ {
return ads::internal::isHorizontalSideBarLocation(d->SideTabBarArea) return ads::internal::isHorizontalSideBarLocation(d->SideTabBarArea) ?
? Qt::Horizontal : Qt::Vertical; Qt::Horizontal :
Qt::Vertical;
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::resetToInitialDockWidgetSize() void CAutoHideDockContainer::resetToInitialDockWidgetSize()
{ {
@ -679,10 +663,9 @@ void CAutoHideDockContainer::resetToInitialDockWidgetSize()
} }
} }
//============================================================================ //============================================================================
void CAutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation NewSideBarLocation, void CAutoHideDockContainer::moveToNewSideBarLocation(
int TabIndex) SideBarLocation NewSideBarLocation, int TabIndex)
{ {
if (NewSideBarLocation == sideBarLocation() && TabIndex == this->tabIndex()) if (NewSideBarLocation == sideBarLocation() && TabIndex == this->tabIndex())
{ {
@ -701,12 +684,10 @@ void CAutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation NewSideBar
} }
} }
//============================================================================ //============================================================================
int CAutoHideDockContainer::tabIndex() const int CAutoHideDockContainer::tabIndex() const
{ {
return d->SideTab->tabIndex(); return d->SideTab->tabIndex();
} }
} } // namespace ads

View File

@ -18,7 +18,6 @@
** License along with this library; If not, see <http://www.gnu.org/licenses/>. ** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/ ******************************************************************************/
//============================================================================ //============================================================================
/// \file AutoHideDockContainer.h /// \file AutoHideDockContainer.h
/// \author Syarif Fakhri /// \author Syarif Fakhri
@ -29,10 +28,10 @@
//============================================================================ //============================================================================
// INCLUDES // INCLUDES
//============================================================================ //============================================================================
#include "ads_globals.h"
#include <QSplitter> #include <QSplitter>
#include "AutoHideTab.h" #include "AutoHideTab.h"
#include "ads_globals.h"
QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter) QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
@ -63,8 +62,9 @@ private:
protected: protected:
virtual bool eventFilter(QObject* watched, QEvent* event) override; virtual bool eventFilter(QObject* watched, QEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override; virtual void resizeEvent(QResizeEvent* event) override;
virtual void leaveEvent(QEvent *event) override; virtual void leaveEvent(QEvent* event) override;
virtual bool event(QEvent* event) override; virtual bool event(QEvent* event) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
/** /**
* Updates the size considering the size limits and the resize margins * Updates the size considering the size limits and the resize margins
@ -194,7 +194,8 @@ public:
* Removes the AutoHide container from the current side bar and adds * Removes the AutoHide container from the current side bar and adds
* it to the new side bar given in SideBarLocation * it to the new side bar given in SideBarLocation
*/ */
void moveToNewSideBarLocation(SideBarLocation SideBarLocation, int TabIndex = -1); void moveToNewSideBarLocation(SideBarLocation SideBarLocation,
int TabIndex = -1);
}; };
} // namespace ads } // namespace ads

View File

@ -33,6 +33,8 @@
#include <QApplication> #include <QApplication>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMenu> #include <QMenu>
#include <qevent.h>
#include <qnamespace.h>
#include "AutoHideDockContainer.h" #include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h" #include "AutoHideSideBar.h"
@ -41,6 +43,7 @@
#include "DockWidget.h" #include "DockWidget.h"
#include "FloatingDragPreview.h" #include "FloatingDragPreview.h"
#include "DockOverlay.h" #include "DockOverlay.h"
#include "ads_globals.h"
namespace ads namespace ads
{ {
@ -55,6 +58,7 @@ struct AutoHideTabPrivate
CAutoHideSideBar* SideBar = nullptr; CAutoHideSideBar* SideBar = nullptr;
Qt::Orientation Orientation{Qt::Vertical}; Qt::Orientation Orientation{Qt::Vertical};
QElapsedTimer TimeSinceHoverMousePress; QElapsedTimer TimeSinceHoverMousePress;
QElapsedTimer TimeSinceDragOver;
bool MousePressed = false; bool MousePressed = false;
eDragState DragState = DraggingInactive; eDragState DragState = DraggingInactive;
QPoint GlobalDragStartMousePosition; QPoint GlobalDragStartMousePosition;
@ -252,6 +256,9 @@ CAutoHideTab::CAutoHideTab(QWidget* parent) :
{ {
setAttribute(Qt::WA_NoMousePropagation); setAttribute(Qt::WA_NoMousePropagation);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
setAcceptDrops(true);
}
} }
@ -355,7 +362,6 @@ bool CAutoHideTab::event(QEvent* event)
case QEvent::Leave: case QEvent::Leave:
d->forwardEventToDockContainer(event); d->forwardEventToDockContainer(event);
break; break;
default: default:
break; break;
} }
@ -537,6 +543,37 @@ void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
Super::mouseMoveEvent(ev); Super::mouseMoveEvent(ev);
} }
//============================================================================
void CAutoHideTab::dragEnterEvent(QDragEnterEvent* ev) {
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
if (!d->TimeSinceDragOver.isValid()) {
d->TimeSinceDragOver.restart();
ev->accept();
}
else if (d->TimeSinceDragOver.hasExpired(500)) {
ev->accept();
}
}
}
//============================================================================
void CAutoHideTab::dragLeaveEvent(QDragLeaveEvent* ev) {
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)) {
d->TimeSinceDragOver.invalidate();
d->forwardEventToDockContainer(ev);
}
}
//============================================================================
void CAutoHideTab::dragMoveEvent(QDragMoveEvent* ev) {
if (CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideOpenOnDragHover)
&& d->TimeSinceDragOver.isValid()
&& d->TimeSinceDragOver.hasExpired(500)) {
d->TimeSinceDragOver.invalidate();
d->DockWidget->autoHideDockContainer()->collapseView(false);
ev->accept();
}
}
//============================================================================ //============================================================================
void CAutoHideTab::requestCloseDockWidget() void CAutoHideTab::requestCloseDockWidget()

View File

@ -76,6 +76,9 @@ protected:
virtual void mousePressEvent(QMouseEvent* ev) override; virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override; virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override; virtual void mouseMoveEvent(QMouseEvent* ev) override;
virtual void dragEnterEvent(QDragEnterEvent* ev) override;
virtual void dragLeaveEvent(QDragLeaveEvent* ev) override;
virtual void dragMoveEvent(QDragMoveEvent* ev) override;
public: public:
using Super = CPushButton; using Super = CPushButton;

View File

@ -254,6 +254,7 @@ public:
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button AutoHideHasCloseButton = 0x80, //< If the flag is set an auto hide title bar has a close button
AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget AutoHideHasMinimizeButton = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget
AutoHideOpenOnDragHover = 0x200, ///< if this flag is set, dragging hover the tab bar will open the dock
DefaultAutoHideConfig = AutoHideFeatureEnabled DefaultAutoHideConfig = AutoHideFeatureEnabled
| DockAreaHasAutoHideButton | DockAreaHasAutoHideButton