mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-24 23:31:32 +08:00
Improved dragging of widgets into AutoHideArea
This commit is contained in:
parent
f6ccaba6aa
commit
b801f0655d
@ -437,8 +437,8 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
||||
{
|
||||
SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
|
||||
//SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea, ads::TopDockWidgetArea}); // just for testing
|
||||
}
|
||||
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
@ -506,7 +506,9 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// Test dock area docking
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetPinnable, false);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget, RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
auto LabelDockWidget = createLongTextLabelDockWidget();
|
||||
|
@ -186,6 +186,12 @@ public:
|
||||
*/
|
||||
void dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea);
|
||||
|
||||
/**
|
||||
* Drop floating widget into dock area
|
||||
*/
|
||||
@ -207,13 +213,13 @@ public:
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea);
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
* Moves the dock widget or dock area given in Widget parameter to
|
||||
* a auto hide sidebar area
|
||||
*/
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
|
||||
void moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area);
|
||||
|
||||
|
||||
/**
|
||||
@ -760,6 +766,33 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area)
|
||||
{
|
||||
std::cout << "DockContainerWidgetPrivate::moveToAutoHideSideBar " << area << std::endl;
|
||||
CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
|
||||
CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||
auto SideBarLocation = internal::toSideBarLocation(area);
|
||||
|
||||
if (DroppedDockWidget)
|
||||
{
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DroppedDockWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto DockWidget : DroppedDockArea->openedDockWidgets())
|
||||
{
|
||||
if (!DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
|
||||
{
|
||||
@ -1724,24 +1757,6 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
d->DockManager->notifyFloatingWidgetDrop(FloatingWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
|
||||
@ -1752,6 +1767,10 @@ void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea,
|
||||
{
|
||||
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
|
||||
}
|
||||
else if (internal::isSideBarArea(DropArea))
|
||||
{
|
||||
d->moveToAutoHideSideBar(Widget, DropArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->moveToContainer(Widget, DropArea);
|
||||
|
@ -103,6 +103,13 @@ protected:
|
||||
*/
|
||||
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget);
|
||||
|
||||
/**
|
||||
* The funtion does the same like createAndSetupAutoHideContainer() but checks
|
||||
* if the given DockWidget is pinnable. If it is not pinnable, the
|
||||
* function returns a nullptr.
|
||||
*/
|
||||
CAutoHideDockContainer* createAutoHideContainerIfPinnable(SideBarLocation area, CDockWidget* DockWidget);
|
||||
|
||||
/**
|
||||
* Helper function for creation of the root splitter
|
||||
*/
|
||||
|
@ -209,6 +209,11 @@ struct DockOverlayCrossPrivate
|
||||
CDockOverlay::eMode Mode)
|
||||
{
|
||||
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
|
||||
// TODO: remove, this is just for debugging
|
||||
if (Mode == CDockOverlay::ModeContainerOverlay)
|
||||
{
|
||||
borderColor = Qt::red;
|
||||
}
|
||||
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
|
||||
QColor overlayColor = iconColor(CDockOverlayCross::OverlayColor);
|
||||
if (overlayColor.alpha() == 255)
|
||||
@ -426,12 +431,26 @@ CDockOverlay::~CDockOverlay()
|
||||
void CDockOverlay::setAllowedAreas(DockWidgetAreas areas)
|
||||
{
|
||||
if (areas == d->AllowedAreas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->AllowedAreas = areas;
|
||||
d->Cross->reset();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockOverlay::setAllowedArea(DockWidgetArea area, bool Enable)
|
||||
{
|
||||
auto AreasOld = d->AllowedAreas;
|
||||
d->AllowedAreas.setFlag(area, Enable);
|
||||
if (AreasOld != d->AllowedAreas)
|
||||
{
|
||||
d->Cross->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockWidgetAreas CDockOverlay::allowedAreas() const
|
||||
{
|
||||
@ -456,6 +475,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
std::cout << d->Mode << " Find out side bar area " << std::endl;
|
||||
auto Rect = rect();
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
if (pos.x() < d->sideBarMouseZone(SideBarLeft))
|
||||
@ -468,6 +488,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
}
|
||||
else if (pos.y() < d->sideBarMouseZone(SideBarTop))
|
||||
{
|
||||
std::cout << d->Mode << " TopAutoHideArea " << std::endl;
|
||||
return TopAutoHideArea;
|
||||
}
|
||||
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom)))
|
||||
@ -513,12 +534,14 @@ DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
||||
{
|
||||
std::cout << d->Mode << " CDockOverlay::showOverlay()" << target << " " << target->objectName().toStdString() << std::endl;
|
||||
if (d->TargetWidget == target)
|
||||
{
|
||||
// Hint: We could update geometry of overlay here.
|
||||
DockWidgetArea da = dropAreaUnderCursor();
|
||||
if (da != d->LastLocation)
|
||||
{
|
||||
std::cout << d->Mode << " repaint()" << std::endl;
|
||||
repaint();
|
||||
d->LastLocation = da;
|
||||
}
|
||||
@ -543,6 +566,7 @@ DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
||||
//============================================================================
|
||||
void CDockOverlay::hideOverlay()
|
||||
{
|
||||
std::cout << d->Mode << " CDockOverlay::hideOverlay()" << std::endl;
|
||||
hide();
|
||||
d->TargetWidget.clear();
|
||||
d->LastLocation = InvalidDockWidgetArea;
|
||||
@ -554,6 +578,7 @@ void CDockOverlay::hideOverlay()
|
||||
void CDockOverlay::enableDropPreview(bool Enable)
|
||||
{
|
||||
d->DropPreviewEnabled = Enable;
|
||||
std::cout << d->Mode << " update() " << Enable << std::endl;
|
||||
update();
|
||||
}
|
||||
|
||||
@ -581,6 +606,7 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
double Factor = (CDockOverlay::ModeContainerOverlay == d->Mode) ?
|
||||
3 : 2;
|
||||
|
||||
std::cout << "CDockOverlay::paintEvent da: " << da << std::endl;
|
||||
switch (da)
|
||||
{
|
||||
case TopDockWidgetArea: r.setHeight(r.height() / Factor); break;
|
||||
@ -596,6 +622,11 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
QPainter painter(this);
|
||||
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
// TODO: This is just for debugging - remove later
|
||||
if (d->Mode == CDockOverlay::ModeContainerOverlay)
|
||||
{
|
||||
Color = Qt::red;
|
||||
}
|
||||
QPen Pen = painter.pen();
|
||||
Pen.setColor(Color.darker(120));
|
||||
Pen.setStyle(Qt::SolidLine);
|
||||
|
@ -72,6 +72,11 @@ public:
|
||||
*/
|
||||
void setAllowedAreas(DockWidgetAreas areas);
|
||||
|
||||
/**
|
||||
* Enable / disable a certain area
|
||||
*/
|
||||
void setAllowedArea(DockWidgetArea area, bool Enable);
|
||||
|
||||
/**
|
||||
* Returns flags with all allowed drop areas
|
||||
*/
|
||||
|
@ -585,11 +585,19 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
}
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(
|
||||
VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
ContainerOverlay->setAllowedAreas(AllowedAreas);
|
||||
|
||||
DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
|
@ -101,6 +101,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
if (!_this->isVisible() || !DockManager)
|
||||
{
|
||||
std::cout << "return 1" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,20 +127,24 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
DropContainer = TopContainer;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
if (!TopContainer)
|
||||
{
|
||||
std::cout << "ContainerOverlay->hideOverlay() 1" << std::endl;
|
||||
ContainerOverlay->hideOverlay();
|
||||
std::cout << "DockAreaOverlay->hideOverlay() 1" << std::endl;
|
||||
DockAreaOverlay->hideOverlay();
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewIsDynamic))
|
||||
{
|
||||
std::cout << "return 2" << std::endl;
|
||||
setHidden(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
|
||||
// Include the overlay widget we're dragging as a visible widget
|
||||
@ -148,15 +153,25 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
VisibleDockAreas++;
|
||||
}
|
||||
std::cout << "VisibleDockAreas " << VisibleDockAreas << std::endl;
|
||||
|
||||
ContainerOverlay->setAllowedAreas( VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
//ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
ContainerOverlay->setAllowedAreas(AllowedAreas);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas >= 0 && DockArea != ContentSourceArea)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
DockAreaOverlay->setAllowedAreas( (VisibleDockAreas == 1) ? NoDockWidgetArea : DockArea->allowedAreas());
|
||||
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
std::cout << "DockWidgetArea " << Area << std::endl;
|
||||
|
||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
|
||||
// the mouse is in the title bar. If the ContainerArea is valid
|
||||
@ -165,28 +180,30 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
if ((Area == CenterDockWidgetArea) && (ContainerDropArea != InvalidDockWidgetArea))
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(false);
|
||||
|
||||
std::cout << "ContainerOverlay->enableDropPreview(true) 1" << std::endl;
|
||||
ContainerOverlay->enableDropPreview(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ContainerOverlay->enableDropPreview 2" << std::endl;
|
||||
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
|
||||
}
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "DockAreaOverlay->hideOverlay() 2" << std::endl;
|
||||
DockAreaOverlay->hideOverlay();
|
||||
// If there is only one single visible dock area in a container, then
|
||||
// it does not make sense to show a dock overlay because the dock area
|
||||
// would be removed and inserted at the same position
|
||||
// would be removed and inserted at the same position. Only auto hide
|
||||
// area is allowed
|
||||
if (VisibleDockAreas == 1)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->setAllowedAreas(AutoHideDockAreas);
|
||||
}
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
|
||||
|
||||
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
|
||||
|
Loading…
Reference in New Issue
Block a user