Started implementing autohide drag functionality

This commit is contained in:
Uwe Kindler 2023-06-27 10:12:51 +02:00
parent 34cc91a9af
commit b9479dbd3d
5 changed files with 229 additions and 14 deletions

View File

@ -1626,14 +1626,16 @@ int CDockContainerWidget::visibleDockAreaCount() const
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
const QPoint& TargetPos)
{
//dockContainer()->createAndSetupAutoHideContainer(area, this);
ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
CDockWidget* SingleDroppedDockWidget = FloatingWidget->topLevelDockWidget();
CDockWidget* SingleDockWidget = topLevelDockWidget();
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
auto dropArea = InvalidDockWidgetArea;
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
bool Dropped = false;
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
std::cout << "DockArea: " << DockArea << " dropArea: " << dropArea << std::endl;
if (DockArea)
{
auto dropOverlay = d->DockManager->dockAreaOverlay();
@ -1654,15 +1656,30 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
}
// mouse is over container
if (InvalidDockWidgetArea == dropArea)
std::cout << "Mouse is over container" << std::endl;
if (InvalidDockWidgetArea == dropArea && InvalidDockWidgetArea != ContainerDropArea)
{
dropArea = ContainerDropArea;
ADS_PRINT("Container Drop Content: " << dropArea);
if (dropArea != InvalidDockWidgetArea)
{
d->dropIntoContainer(FloatingWidget, dropArea);
Dropped = true;
}
if (internal::isSideBarArea(ContainerDropArea))
{
auto SideBarLocation = internal::toSideBarLocation(ContainerDropArea);
std::cout << "Drop into sidebar " << std::endl;
auto NewDockAreas = FloatingWidget->findChildren<CDockAreaWidget*>(
QString(), Qt::FindChildrenRecursively);
for (auto DockArea : NewDockAreas)
{
auto DockWidgets = DockArea->dockWidgets();
for (auto DockWidget : DockWidgets)
{
createAndSetupAutoHideContainer(SideBarLocation, DockWidget);
}
}
}
else
{
ADS_PRINT("Container Drop Content: " << ContainerDropArea);
d->dropIntoContainer(FloatingWidget, ContainerDropArea);
}
Dropped = true;
}
// Remove the auto hide widgets from the FloatingWidget and insert

View File

@ -38,11 +38,15 @@
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockContainerWidget.h"
#include "AutoHideSideBar.h"
#include "DockManager.h"
#include <iostream>
namespace ads
{
static const int AutoHideAreaWidth = 32;
/**
* Private data class of CDockOverlay
@ -62,6 +66,12 @@ struct DockOverlayPrivate
* Private data constructor
*/
DockOverlayPrivate(CDockOverlay* _public) : _this(_public) {}
/**
* Returns the overlay width / height depending on the visibility
* of the sidebar
*/
int sideBarOverlaySize(SideBarLocation sideBarLocation);
};
/**
@ -155,8 +165,20 @@ struct DockOverlayCrossPrivate
QLabel* l = new QLabel();
l->setObjectName("DockWidgetAreaLabel");
const qreal metric = dropIndicatiorWidth(l);
const QSizeF size(metric, metric);
qreal metric = dropIndicatiorWidth(l);
QSizeF size(metric, metric);
if (internal::isSideBarArea(DockWidgetArea))
{
auto SideBarLocation = internal::toSideBarLocation(DockWidgetArea);
if (internal::isHorizontalSideBarLocation(SideBarLocation))
{
size.setHeight(size.height() / 2);
}
else
{
size.setWidth(size.width() / 2);
}
}
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
l->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
@ -283,7 +305,7 @@ struct DockOverlayCrossPrivate
p.restore();
// Draw arrow for outer container drop indicators
if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
/*if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
{
QRectF ArrowRect;
ArrowRect.setSize(baseSize);
@ -317,7 +339,7 @@ struct DockOverlayCrossPrivate
}
p.drawPolygon(Arrow);
}
}*/
pm.setDevicePixelRatio(DevicePixelRatio);
return pm;
@ -326,6 +348,22 @@ struct DockOverlayCrossPrivate
};
//============================================================================
int DockOverlayPrivate::sideBarOverlaySize(SideBarLocation sideBarLocation)
{
auto Container = qobject_cast<CDockContainerWidget*>(TargetWidget.data());
auto SideBar = Container->sideTabBar(sideBarLocation);
if (!SideBar || !SideBar->isVisibleTo(Container))
{
return AutoHideAreaWidth;
}
else
{
return (SideBar->orientation() == Qt::Horizontal) ? SideBar->height() : SideBar->width();
}
}
//============================================================================
CDockOverlay::CDockOverlay(QWidget* parent, eMode Mode) :
QFrame(parent),
@ -375,15 +413,42 @@ DockWidgetAreas CDockOverlay::allowedAreas() const
//============================================================================
DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
{
if (!d->TargetWidget)
{
return InvalidDockWidgetArea;
}
DockWidgetArea Result = d->Cross->cursorLocation();
if (Result != InvalidDockWidgetArea)
{
return Result;
}
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
if (!DockArea)
{
/*auto Rect = rect();
const QPoint pos = mapFromGlobal(QCursor::pos());
if (pos.x() < d->sideBarOverlaySize(SideBarLeft))
{
return LeftAutoHideArea;
}
else if (pos.x() > (Rect.width() - d->sideBarOverlaySize(SideBarRight)))
{
return RightAutoHideArea;
}
else if (pos.y() < d->sideBarOverlaySize(SideBarTop))
{
return TopAutoHideArea;
}
else if (pos.y() > (Rect.height() - d->sideBarOverlaySize(SideBarBottom)))
{
return BottomAutoHideArea;
}
else
{
return Result;
}*/
return Result;
}
@ -490,6 +555,10 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
case BottomDockWidgetArea: r.setY(r.height() * (1 - 1 / Factor)); break;
case LeftDockWidgetArea: r.setWidth(r.width() / Factor); break;
case CenterDockWidgetArea: r = rect();break;
case LeftAutoHideArea: r.setWidth(d->sideBarOverlaySize(SideBarLeft)); break;
case RightAutoHideArea: r.setX(r.width() - d->sideBarOverlaySize(SideBarRight)); break;
case TopAutoHideArea: r.setHeight(d->sideBarOverlaySize(SideBarTop)); break;
case BottomAutoHideArea: r.setY(r.height() - d->sideBarOverlaySize(SideBarBottom)); break;
default: return;
}
QPainter painter(this);
@ -574,6 +643,23 @@ QPoint DockOverlayCrossPrivate::areaGridPosition(const DockWidgetArea area)
default: return QPoint();
}
}
else if (CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
{
switch (area)
{
case TopDockWidgetArea: return QPoint(1, 3);
case RightDockWidgetArea: return QPoint(3, 5);
case BottomDockWidgetArea: return QPoint(5, 3);
case LeftDockWidgetArea: return QPoint(3, 1);
case CenterDockWidgetArea: return QPoint(3, 3);
case TopAutoHideArea: return QPoint(0, 3);
case RightAutoHideArea: return QPoint(3, 6);
case BottomAutoHideArea: return QPoint(6, 3);
case LeftAutoHideArea: return QPoint(3, 0);
default: return QPoint();
}
}
else
{
switch (area)
@ -627,6 +713,16 @@ void CDockOverlayCross::setupOverlayCross(CDockOverlay::eMode Mode)
areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, Mode));
areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
if (CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled)
&& CDockOverlay::ModeContainerOverlay == Mode)
{
areaWidgets.insert(TopAutoHideArea, d->createDropIndicatorWidget(TopAutoHideArea, Mode));
areaWidgets.insert(RightAutoHideArea, d->createDropIndicatorWidget(RightAutoHideArea, Mode));
areaWidgets.insert(BottomAutoHideArea, d->createDropIndicatorWidget(BottomAutoHideArea, Mode));
areaWidgets.insert(LeftAutoHideArea, d->createDropIndicatorWidget(LeftAutoHideArea, Mode));
}
#if QT_VERSION >= 0x050600
d->LastDevicePixelRatio = devicePixelRatioF();
#else
@ -713,6 +809,26 @@ void CDockOverlayCross::setAreaWidgets(const QHash<DockWidgetArea, QWidget*>& wi
d->GridLayout->setColumnStretch(3, 0);
d->GridLayout->setColumnStretch(4, 1);
}
else if (CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
{
d->GridLayout->setContentsMargins(4, 4, 4, 4);
d->GridLayout->setSpacing(4);
d->GridLayout->setRowStretch(0, 0);
d->GridLayout->setRowStretch(1, 0);
d->GridLayout->setRowStretch(2, 1);
d->GridLayout->setRowStretch(3, 1);
d->GridLayout->setRowStretch(4, 1);
d->GridLayout->setRowStretch(5, 0);
d->GridLayout->setRowStretch(6, 0);
d->GridLayout->setColumnStretch(0, 0);
d->GridLayout->setColumnStretch(1, 0);
d->GridLayout->setColumnStretch(2, 1);
d->GridLayout->setColumnStretch(3, 1);
d->GridLayout->setColumnStretch(4, 1);
d->GridLayout->setColumnStretch(5, 0);
d->GridLayout->setColumnStretch(6, 0);
}
else
{
d->GridLayout->setContentsMargins(4, 4, 4, 4);

View File

@ -347,6 +347,7 @@ void CFloatingDragPreview::startFloating(const QPoint &DragStartMousePos,
void CFloatingDragPreview::finishDragging()
{
ADS_PRINT("CFloatingDragPreview::finishDragging");
std::cout << "CFloatingDragPreview::finishDragging" << std::endl;
auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
@ -369,12 +370,28 @@ void CFloatingDragPreview::finishDragging()
}
else if (ContainerDropArea != InvalidDockWidgetArea)
{
std::cout << "ContainerDropArea != InvalidDockWidgetArea " << ContainerDropArea << std::endl;
// If there is only one single dock area, and we drop into the center
// then we tabify the dropped widget into the only visible dock area
if (d->DropContainer->visibleDockAreaCount() <= 1 && CenterDockWidgetArea == ContainerDropArea)
{
d->DropContainer->dropWidget(d->Content, ContainerDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
}
else if (internal::isSideBarArea(ContainerDropArea))
{
// Drop into AutoHideArea
auto DockWidget = qobject_cast<CDockWidget*>(d->Content);
auto DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
auto SideBarLocation = internal::toSideBarLocation(ContainerDropArea);
if (DockWidget)
{
DockWidget->toggleAutoHide(SideBarLocation);
}
else if (DockArea)
{
DockArea->toggleAutoHide(SideBarLocation);
}
}
else
{
d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);

View File

@ -333,6 +333,47 @@ CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
}
//============================================================================
SideBarLocation toSideBarLocation(DockWidgetArea Area)
{
switch (Area)
{
case LeftAutoHideArea: return SideBarLeft;
case RightAutoHideArea: return SideBarRight;
case TopAutoHideArea: return SideBarTop;
case BottomAutoHideArea: return SideBarBottom;
default:
return SideBarNone;
}
return SideBarNone;
}
//============================================================================
bool isHorizontalSideBarLocation(SideBarLocation Location)
{
switch (Location)
{
case SideBarTop:
case SideBarBottom: return true;
case SideBarLeft:
case SideBarRight: return false;
default:
return false;
}
return false;
}
//============================================================================
bool isSideBarArea(DockWidgetArea Area)
{
return toSideBarLocation(Area) != SideBarNone;
}
//============================================================================
QPixmap createTransparentPixmap(const QPixmap& Source, qreal Opacity)
{

View File

@ -82,6 +82,10 @@ enum DockWidgetArea
TopDockWidgetArea = 0x04,
BottomDockWidgetArea = 0x08,
CenterDockWidgetArea = 0x10,
LeftAutoHideArea = 0x20,
RightAutoHideArea = 0x40,
TopAutoHideArea = 0x80,
BottomAutoHideArea = 0x100,
InvalidDockWidgetArea = NoDockWidgetArea,
OuterDockAreas = TopDockWidgetArea | LeftDockWidgetArea | RightDockWidgetArea | BottomDockWidgetArea,
@ -194,6 +198,7 @@ void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
*/
void hideEmptyParentSplitters(CDockSplitter* FirstParentSplitter);
/**
* Convenience class for QPair to provide better naming than first and
* second
@ -212,6 +217,25 @@ public:
*/
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area);
/**
* Returns the SieBarLocation for the AutoHide dock widget areas
*/
SideBarLocation toSideBarLocation(DockWidgetArea Area);
/**
* Returns true for the top or bottom side bar ansd false for the
* left and right side bar
*/
bool isHorizontalSideBarLocation(SideBarLocation Location);
/**
* Returns true, if the given dock area is a SideBar area
*/
bool isSideBarArea(DockWidgetArea Area);
/**
* Searches for the parent widget of the given type.
* Returns the parent widget of the given widget or 0 if the widget is not