2016-02-02 22:01:48 +08:00
|
|
|
#include "ads/DropOverlay.h"
|
2015-12-09 19:21:38 +08:00
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QPointer>
|
|
|
|
#include <QPaintEvent>
|
|
|
|
#include <QResizeEvent>
|
|
|
|
#include <QMoveEvent>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QGridLayout>
|
|
|
|
#include <QCursor>
|
|
|
|
#include <QtGui/QIcon>
|
|
|
|
#include <QtWidgets/QLabel>
|
|
|
|
|
|
|
|
ADS_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
// Helper /////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static QWidget* createDropWidget(const QString& img)
|
|
|
|
{
|
|
|
|
auto label = new QLabel();
|
|
|
|
label->setObjectName("DropAreaLabel");
|
|
|
|
label->setPixmap(QPixmap(img));
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
DropOverlay::DropOverlay(DropAreas areas, QWidget *parent) :
|
2015-12-09 19:21:38 +08:00
|
|
|
QFrame(parent),
|
2016-02-03 17:50:34 +08:00
|
|
|
_splitAreas(NULL),
|
|
|
|
_fullAreaDrop(false)
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
2016-02-02 20:49:10 +08:00
|
|
|
//setAttribute(Qt::WA_TransparentForMouseEvents);
|
2015-12-09 19:21:38 +08:00
|
|
|
setWindowFlags(windowFlags() | Qt::Tool);
|
|
|
|
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
|
|
|
setWindowOpacity(0.2);
|
|
|
|
|
2016-02-02 20:49:10 +08:00
|
|
|
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
2015-12-09 19:21:38 +08:00
|
|
|
l->setContentsMargins(0, 0, 0, 0);
|
|
|
|
l->setSpacing(0);
|
|
|
|
setLayout(l);
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
_splitAreas = new DropSplitAreas(areas, parent);
|
2015-12-09 19:21:38 +08:00
|
|
|
_splitAreas->move(pos());
|
|
|
|
_splitAreas->resize(size());
|
|
|
|
_splitAreas->setVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
DropOverlay::~DropOverlay()
|
|
|
|
{
|
|
|
|
if (_splitAreas)
|
|
|
|
{
|
|
|
|
delete _splitAreas;
|
|
|
|
_splitAreas = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DropArea DropOverlay::cursorLocation() const
|
|
|
|
{
|
|
|
|
auto loc = InvalidDropArea;
|
|
|
|
if (_splitAreas)
|
|
|
|
{
|
|
|
|
loc = _splitAreas->cursorLocation();
|
|
|
|
}
|
|
|
|
return loc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropOverlay::paintEvent(QPaintEvent*)
|
|
|
|
{
|
|
|
|
QPainter p(this);
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
// Always draw drop-rect over the entire rect()
|
|
|
|
if (_fullAreaDrop)
|
|
|
|
{
|
|
|
|
QRect r = rect();
|
|
|
|
p.fillRect(r, QBrush(QColor(0, 100, 255), Qt::Dense4Pattern));
|
|
|
|
p.setBrush(QBrush(QColor(0, 100, 255)));
|
|
|
|
p.drawRect(r);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-02 20:49:10 +08:00
|
|
|
// Draw rect based on location
|
|
|
|
QRect r = rect();
|
|
|
|
const DropArea da = cursorLocation();
|
|
|
|
switch (da)
|
|
|
|
{
|
|
|
|
case DropArea::TopDropArea:
|
|
|
|
r.setHeight(r.height() / 2);
|
|
|
|
break;
|
|
|
|
case DropArea::RightDropArea:
|
|
|
|
r.setX(r.width() / 2);
|
|
|
|
break;
|
|
|
|
case DropArea::BottomDropArea:
|
|
|
|
r.setY(r.height() / 2);
|
|
|
|
break;
|
|
|
|
case DropArea::LeftDropArea:
|
|
|
|
r.setWidth(r.width() / 2);
|
|
|
|
break;
|
|
|
|
case DropArea::CenterDropArea:
|
|
|
|
r = rect();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r = QRect();
|
|
|
|
}
|
|
|
|
if (!r.isNull())
|
|
|
|
{
|
|
|
|
p.fillRect(r, QBrush(QColor(0, 100, 255), Qt::Dense4Pattern));
|
|
|
|
p.setBrush(QBrush(QColor(0, 100, 255)));
|
|
|
|
p.drawRect(r);
|
|
|
|
}
|
|
|
|
|
2015-12-09 19:21:38 +08:00
|
|
|
// Draw rect over the entire size + border.
|
2016-02-02 20:49:10 +08:00
|
|
|
// auto r = rect();
|
|
|
|
// r.setWidth(r.width() - 1);
|
|
|
|
// r.setHeight(r.height() - 1);
|
2015-12-09 19:21:38 +08:00
|
|
|
|
2016-02-02 20:49:10 +08:00
|
|
|
// p.fillRect(r, QBrush(QColor(0, 100, 255), Qt::Dense4Pattern));
|
|
|
|
// p.setBrush(QBrush(QColor(0, 100, 255)));
|
|
|
|
// p.drawRect(r);
|
2015-12-09 19:21:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void DropOverlay::resizeEvent(QResizeEvent* e)
|
|
|
|
{
|
|
|
|
// Keep it in center of DropOverlay
|
|
|
|
if (_splitAreas)
|
|
|
|
{
|
|
|
|
_splitAreas->resize(e->size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropOverlay::moveEvent(QMoveEvent* e)
|
|
|
|
{
|
|
|
|
// Keep it in center of DropOverlay
|
|
|
|
if (_splitAreas)
|
|
|
|
{
|
|
|
|
_splitAreas->move(e->pos());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
DropSplitAreas::DropSplitAreas(DropAreas areas, QWidget* parent) :
|
|
|
|
AbstractDropAreas(parent),
|
|
|
|
_top(0),
|
|
|
|
_right(0),
|
|
|
|
_bottom(0),
|
|
|
|
_left(0),
|
|
|
|
_center(0)
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
//setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
|
|
setAttribute(Qt::WA_TranslucentBackground);
|
|
|
|
setWindowFlags(windowFlags() | Qt::Tool);
|
|
|
|
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
|
|
|
|
|
|
|
QGridLayout* grid = new QGridLayout();
|
|
|
|
grid->setContentsMargins(0, 0, 0, 0);
|
|
|
|
grid->setSpacing(6);
|
2016-02-03 17:50:34 +08:00
|
|
|
|
|
|
|
if (areas.testFlag(DropArea::TopDropArea))
|
|
|
|
{
|
|
|
|
_top = createDropWidget(":/img/split-top.png");
|
|
|
|
grid->addWidget(_top, 0, 1, Qt::AlignHCenter | Qt::AlignBottom);
|
|
|
|
}
|
|
|
|
if (areas.testFlag(DropArea::RightDropArea))
|
|
|
|
{
|
|
|
|
_right = createDropWidget(":/img/split-right.png");
|
|
|
|
grid->addWidget(_right, 1, 2, Qt::AlignLeft | Qt::AlignVCenter);
|
|
|
|
}
|
|
|
|
if (areas.testFlag(DropArea::BottomDropArea))
|
|
|
|
{
|
|
|
|
_bottom = createDropWidget(":/img/split-bottom.png");
|
|
|
|
grid->addWidget(_bottom, 2, 1, Qt::AlignHCenter | Qt::AlignTop);
|
|
|
|
}
|
|
|
|
if (areas.testFlag(DropArea::LeftDropArea))
|
|
|
|
{
|
|
|
|
_left = createDropWidget(":/img/split-left.png");
|
|
|
|
grid->addWidget(_left, 1, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
}
|
|
|
|
if (areas.testFlag(DropArea::CenterDropArea))
|
|
|
|
{
|
|
|
|
_center = createDropWidget(":/img/dock-center.png");
|
|
|
|
grid->addWidget(_center, 1, 1, Qt::AlignCenter);
|
|
|
|
}
|
2015-12-09 19:21:38 +08:00
|
|
|
|
|
|
|
QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom);
|
|
|
|
bl1->setContentsMargins(0, 0, 0, 0);
|
|
|
|
bl1->setSpacing(0);
|
|
|
|
setLayout(bl1);
|
|
|
|
|
|
|
|
QBoxLayout* bl2 = new QBoxLayout(QBoxLayout::LeftToRight);
|
|
|
|
bl2->setContentsMargins(0, 0, 0, 0);
|
|
|
|
bl2->setSpacing(0);
|
|
|
|
|
|
|
|
bl1->addStretch(1);
|
|
|
|
bl1->addLayout(bl2);
|
|
|
|
bl2->addStretch(1);
|
|
|
|
bl2->addLayout(grid, 0);
|
|
|
|
bl2->addStretch(1);
|
|
|
|
bl1->addStretch(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
DropArea DropSplitAreas::cursorLocation() const
|
|
|
|
{
|
|
|
|
auto loc = InvalidDropArea;
|
|
|
|
auto pos = mapFromGlobal(QCursor::pos());
|
2016-02-03 17:50:34 +08:00
|
|
|
if (_top && _top->geometry().contains(pos))
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
loc = TopDropArea;
|
|
|
|
}
|
2016-02-03 17:50:34 +08:00
|
|
|
else if (_right && _right->geometry().contains(pos))
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
loc = RightDropArea;
|
|
|
|
}
|
2016-02-03 17:50:34 +08:00
|
|
|
else if (_bottom && _bottom->geometry().contains(pos))
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
loc = BottomDropArea;
|
|
|
|
}
|
2016-02-03 17:50:34 +08:00
|
|
|
else if (_left && _left->geometry().contains(pos))
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
loc = LeftDropArea;
|
|
|
|
}
|
2016-02-03 17:50:34 +08:00
|
|
|
else if (_center && _center->geometry().contains(pos))
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
loc = CenterDropArea;
|
|
|
|
}
|
|
|
|
return loc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Globals ////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static QPointer<DropOverlay> MyOverlay;
|
|
|
|
static QPointer<QWidget> MyOverlayParent;
|
2016-02-01 17:55:45 +08:00
|
|
|
static QRect MyOverlayParentRect;
|
2016-02-02 20:49:10 +08:00
|
|
|
static DropArea MyOverlayLastLocation = InvalidDropArea;
|
2015-12-09 19:21:38 +08:00
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
DropArea showDropOverlay(QWidget* parent, DropAreas areas)
|
2015-12-09 19:21:38 +08:00
|
|
|
{
|
|
|
|
if (MyOverlay)
|
|
|
|
{
|
|
|
|
if (MyOverlayParent == parent)
|
|
|
|
{
|
|
|
|
// Hint: We could update geometry of overlay here.
|
2016-02-02 20:49:10 +08:00
|
|
|
DropArea da = MyOverlay->cursorLocation();
|
|
|
|
if (da != MyOverlayLastLocation)
|
|
|
|
{
|
|
|
|
MyOverlay->repaint();
|
|
|
|
MyOverlayLastLocation = da;
|
|
|
|
}
|
|
|
|
return da;
|
2015-12-09 19:21:38 +08:00
|
|
|
}
|
|
|
|
hideDropOverlay();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new overlay and move it directly over the "parent" widget.
|
2016-02-03 17:50:34 +08:00
|
|
|
MyOverlay = new DropOverlay(areas, parent);
|
2015-12-09 19:21:38 +08:00
|
|
|
MyOverlay->resize(parent->size());
|
|
|
|
MyOverlay->move(parent->mapToGlobal(parent->rect().topLeft()));
|
|
|
|
MyOverlay->show();
|
|
|
|
MyOverlayParent = parent;
|
|
|
|
return MyOverlay->cursorLocation();
|
|
|
|
}
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas)
|
2016-02-01 17:55:45 +08:00
|
|
|
{
|
|
|
|
if (MyOverlay)
|
|
|
|
{
|
|
|
|
if (MyOverlayParent == parent && MyOverlayParentRect == areaRect)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
hideDropOverlay();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create overlay and move it to the parent's areaRect
|
2016-02-03 17:50:34 +08:00
|
|
|
MyOverlay = new DropOverlay(areas, parent);
|
|
|
|
MyOverlay->setFullAreaDropEnabled(true);
|
2016-02-01 17:55:45 +08:00
|
|
|
MyOverlay->resize(areaRect.size());
|
|
|
|
MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y())));
|
|
|
|
MyOverlay->show();
|
|
|
|
MyOverlayParent = parent;
|
|
|
|
MyOverlayParentRect = areaRect;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-09 19:21:38 +08:00
|
|
|
void hideDropOverlay()
|
|
|
|
{
|
|
|
|
if (MyOverlay)
|
|
|
|
{
|
|
|
|
MyOverlay->hide();
|
|
|
|
delete MyOverlay;
|
|
|
|
MyOverlayParent.clear();
|
2016-02-01 17:55:45 +08:00
|
|
|
MyOverlayParentRect = QRect();
|
2016-02-02 20:49:10 +08:00
|
|
|
MyOverlayLastLocation = InvalidDropArea;
|
2015-12-09 19:21:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-03 17:50:34 +08:00
|
|
|
ADS_NAMESPACE_END
|