1
0
mirror of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git synced 2025-03-16 02:59:51 +08:00

Moved title bar dragging code from DockAreaTabBar into DockAreaTitleBar

This commit is contained in:
Uwe Kindler 2020-02-07 12:16:26 +01:00
parent ae72f5e47d
commit b61f50982a
6 changed files with 194 additions and 200 deletions

View File

@ -54,13 +54,10 @@ namespace ads
struct DockAreaTabBarPrivate struct DockAreaTabBarPrivate
{ {
CDockAreaTabBar* _this; CDockAreaTabBar* _this;
QPoint DragStartMousePos;
CDockAreaWidget* DockArea; CDockAreaWidget* DockArea;
IFloatingWidget* FloatingWidget = nullptr;
QWidget* TabsContainerWidget; QWidget* TabsContainerWidget;
QBoxLayout* TabsLayout; QBoxLayout* TabsLayout;
int CurrentIndex = -1; int CurrentIndex = -1;
eDragState DragState = DraggingInactive;
/** /**
* Private data constructor * Private data constructor
@ -72,14 +69,6 @@ struct DockAreaTabBarPrivate
* The function reassigns the stylesheet to update the tabs * The function reassigns the stylesheet to update the tabs
*/ */
void updateTabs(); void updateTabs();
/**
* Test function for current drag state
*/
bool isDraggingState(eDragState dragState) const
{
return this->DragState == dragState;
}
}; };
// struct DockAreaTabBarPrivate // struct DockAreaTabBarPrivate
@ -164,149 +153,6 @@ void CDockAreaTabBar::wheelEvent(QWheelEvent* Event)
} }
//============================================================================
void CDockAreaTabBar::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->DragStartMousePos = ev->pos();
d->DragState = DraggingMousePressed;
return;
}
Super::mousePressEvent(ev);
}
//============================================================================
void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ADS_PRINT("CDockAreaTabBar::mouseReleaseEvent");
ev->accept();
auto CurrentDragState = d->DragState;
d->DragStartMousePos = QPoint();
d->DragState = DraggingInactive;
if (DraggingFloatingWidget == CurrentDragState)
{
d->FloatingWidget->finishDragging();
}
return;
}
Super::mouseReleaseEvent(ev);
}
//============================================================================
void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev)
{
Super::mouseMoveEvent(ev);
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
return;
}
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating()
&& d->DockArea->dockContainer()->visibleDockAreaCount() == 1)
{
return;
}
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance())
{
ADS_PRINT("CTabsScrollArea::startFloating");
startFloating(d->DragStartMousePos);
auto Overlay = d->DockArea->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
}
return;
}
//============================================================================
void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
{
return;
}
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
makeAreaFloating(event->pos(), DraggingInactive);
}
//============================================================================
IFloatingWidget* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset, eDragState DragState)
{
QSize Size = d->DockArea->size();
d->DragState = DragState;
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DragState);
CFloatingDockContainer* FloatingDockContainer = nullptr;
IFloatingWidget* FloatingWidget;
if (OpaqueUndocking)
{
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(d->DockArea);
}
else
{
auto w = new CFloatingDragPreview(d->DockArea);
connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
{
d->DragState = DraggingInactive;
});
FloatingWidget = w;
}
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
if (FloatingDockContainer)
{
auto TopLevelDockWidget = FloatingDockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
}
return FloatingWidget;
}
//============================================================================
void CDockAreaTabBar::startFloating(const QPoint& Offset)
{
d->FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
}
//============================================================================ //============================================================================
void CDockAreaTabBar::setCurrentIndex(int index) void CDockAreaTabBar::setCurrentIndex(int index)
{ {
@ -625,7 +471,6 @@ bool CDockAreaTabBar::isTabOpen(int Index) const
QSize CDockAreaTabBar::minimumSizeHint() const QSize CDockAreaTabBar::minimumSizeHint() const
{ {
QSize Size = sizeHint(); QSize Size = sizeHint();
//Size.setWidth(Super::minimumSizeHint().width());// this defines the minimum width of a dock area
Size.setWidth(10); Size.setWidth(10);
return Size; return Size;
} }
@ -637,13 +482,6 @@ QSize CDockAreaTabBar::sizeHint() const
return d->TabsContainerWidget->sizeHint(); return d->TabsContainerWidget->sizeHint();
} }
//===========================================================================
eDragState CDockAreaTabBar::dragState() const
{
return d->DragState;
}
} // namespace ads } // namespace ads

View File

@ -67,42 +67,6 @@ private slots:
protected: protected:
virtual void wheelEvent(QWheelEvent* Event) override; virtual void wheelEvent(QWheelEvent* Event) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mousePressEvent(QMouseEvent* ev) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
/**
* Starts floating the complete docking area including all dock widgets,
* if it is not the last dock area in a floating widget
*/
virtual void mouseMoveEvent(QMouseEvent* ev) override;
/**
* Double clicking the title bar also starts floating of the complete area
*/
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
/**
* Starts floating
*/
void startFloating(const QPoint& Offset);
/**
* Makes the dock area floating
*/
IFloatingWidget* makeAreaFloating(const QPoint& Offset, eDragState DragState);
/**
* Returns the current drag state
*/
eDragState dragState() const;
public: public:
using Super = QScrollArea; using Super = QScrollArea;

View File

@ -41,6 +41,7 @@
#include "ads_globals.h" #include "ads_globals.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "FloatingDragPreview.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockOverlay.h" #include "DockOverlay.h"
#include "DockManager.h" #include "DockManager.h"
@ -72,6 +73,11 @@ struct DockAreaTitleBarPrivate
QMenu* TabsMenu; QMenu* TabsMenu;
QList<tTitleBarButton*> DockWidgetActionsButtons; QList<tTitleBarButton*> DockWidgetActionsButtons;
QPoint DragStartMousePos;
eDragState DragState = DraggingInactive;
IFloatingWidget* FloatingWidget = nullptr;
/** /**
* Private data constructor * Private data constructor
*/ */
@ -102,6 +108,25 @@ struct DockAreaTitleBarPrivate
{ {
return CDockManager::configFlags().testFlag(Flag); return CDockManager::configFlags().testFlag(Flag);
} }
/**
* Test function for current drag state
*/
bool isDraggingState(eDragState dragState) const
{
return this->DragState == dragState;
}
/**
* Starts floating
*/
void startFloating(const QPoint& Offset);
/**
* Makes the dock area floating
*/
IFloatingWidget* makeAreaFloating(const QPoint& Offset, eDragState DragState);
};// struct DockAreaTitleBarPrivate };// struct DockAreaTitleBarPrivate
@ -241,6 +266,50 @@ void DockAreaTitleBarPrivate::createTabBar()
} }
//============================================================================
IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset, eDragState DragState)
{
QSize Size = DockArea->size();
this->DragState = DragState;
bool OpaqueUndocking = CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking) ||
(DraggingFloatingWidget != DragState);
CFloatingDockContainer* FloatingDockContainer = nullptr;
IFloatingWidget* FloatingWidget;
if (OpaqueUndocking)
{
FloatingWidget = FloatingDockContainer = new CFloatingDockContainer(DockArea);
}
else
{
auto w = new CFloatingDragPreview(DockArea);
QObject::connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
{
this->DragState = DraggingInactive;
});
FloatingWidget = w;
}
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
if (FloatingDockContainer)
{
auto TopLevelDockWidget = FloatingDockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
}
return FloatingWidget;
}
//============================================================================
void DockAreaTitleBarPrivate::startFloating(const QPoint& Offset)
{
FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
}
//============================================================================ //============================================================================
CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) : CDockAreaTitleBar::CDockAreaTitleBar(CDockAreaWidget* parent) :
QFrame(parent), QFrame(parent),
@ -362,7 +431,7 @@ void CDockAreaTitleBar::onUndockButtonClicked()
{ {
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)) if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive); d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
} }
} }
@ -453,7 +522,7 @@ void CDockAreaTitleBar::setVisible(bool Visible)
//============================================================================ //============================================================================
void CDockAreaTitleBar::showContextMenu(const QPoint& pos) void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
{ {
if (d->TabBar->dragState() == DraggingFloatingWidget) if (d->DragState == DraggingFloatingWidget)
{ {
return; return;
} }
@ -469,6 +538,105 @@ void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
} }
//============================================================================
void CDockAreaTitleBar::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->DragStartMousePos = ev->pos();
d->DragState = DraggingMousePressed;
return;
}
Super::mousePressEvent(ev);
}
//============================================================================
void CDockAreaTitleBar::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ADS_PRINT("CDockAreaTitleBar::mouseReleaseEvent");
ev->accept();
auto CurrentDragState = d->DragState;
d->DragStartMousePos = QPoint();
d->DragState = DraggingInactive;
if (DraggingFloatingWidget == CurrentDragState)
{
d->FloatingWidget->finishDragging();
}
return;
}
Super::mouseReleaseEvent(ev);
}
//============================================================================
void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
{
Super::mouseMoveEvent(ev);
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
{
d->DragState = DraggingInactive;
return;
}
// move floating window
if (d->isDraggingState(DraggingFloatingWidget))
{
d->FloatingWidget->moveFloating();
return;
}
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating()
&& d->DockArea->dockContainer()->visibleDockAreaCount() == 1)
{
return;
}
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance())
{
ADS_PRINT("CTabsScrollArea::startFloating");
d->startFloating(d->DragStartMousePos);
auto Overlay = d->DockArea->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
}
return;
}
//============================================================================
void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
{
return;
}
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
d->makeAreaFloating(event->pos(), DraggingInactive);
}
} // namespace ads } // namespace ads
#include "DockAreaTitleBar.moc" #include "DockAreaTitleBar.moc"

View File

@ -62,6 +62,28 @@ private slots:
void onCurrentTabChanged(int Index); void onCurrentTabChanged(int Index);
void showContextMenu(const QPoint& pos); void showContextMenu(const QPoint& pos);
protected:
/**
* Stores mouse position to detect dragging
*/
virtual void mousePressEvent(QMouseEvent* ev) override;
/**
* Stores mouse position to detect dragging
*/
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
/**
* Starts floating the complete docking area including all dock widgets,
* if it is not the last dock area in a floating widget
*/
virtual void mouseMoveEvent(QMouseEvent* ev) override;
/**
* Double clicking the title bar also starts floating of the complete area
*/
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
public slots: public slots:
/** /**
* Call this slot to tell the title bar that it should update the tabs menu * Call this slot to tell the title bar that it should update the tabs menu

View File

@ -88,6 +88,7 @@ private:
friend struct DockWidgetTabPrivate; friend struct DockWidgetTabPrivate;
friend class CFloatingDragPreview; friend class CFloatingDragPreview;
friend struct FloatingDragPreviewPrivate; friend struct FloatingDragPreviewPrivate;
friend class CDockAreaTitleBar;
protected: protected:
/** /**

View File

@ -74,6 +74,7 @@ protected:
friend class CDockAreaTabBar; friend class CDockAreaTabBar;
friend class CDockWidgetTab; friend class CDockWidgetTab;
friend struct DockWidgetTabPrivate; friend struct DockWidgetTabPrivate;
friend struct DockAreaTitleBarPrivate;
/** /**
* Assigns the dock manager that manages this dock widget * Assigns the dock manager that manages this dock widget