mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 13:15:43 +08:00
fix #17 - get rid of static drop overlay
- holds one instance of DropOverlay for each ContainerWidget.
This commit is contained in:
parent
823028c6aa
commit
5041f5076a
@ -18,6 +18,7 @@ class QGridLayout;
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class SectionWidget;
|
||||
class DropOverlay;
|
||||
class InternalContentData;
|
||||
|
||||
|
||||
@ -178,6 +179,9 @@ private:
|
||||
Qt::Orientation _orientation;
|
||||
QPointer<QSplitter> _splitter; // $mfreiholz: I'd like to remove this variable entirely,
|
||||
// because it changes during user interaction anyway.
|
||||
|
||||
// Drop overlay stuff.
|
||||
QPointer<DropOverlay> _dropOverlay;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef DROP_OVERLAY_H
|
||||
#define DROP_OVERLAY_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QRect>
|
||||
#include <QFrame>
|
||||
|
||||
@ -16,11 +17,17 @@ class DropOverlay : public QFrame
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DropOverlay(DropAreas areas, QWidget* parent);
|
||||
DropOverlay(QWidget* parent);
|
||||
virtual ~DropOverlay();
|
||||
|
||||
void setDropAreas(DropAreas areas);
|
||||
void setFullAreaDropEnabled(bool enabled) { _fullAreaDrop = enabled; }
|
||||
DropArea cursorLocation() const;
|
||||
|
||||
DropArea showDropOverlay(QWidget* target, DropAreas areas = AllAreas);
|
||||
void showDropOverlay(QWidget* target, const QRect& targetAreaRect, DropAreas areas = AllAreas);
|
||||
void hideDropOverlay();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *e);
|
||||
virtual void resizeEvent(QResizeEvent* e);
|
||||
@ -29,24 +36,20 @@ protected:
|
||||
private:
|
||||
DropSplitAreas* _splitAreas;
|
||||
bool _fullAreaDrop;
|
||||
};
|
||||
|
||||
// AbstractDropAreas is used as base for drop area indicator widgets.
|
||||
class AbstractDropAreas : public QWidget
|
||||
{
|
||||
public:
|
||||
AbstractDropAreas(QWidget* parent) : QWidget(parent) {}
|
||||
virtual DropArea cursorLocation() const = 0;
|
||||
QPointer<QWidget> _target;
|
||||
QRect _targetRect;
|
||||
DropArea _lastLocation;
|
||||
};
|
||||
|
||||
// DropSplitAreas shows a cross with 5 different drop area possibilities.
|
||||
class DropSplitAreas : public AbstractDropAreas
|
||||
class DropSplitAreas : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DropSplitAreas(DropAreas areas, QWidget* parent);
|
||||
virtual DropArea cursorLocation() const;
|
||||
DropArea cursorLocation() const;
|
||||
|
||||
private:
|
||||
QWidget* _top;
|
||||
@ -56,11 +59,5 @@ private:
|
||||
QWidget* _center;
|
||||
};
|
||||
|
||||
|
||||
DropArea showDropOverlay(QWidget* parent, DropAreas areas = AllAreas);
|
||||
void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas = AllAreas);
|
||||
void hideDropOverlay();
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "ads/SectionWidget.h"
|
||||
#include "ads/SectionTitleWidget.h"
|
||||
#include "ads/SectionContentWidget.h"
|
||||
#include "ads/DropOverlay.h"
|
||||
#include "ads/Serialization.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
@ -36,7 +37,8 @@ ContainerWidget::ContainerWidget(QWidget *parent) :
|
||||
QFrame(parent),
|
||||
_mainLayout(NULL),
|
||||
_orientation(Qt::Horizontal),
|
||||
_splitter(NULL)
|
||||
_splitter(NULL),
|
||||
_dropOverlay(new DropOverlay(this))
|
||||
{
|
||||
_mainLayout = new QGridLayout();
|
||||
_mainLayout->setContentsMargins(9, 9, 9, 9);
|
||||
|
@ -24,24 +24,21 @@ static QWidget* createDropWidget(const QString& img)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
DropOverlay::DropOverlay(DropAreas areas, QWidget *parent) :
|
||||
DropOverlay::DropOverlay(QWidget* parent) :
|
||||
QFrame(parent),
|
||||
_splitAreas(NULL),
|
||||
_fullAreaDrop(false)
|
||||
_fullAreaDrop(false),
|
||||
_lastLocation(InvalidDropArea)
|
||||
{
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowOpacity(0.2);
|
||||
setWindowTitle("DropOverlay");
|
||||
setVisible(false);
|
||||
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
|
||||
_splitAreas = new DropSplitAreas(areas, parent);
|
||||
_splitAreas->move(pos());
|
||||
_splitAreas->resize(size());
|
||||
_splitAreas->setVisible(true);
|
||||
}
|
||||
|
||||
DropOverlay::~DropOverlay()
|
||||
@ -53,6 +50,19 @@ DropOverlay::~DropOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
void DropOverlay::setDropAreas(DropAreas areas)
|
||||
{
|
||||
if (_splitAreas)
|
||||
{
|
||||
delete _splitAreas;
|
||||
_splitAreas = NULL;
|
||||
}
|
||||
_splitAreas = new DropSplitAreas(areas, parentWidget());
|
||||
_splitAreas->move(pos());
|
||||
_splitAreas->resize(size());
|
||||
_splitAreas->setVisible(false);
|
||||
}
|
||||
|
||||
DropArea DropOverlay::cursorLocation() const
|
||||
{
|
||||
DropArea loc = InvalidDropArea;
|
||||
@ -63,6 +73,71 @@ DropArea DropOverlay::cursorLocation() const
|
||||
return loc;
|
||||
}
|
||||
|
||||
DropArea DropOverlay::showDropOverlay(QWidget* target, DropAreas areas)
|
||||
{
|
||||
if (_target == target)
|
||||
{
|
||||
// Hint: We could update geometry of overlay here.
|
||||
DropArea da = cursorLocation();
|
||||
if (da != _lastLocation)
|
||||
{
|
||||
repaint();
|
||||
_lastLocation = da;
|
||||
}
|
||||
return da;
|
||||
}
|
||||
hideDropOverlay();
|
||||
|
||||
// Move directly over the "parent" widget.
|
||||
setDropAreas(areas);
|
||||
setFullAreaDropEnabled(false);
|
||||
resize(target->size());
|
||||
move(target->mapToGlobal(target->rect().topLeft()));
|
||||
show();
|
||||
_splitAreas->show();
|
||||
_target = target;
|
||||
return cursorLocation();
|
||||
}
|
||||
|
||||
void DropOverlay::showDropOverlay(QWidget* target, const QRect& targetAreaRect, DropAreas areas)
|
||||
{
|
||||
if (_target == target && _targetRect == targetAreaRect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hideDropOverlay();
|
||||
|
||||
// Create overlay and move it to the parent's areaRect
|
||||
// MyOverlay = new DropOverlay(areas, parent);
|
||||
setDropAreas(areas);
|
||||
setFullAreaDropEnabled(true);
|
||||
resize(targetAreaRect.size());
|
||||
move(target->mapToGlobal(QPoint(targetAreaRect.x(), targetAreaRect.y())));
|
||||
show();
|
||||
_splitAreas->show();
|
||||
_target = target;
|
||||
_targetRect = targetAreaRect;
|
||||
return;
|
||||
}
|
||||
|
||||
void DropOverlay::hideDropOverlay()
|
||||
{
|
||||
hide();
|
||||
if (_splitAreas)
|
||||
{
|
||||
_splitAreas->hide();
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_target.clear();
|
||||
#else
|
||||
_target = 0;
|
||||
#endif
|
||||
|
||||
_targetRect = QRect();
|
||||
_lastLocation = InvalidDropArea;
|
||||
}
|
||||
|
||||
void DropOverlay::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter p(this);
|
||||
@ -138,7 +213,7 @@ void DropOverlay::moveEvent(QMoveEvent* e)
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
DropSplitAreas::DropSplitAreas(DropAreas areas, QWidget* parent) :
|
||||
AbstractDropAreas(parent),
|
||||
QWidget(parent),
|
||||
_top(0),
|
||||
_right(0),
|
||||
_bottom(0),
|
||||
@ -147,7 +222,6 @@ DropSplitAreas::DropSplitAreas(DropAreas areas, QWidget* parent) :
|
||||
{
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowTitle("DropSplitAreas");
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
QGridLayout* grid = new QGridLayout();
|
||||
@ -224,76 +298,4 @@ DropArea DropSplitAreas::cursorLocation() const
|
||||
return loc;
|
||||
}
|
||||
|
||||
// Globals ////////////////////////////////////////////////////////////
|
||||
|
||||
static QPointer<DropOverlay> MyOverlay;
|
||||
static QPointer<QWidget> MyOverlayParent;
|
||||
static QRect MyOverlayParentRect;
|
||||
static DropArea MyOverlayLastLocation = InvalidDropArea;
|
||||
|
||||
DropArea showDropOverlay(QWidget* parent, DropAreas areas)
|
||||
{
|
||||
if (MyOverlay)
|
||||
{
|
||||
if (MyOverlayParent == parent)
|
||||
{
|
||||
// Hint: We could update geometry of overlay here.
|
||||
DropArea da = MyOverlay->cursorLocation();
|
||||
if (da != MyOverlayLastLocation)
|
||||
{
|
||||
MyOverlay->repaint();
|
||||
MyOverlayLastLocation = da;
|
||||
}
|
||||
return da;
|
||||
}
|
||||
hideDropOverlay();
|
||||
}
|
||||
|
||||
// Create new overlay and move it directly over the "parent" widget.
|
||||
MyOverlay = new DropOverlay(areas, parent);
|
||||
MyOverlay->resize(parent->size());
|
||||
MyOverlay->move(parent->mapToGlobal(parent->rect().topLeft()));
|
||||
MyOverlay->show();
|
||||
MyOverlayParent = parent;
|
||||
return MyOverlay->cursorLocation();
|
||||
}
|
||||
|
||||
void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas)
|
||||
{
|
||||
if (MyOverlay)
|
||||
{
|
||||
if (MyOverlayParent == parent && MyOverlayParentRect == areaRect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hideDropOverlay();
|
||||
}
|
||||
|
||||
// Create overlay and move it to the parent's areaRect
|
||||
MyOverlay = new DropOverlay(areas, parent);
|
||||
MyOverlay->setFullAreaDropEnabled(true);
|
||||
MyOverlay->resize(areaRect.size());
|
||||
MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y())));
|
||||
MyOverlay->show();
|
||||
MyOverlayParent = parent;
|
||||
MyOverlayParentRect = areaRect;
|
||||
return;
|
||||
}
|
||||
|
||||
void hideDropOverlay()
|
||||
{
|
||||
if (MyOverlay)
|
||||
{
|
||||
MyOverlay->hide();
|
||||
delete MyOverlay;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
MyOverlayParent.clear();
|
||||
#else
|
||||
MyOverlayParent = 0;
|
||||
#endif
|
||||
MyOverlayParentRect = QRect();
|
||||
MyOverlayLastLocation = InvalidDropArea;
|
||||
}
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
|
@ -75,15 +75,15 @@ void SectionTitleWidget::mousePressEvent(QMouseEvent* ev)
|
||||
void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
SectionWidget* section = NULL;
|
||||
ContainerWidget* cw = findParentContainerWidget(this);
|
||||
|
||||
// Drop contents of FloatingWidget into SectionWidget.
|
||||
if (_fw)
|
||||
{
|
||||
ContainerWidget* cw = findParentContainerWidget(this);
|
||||
SectionWidget* sw = cw->sectionAt(cw->mapFromGlobal(ev->globalPos()));
|
||||
if (sw)
|
||||
{
|
||||
DropArea loc = showDropOverlay(sw);
|
||||
DropArea loc = cw->_dropOverlay->showDropOverlay(sw);
|
||||
if (loc != InvalidDropArea)
|
||||
{
|
||||
#if !defined(ADS_ANIMATIONS_ENABLED)
|
||||
@ -170,7 +170,7 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
// Reset
|
||||
_dragStartPos = QPoint();
|
||||
_tabMoving = false;
|
||||
hideDropOverlay();
|
||||
cw->_dropOverlay->hideDropOverlay();
|
||||
QFrame::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
@ -194,29 +194,29 @@ void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev)
|
||||
section = cw->sectionAt(cw->mapFromGlobal(QCursor::pos()));
|
||||
if (section)
|
||||
{
|
||||
showDropOverlay(section);
|
||||
cw->_dropOverlay->showDropOverlay(section);
|
||||
}
|
||||
// Mouse is at the edge of the ContainerWidget
|
||||
// Top, Right, Bottom, Left
|
||||
else if (cw->outerTopDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
showDropOverlay(cw, cw->outerTopDropRect(), ADS_NS::TopDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerTopDropRect(), ADS_NS::TopDropArea);
|
||||
}
|
||||
else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
showDropOverlay(cw, cw->outerRightDropRect(), ADS_NS::RightDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerRightDropRect(), ADS_NS::RightDropArea);
|
||||
}
|
||||
else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
showDropOverlay(cw, cw->outerBottomDropRect(), ADS_NS::BottomDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerBottomDropRect(), ADS_NS::BottomDropArea);
|
||||
}
|
||||
else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
showDropOverlay(cw, cw->outerLeftDropRect(), ADS_NS::LeftDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerLeftDropRect(), ADS_NS::LeftDropArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
hideDropOverlay();
|
||||
cw->_dropOverlay->hideDropOverlay();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user