mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-01-24 13:32:06 +08:00
Changed FloatingDockContainer to use an internal state machine to improve code clarity and to handle some corner cases on Windows where resizing and moving the floating window to the screen edges caused trouble
This commit is contained in:
parent
ff9d965726
commit
1a47918bdb
@ -66,8 +66,7 @@ struct FloatingDockContainerPrivate
|
|||||||
CDockContainerWidget* DockContainer;
|
CDockContainerWidget* DockContainer;
|
||||||
unsigned int zOrderIndex = ++zOrderCounter;
|
unsigned int zOrderIndex = ++zOrderCounter;
|
||||||
QPointer<CDockManager> DockManager;
|
QPointer<CDockManager> DockManager;
|
||||||
bool DraggingActive = false;
|
eDragState DraggingState = StateInactive;
|
||||||
bool NonClientAreaMouseButtonPress = false;
|
|
||||||
QPoint DragStartMousePosition;
|
QPoint DragStartMousePosition;
|
||||||
CDockContainerWidget* DropContainer = nullptr;
|
CDockContainerWidget* DropContainer = nullptr;
|
||||||
CDockAreaWidget* SingleDockArea = nullptr;
|
CDockAreaWidget* SingleDockArea = nullptr;
|
||||||
@ -79,10 +78,24 @@ struct FloatingDockContainerPrivate
|
|||||||
|
|
||||||
void titleMouseReleaseEvent();
|
void titleMouseReleaseEvent();
|
||||||
void updateDropOverlays(const QPoint& GlobalPos);
|
void updateDropOverlays(const QPoint& GlobalPos);
|
||||||
void setDraggingActive(bool Active);
|
|
||||||
|
/**
|
||||||
|
* Tests is a certain state is active
|
||||||
|
*/
|
||||||
|
bool isState(eDragState StateId) const
|
||||||
|
{
|
||||||
|
return StateId == DraggingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setState(eDragState StateId)
|
||||||
|
{
|
||||||
|
DraggingState = StateId;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// struct FloatingDockContainerPrivate
|
// struct FloatingDockContainerPrivate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContainer* _public) :
|
FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContainer* _public) :
|
||||||
_this(_public)
|
_this(_public)
|
||||||
@ -95,7 +108,7 @@ FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContaine
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||||
{
|
{
|
||||||
setDraggingActive(false);
|
setState(StateInactive);
|
||||||
if (!DropContainer)
|
if (!DropContainer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -202,18 +215,6 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void FloatingDockContainerPrivate::setDraggingActive(bool Active)
|
|
||||||
{
|
|
||||||
qDebug() << "FloatingDockContainerPrivate::setDraggingActive " << Active;
|
|
||||||
DraggingActive = Active;
|
|
||||||
if (!DraggingActive)
|
|
||||||
{
|
|
||||||
NonClientAreaMouseButtonPress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
||||||
QWidget(DockManager, Qt::Window),
|
QWidget(DockManager, Qt::Window),
|
||||||
@ -289,18 +290,18 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
|
|||||||
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::moveEvent(event);
|
QWidget::moveEvent(event);
|
||||||
if (!qApp->mouseButtons().testFlag(Qt::LeftButton))
|
switch (d->DraggingState)
|
||||||
{
|
|
||||||
if (d->DraggingActive)
|
|
||||||
{
|
|
||||||
d->setDraggingActive(false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->DraggingActive)
|
|
||||||
{
|
{
|
||||||
|
case StateMousePressed:
|
||||||
|
d->setState(StateDraggingActive);
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StateDraggingActive:
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,12 +310,16 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
qDebug() << "CFloatingDockContainer closeEvent";
|
qDebug() << "CFloatingDockContainer closeEvent";
|
||||||
d->setDraggingActive(false);
|
d->setState(StateInactive);
|
||||||
|
|
||||||
if (isClosable())
|
if (isClosable())
|
||||||
|
{
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -354,31 +359,45 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
bool CFloatingDockContainer::event(QEvent *e)
|
bool CFloatingDockContainer::event(QEvent *e)
|
||||||
{
|
{
|
||||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress)
|
switch (d->DraggingState)
|
||||||
{
|
{
|
||||||
if (QGuiApplication::mouseButtons() == Qt::LeftButton)
|
case StateInactive:
|
||||||
|
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
|
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
|
||||||
d->NonClientAreaMouseButtonPress = true;
|
d->setState(StateMousePressed);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (e->type() == QEvent::NonClientAreaMouseButtonDblClick)
|
|
||||||
|
case StateMousePressed:
|
||||||
|
switch (e->type())
|
||||||
{
|
{
|
||||||
|
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
|
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
|
||||||
d->setDraggingActive(false);
|
d->setState(StateInactive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QEvent::Resize:
|
||||||
|
// If the first event after the mouse press is a resize event, then
|
||||||
|
// the user resizes the window instead of dragging it around
|
||||||
|
d->setState(StateInactive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if ((e->type() == QEvent::NonClientAreaMouseButtonRelease) && d->DraggingActive)
|
break;
|
||||||
|
|
||||||
|
case StateDraggingActive:
|
||||||
|
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
|
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
|
||||||
d->titleMouseReleaseEvent();
|
d->titleMouseReleaseEvent();
|
||||||
}
|
}
|
||||||
else if (!d->DraggingActive && d->NonClientAreaMouseButtonPress && (e->type() == QEvent::Resize))
|
break;
|
||||||
{
|
|
||||||
d->NonClientAreaMouseButtonPress = false;
|
default:
|
||||||
}
|
break;
|
||||||
else if (!d->DraggingActive && d->NonClientAreaMouseButtonPress && (e->type() == QEvent::Move))
|
|
||||||
{
|
|
||||||
d->setDraggingActive(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "CFloatingDockContainer::event " << e->type();
|
qDebug() << "CFloatingDockContainer::event " << e->type();
|
||||||
@ -390,7 +409,7 @@ bool CFloatingDockContainer::event(QEvent *e)
|
|||||||
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(watched);
|
Q_UNUSED(watched);
|
||||||
if (event->type() == QEvent::MouseButtonRelease && d->DraggingActive)
|
if (event->type() == QEvent::MouseButtonRelease && d->isState(StateDraggingActive))
|
||||||
{
|
{
|
||||||
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
|
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
|
||||||
d->titleMouseReleaseEvent();
|
d->titleMouseReleaseEvent();
|
||||||
@ -404,7 +423,7 @@ bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
|||||||
void CFloatingDockContainer::startFloating(const QPoint& Pos, const QSize& Size)
|
void CFloatingDockContainer::startFloating(const QPoint& Pos, const QSize& Size)
|
||||||
{
|
{
|
||||||
resize(Size);
|
resize(Size);
|
||||||
d->setDraggingActive(true);
|
d->setState(StateDraggingActive);
|
||||||
QPoint TargetPos = QCursor::pos() - Pos;
|
QPoint TargetPos = QCursor::pos() - Pos;
|
||||||
move(TargetPos);
|
move(TargetPos);
|
||||||
show();
|
show();
|
||||||
|
Loading…
Reference in New Issue
Block a user