Adds drop functionality for outer areas

This commit is contained in:
mfreiholz 2016-02-01 10:55:45 +01:00
parent acd549d6a6
commit 863d3233ad
7 changed files with 146 additions and 13 deletions

View File

@ -57,4 +57,21 @@ QSplitter* findParentSplitter(class QWidget* w)
return cw; return cw;
} }
QSplitter* findImmediateSplitter(class QWidget* w)
{
QSplitter* sp = NULL;
QLayout* l = w->layout();
if (!l || l->count() <= 0)
return sp;
for (int i = 0; i < l->count(); ++i)
{
QLayoutItem* li = l->itemAt(0);
if (!li->widget())
continue;
if ((sp = dynamic_cast<QSplitter*>(li->widget())) != NULL)
break;
}
return sp;
}
ADS_NAMESPACE_END ADS_NAMESPACE_END

View File

@ -79,6 +79,7 @@ public:
class ContainerWidget* findParentContainerWidget(class QWidget* w); class ContainerWidget* findParentContainerWidget(class QWidget* w);
class SectionWidget* findParentSectionWidget(class QWidget* w); class SectionWidget* findParentSectionWidget(class QWidget* w);
QSplitter* findParentSplitter(class QWidget* w); QSplitter* findParentSplitter(class QWidget* w);
QSplitter* findImmediateSplitter(class QWidget* w);
ADS_NAMESPACE_END ADS_NAMESPACE_END

View File

@ -19,6 +19,41 @@ static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal)
return s; return s;
} }
static void dropContentOuterHelper(ContainerWidget* cw, QLayout* l, const InternalContentData& data, Qt::Orientation orientation, bool append)
{
auto sw = new SectionWidget(cw);
sw->addContent(data, true);
QSplitter* oldsp = findImmediateSplitter(cw);
if (oldsp->orientation() == orientation
|| oldsp->count() == 1)
{
oldsp->setOrientation(orientation);
if (append)
oldsp->addWidget(sw);
else
oldsp->insertWidget(0, sw);
}
else
{
auto sp = newSplitter(orientation);
if (append)
{
auto li = l->replaceWidget(oldsp, sp);
sp->addWidget(oldsp);
sp->addWidget(sw);
delete li;
}
else
{
sp->addWidget(sw);
auto li = l->replaceWidget(oldsp, sp);
sp->addWidget(oldsp);
delete li;
}
}
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
ContainerWidget::ContainerWidget(QWidget *parent) : ContainerWidget::ContainerWidget(QWidget *parent) :
@ -49,9 +84,24 @@ void ContainerWidget::setOrientation(Qt::Orientation orientation)
void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget* targetSection, DropArea area) void ContainerWidget::dropContent(const InternalContentData& data, SectionWidget* targetSection, DropArea area)
{ {
// Drop on outer area
if (!targetSection) if (!targetSection)
{ {
qWarning() << "Drop on invalid targetSection"; switch (area)
{
case TopDropArea:
dropContentOuterHelper(this, _mainLayout, data, Qt::Vertical, false);
break;
case RightDropArea:
dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, true);
break;
case BottomDropArea:
dropContentOuterHelper(this, _mainLayout, data, Qt::Vertical, true);
break;
case LeftDropArea:
dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, false);
break;
}
return; return;
} }
@ -226,6 +276,27 @@ QRect ContainerWidget::outerLeftDropRect() const
return QRect(r.left(), r.top(), w, r.height()); return QRect(r.left(), r.top(), w, r.height());
} }
QByteArray ContainerWidget::saveGeometry() const
{
QByteArray ba;
QDataStream out(&ba, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_5);
out << (int) 0x00001337;
out << _sections.size();
return ba;
}
bool ContainerWidget::restoreGeometry(const QByteArray& data)
{
QDataStream in(data);
in.setVersion(QDataStream::Qt_4_5);
int magic = 0;
in >> magic;
return false;
}
void ContainerWidget::paintEvent(QPaintEvent* e) void ContainerWidget::paintEvent(QPaintEvent* e)
{ {
QFrame::paintEvent(e); QFrame::paintEvent(e);

View File

@ -41,6 +41,10 @@ public:
QRect outerBottomDropRect() const; QRect outerBottomDropRect() const;
QRect outerLeftDropRect() const; QRect outerLeftDropRect() const;
// Geometry and state serialization
QByteArray saveGeometry() const;
bool restoreGeometry(const QByteArray& data);
protected: protected:
virtual void paintEvent(QPaintEvent*); virtual void paintEvent(QPaintEvent*);
virtual void contextMenuEvent(QContextMenuEvent*); virtual void contextMenuEvent(QContextMenuEvent*);

View File

@ -168,6 +168,7 @@ DropArea DropSplitAreas::cursorLocation() const
static QPointer<DropOverlay> MyOverlay; static QPointer<DropOverlay> MyOverlay;
static QPointer<QWidget> MyOverlayParent; static QPointer<QWidget> MyOverlayParent;
static QRect MyOverlayParentRect;
DropArea showDropOverlay(QWidget* parent) DropArea showDropOverlay(QWidget* parent)
{ {
@ -190,6 +191,27 @@ DropArea showDropOverlay(QWidget* parent)
return MyOverlay->cursorLocation(); return MyOverlay->cursorLocation();
} }
void showDropOverlay(QWidget* parent, const QRect& areaRect)
{
if (MyOverlay)
{
if (MyOverlayParent == parent && MyOverlayParentRect == areaRect)
{
return;
}
hideDropOverlay();
}
// Create overlay and move it to the parent's areaRect
MyOverlay = new DropOverlay(parent);
MyOverlay->resize(areaRect.size());
MyOverlay->move(parent->mapToGlobal(QPoint(areaRect.x(), areaRect.y())));
MyOverlay->show();
MyOverlayParent = parent;
MyOverlayParentRect = areaRect;
return;
}
void hideDropOverlay() void hideDropOverlay()
{ {
if (MyOverlay) if (MyOverlay)
@ -197,6 +219,7 @@ void hideDropOverlay()
MyOverlay->hide(); MyOverlay->hide();
delete MyOverlay; delete MyOverlay;
MyOverlayParent.clear(); MyOverlayParent.clear();
MyOverlayParentRect = QRect();
} }
} }

View File

@ -2,6 +2,7 @@
#define DROP_OVERLAY_H #define DROP_OVERLAY_H
#include <QFrame> #include <QFrame>
#include <QRect>
#include "ads.h" #include "ads.h"
@ -54,6 +55,7 @@ private:
DropArea showDropOverlay(QWidget* parent); DropArea showDropOverlay(QWidget* parent);
void showDropOverlay(QWidget* parent, const QRect& areaRect);
void hideDropOverlay(); void hideDropOverlay();
ADS_NAMESPACE_END ADS_NAMESPACE_END

View File

@ -29,12 +29,12 @@ static void deleteEmptySplitter(ContainerWidget* container)
auto splitters = container->findChildren<QSplitter*>(); auto splitters = container->findChildren<QSplitter*>();
for (auto i = 0; i < splitters.count(); ++i) for (auto i = 0; i < splitters.count(); ++i)
{ {
if (splitters[i]->count() == 0 && container->_splitter != splitters[i]) if (splitters[i]->count() == 0 /*&& container->_splitter != splitters[i]*/)
{ {
if (splitters[i] == container->_splitter) if (splitters[i] == container->_splitter)
continue; continue;
qDebug() << "Delete empty QSplitter"; qDebug() << "Delete empty QSplitter";
splitters[i]->deleteLater(); delete splitters[i];//splitters[i]->deleteLater();
} }
} }
} }
@ -96,11 +96,7 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
if (sw) if (sw)
{ {
auto loc = showDropOverlay(sw); auto loc = showDropOverlay(sw);
if (loc == InvalidDropArea) if (loc != InvalidDropArea)
{
qDebug() << "Invalid drop area";
}
else
{ {
#if !defined(ADS_ANIMATIONS_ENABLED) #if !defined(ADS_ANIMATIONS_ENABLED)
auto data = _fw->takeContent(); auto data = _fw->takeContent();
@ -133,9 +129,28 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
} }
} }
// Mouse is over a outer-edge drop area // Mouse is over a outer-edge drop area
else if (false) else
{ {
DropArea dropArea = DropArea::InvalidDropArea;
if (cw->outerTopDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
dropArea = DropArea::TopDropArea;
if (cw->outerRightDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
dropArea = DropArea::RightDropArea;
if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
dropArea = DropArea::BottomDropArea;
if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
dropArea = DropArea::LeftDropArea;
if (dropArea != DropArea::InvalidDropArea)
{
#if !defined(ADS_ANIMATIONS_ENABLED)
auto data = _fw->takeContent();
_fw->deleteLater();
_fw.clear();
cw->dropContent(data, NULL, dropArea);
#else
#endif
}
} }
} }
@ -169,19 +184,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())))
{ {
qDebug() << "Top area..."; showDropOverlay(cw, cw->outerTopDropRect());
} }
else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
qDebug() << "Right area..."; showDropOverlay(cw, cw->outerRightDropRect());
} }
else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
qDebug() << "Bottom area..."; showDropOverlay(cw, cw->outerBottomDropRect());
} }
else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos()))) else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
{ {
qDebug() << "Left area..."; showDropOverlay(cw, cw->outerLeftDropRect());
} }
else else
{ {