Available drop areas for DropOverlay can be configured via constructor

now.
Better visualization for edge-drops, always shown entire rect as active
drop area and only show a single drop icon.
This commit is contained in:
mfreiholz 2016-02-03 10:50:34 +01:00
parent 2a5849a266
commit 7123410bb1
6 changed files with 86 additions and 43 deletions

View File

@ -26,13 +26,16 @@ ADS_NAMESPACE_BEGIN
enum DropArea enum DropArea
{ {
TopDropArea, InvalidDropArea = 0,
RightDropArea, TopDropArea = 1,
BottomDropArea, RightDropArea = 2,
LeftDropArea, BottomDropArea = 4,
CenterDropArea, LeftDropArea = 8,
InvalidDropArea CenterDropArea = 16,
AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea
}; };
Q_DECLARE_FLAGS(DropAreas, DropArea)
class InternalContentData class InternalContentData
{ {

View File

@ -15,8 +15,9 @@ class DropOverlay : public QFrame
Q_OBJECT Q_OBJECT
public: public:
DropOverlay(QWidget* parent); DropOverlay(DropAreas areas, QWidget* parent);
virtual ~DropOverlay(); virtual ~DropOverlay();
void setFullAreaDropEnabled(bool enabled) { _fullAreaDrop = enabled; }
DropArea cursorLocation() const; DropArea cursorLocation() const;
protected: protected:
@ -26,6 +27,7 @@ protected:
private: private:
class DropSplitAreas* _splitAreas; class DropSplitAreas* _splitAreas;
bool _fullAreaDrop;
}; };
// AbstractDropAreas is used as base for drop area indicator widgets. // AbstractDropAreas is used as base for drop area indicator widgets.
@ -42,7 +44,7 @@ class DropSplitAreas : public AbstractDropAreas
Q_OBJECT Q_OBJECT
public: public:
DropSplitAreas(QWidget* parent); DropSplitAreas(DropAreas areas, QWidget* parent);
virtual DropArea cursorLocation() const; virtual DropArea cursorLocation() const;
private: private:
@ -54,8 +56,8 @@ private:
}; };
DropArea showDropOverlay(QWidget* parent); DropArea showDropOverlay(QWidget* parent, DropAreas areas = DropArea::AllAreas);
void showDropOverlay(QWidget* parent, const QRect& areaRect); void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas = DropArea::AllAreas);
void hideDropOverlay(); void hideDropOverlay();
ADS_NAMESPACE_END ADS_NAMESPACE_END

View File

@ -100,6 +100,8 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget
case LeftDropArea: case LeftDropArea:
dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, false); dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, false);
break; break;
default:
return;
} }
return; return;
} }
@ -190,6 +192,8 @@ void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget
targetSection->addContent(data, true); targetSection->addContent(data, true);
break; break;
} }
default:
break;
} }
} }

View File

@ -25,9 +25,10 @@ static QWidget* createDropWidget(const QString& img)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
DropOverlay::DropOverlay(QWidget *parent) : DropOverlay::DropOverlay(DropAreas areas, QWidget *parent) :
QFrame(parent), QFrame(parent),
_splitAreas(NULL) _splitAreas(NULL),
_fullAreaDrop(false)
{ {
//setAttribute(Qt::WA_TransparentForMouseEvents); //setAttribute(Qt::WA_TransparentForMouseEvents);
setWindowFlags(windowFlags() | Qt::Tool); setWindowFlags(windowFlags() | Qt::Tool);
@ -39,7 +40,7 @@ DropOverlay::DropOverlay(QWidget *parent) :
l->setSpacing(0); l->setSpacing(0);
setLayout(l); setLayout(l);
_splitAreas = new DropSplitAreas(parent); _splitAreas = new DropSplitAreas(areas, parent);
_splitAreas->move(pos()); _splitAreas->move(pos());
_splitAreas->resize(size()); _splitAreas->resize(size());
_splitAreas->setVisible(true); _splitAreas->setVisible(true);
@ -68,6 +69,16 @@ void DropOverlay::paintEvent(QPaintEvent*)
{ {
QPainter p(this); QPainter p(this);
// 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;
}
// Draw rect based on location // Draw rect based on location
QRect r = rect(); QRect r = rect();
const DropArea da = cursorLocation(); const DropArea da = cursorLocation();
@ -128,27 +139,48 @@ void DropOverlay::moveEvent(QMoveEvent* e)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
DropSplitAreas::DropSplitAreas(QWidget* parent) : AbstractDropAreas(parent) DropSplitAreas::DropSplitAreas(DropAreas areas, QWidget* parent) :
AbstractDropAreas(parent),
_top(0),
_right(0),
_bottom(0),
_left(0),
_center(0)
{ {
//setAttribute(Qt::WA_TransparentForMouseEvents); //setAttribute(Qt::WA_TransparentForMouseEvents);
setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(windowFlags() | Qt::Tool); setWindowFlags(windowFlags() | Qt::Tool);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint); setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
_top = createDropWidget(":/img/split-top.png");
_right = createDropWidget(":/img/split-right.png");
_bottom = createDropWidget(":/img/split-bottom.png");
_left = createDropWidget(":/img/split-left.png");
_center = createDropWidget(":/img/dock-center.png");
QGridLayout* grid = new QGridLayout(); QGridLayout* grid = new QGridLayout();
grid->setContentsMargins(0, 0, 0, 0); grid->setContentsMargins(0, 0, 0, 0);
grid->setSpacing(6); grid->setSpacing(6);
if (areas.testFlag(DropArea::TopDropArea))
{
_top = createDropWidget(":/img/split-top.png");
grid->addWidget(_top, 0, 1, Qt::AlignHCenter | Qt::AlignBottom); 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); 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); 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); 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); grid->addWidget(_center, 1, 1, Qt::AlignCenter);
}
QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom); QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom);
bl1->setContentsMargins(0, 0, 0, 0); bl1->setContentsMargins(0, 0, 0, 0);
@ -171,23 +203,23 @@ DropArea DropSplitAreas::cursorLocation() const
{ {
auto loc = InvalidDropArea; auto loc = InvalidDropArea;
auto pos = mapFromGlobal(QCursor::pos()); auto pos = mapFromGlobal(QCursor::pos());
if (_top->geometry().contains(pos)) if (_top && _top->geometry().contains(pos))
{ {
loc = TopDropArea; loc = TopDropArea;
} }
else if (_right->geometry().contains(pos)) else if (_right && _right->geometry().contains(pos))
{ {
loc = RightDropArea; loc = RightDropArea;
} }
else if (_bottom->geometry().contains(pos)) else if (_bottom && _bottom->geometry().contains(pos))
{ {
loc = BottomDropArea; loc = BottomDropArea;
} }
else if (_left->geometry().contains(pos)) else if (_left && _left->geometry().contains(pos))
{ {
loc = LeftDropArea; loc = LeftDropArea;
} }
else if (_center->geometry().contains(pos)) else if (_center && _center->geometry().contains(pos))
{ {
loc = CenterDropArea; loc = CenterDropArea;
} }
@ -201,7 +233,7 @@ static QPointer<QWidget> MyOverlayParent;
static QRect MyOverlayParentRect; static QRect MyOverlayParentRect;
static DropArea MyOverlayLastLocation = InvalidDropArea; static DropArea MyOverlayLastLocation = InvalidDropArea;
DropArea showDropOverlay(QWidget* parent) DropArea showDropOverlay(QWidget* parent, DropAreas areas)
{ {
if (MyOverlay) if (MyOverlay)
{ {
@ -220,7 +252,7 @@ DropArea showDropOverlay(QWidget* parent)
} }
// Create new overlay and move it directly over the "parent" widget. // Create new overlay and move it directly over the "parent" widget.
MyOverlay = new DropOverlay(parent); MyOverlay = new DropOverlay(areas, parent);
MyOverlay->resize(parent->size()); MyOverlay->resize(parent->size());
MyOverlay->move(parent->mapToGlobal(parent->rect().topLeft())); MyOverlay->move(parent->mapToGlobal(parent->rect().topLeft()));
MyOverlay->show(); MyOverlay->show();
@ -228,7 +260,7 @@ DropArea showDropOverlay(QWidget* parent)
return MyOverlay->cursorLocation(); return MyOverlay->cursorLocation();
} }
void showDropOverlay(QWidget* parent, const QRect& areaRect) void showDropOverlay(QWidget* parent, const QRect& areaRect, DropAreas areas)
{ {
if (MyOverlay) if (MyOverlay)
{ {
@ -240,7 +272,8 @@ void showDropOverlay(QWidget* parent, const QRect& areaRect)
} }
// Create overlay and move it to the parent's areaRect // Create overlay and move it to the parent's areaRect
MyOverlay = new DropOverlay(parent); MyOverlay = new DropOverlay(areas, parent);
MyOverlay->setFullAreaDropEnabled(true);
MyOverlay->resize(areaRect.size()); MyOverlay->resize(areaRect.size());
MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y()))); MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y())));
MyOverlay->show(); MyOverlay->show();

View File

@ -40,6 +40,7 @@ FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPt
auto closeButton = new QPushButton(); auto closeButton = new QPushButton();
closeButton->setObjectName("closeButton"); closeButton->setObjectName("closeButton");
closeButton->setFlat(true);
closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
closeButton->setToolTip(tr("Close")); closeButton->setToolTip(tr("Close"));
closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

View File

@ -186,19 +186,19 @@ void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev)
// Top, Right, Bottom, Left // Top, Right, Bottom, Left
else if (cw->outerTopDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerTopDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
showDropOverlay(cw, cw->outerTopDropRect()); showDropOverlay(cw, cw->outerTopDropRect(), DropArea::TopDropArea);
} }
else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
showDropOverlay(cw, cw->outerRightDropRect()); showDropOverlay(cw, cw->outerRightDropRect(), DropArea::RightDropArea);
} }
else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
showDropOverlay(cw, cw->outerBottomDropRect()); showDropOverlay(cw, cw->outerBottomDropRect(), DropArea::BottomDropArea);
} }
else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
showDropOverlay(cw, cw->outerLeftDropRect()); showDropOverlay(cw, cw->outerLeftDropRect(), DropArea::LeftDropArea);
} }
else else
{ {