mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 13:15:43 +08:00
Improved handling and display of border drop overlays. Now border drop overlay items are visible as soon as a floating widget enters container widget area, some refactoring to improve code quality
This commit is contained in:
parent
3fd20fad16
commit
411e4002f1
@ -60,12 +60,8 @@ enum DropArea
|
||||
LeftDropArea = 8,
|
||||
CenterDropArea = 16,
|
||||
|
||||
TopBorderDropArea = 32,
|
||||
RightBorderDropArea = 64,
|
||||
BottomBorderDropArea = 128,
|
||||
LeftBorderDropArea = 256,
|
||||
|
||||
AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea
|
||||
OuterAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea,
|
||||
AllAreas = OuterAreas | CenterDropArea
|
||||
};
|
||||
Q_DECLARE_FLAGS(DropAreas, DropArea)
|
||||
|
||||
|
@ -141,11 +141,15 @@ private:
|
||||
|
||||
void moveFloatingWidget(const QPoint& TargetPos);
|
||||
FloatingWidget* startFloating(SectionWidget* sectionwidget, int ContentUid, const QPoint& TargetPos);
|
||||
void hideContainerOverlay();
|
||||
SectionWidget* insertNewSectionWidget(const InternalContentData& data,
|
||||
SectionWidget* targetSection, SectionWidget* ret, Qt::Orientation Orientation, int InsertIndexOffset);
|
||||
|
||||
private slots:
|
||||
void onActiveTabChanged();
|
||||
void onActionToggleSectionContentVisibility(bool visible);
|
||||
|
||||
|
||||
signals:
|
||||
void orientationChanged();
|
||||
|
||||
|
@ -27,6 +27,9 @@ class FloatingWidget;
|
||||
class HiddenSectionItem;
|
||||
|
||||
|
||||
/**
|
||||
* Container widget private data
|
||||
*/
|
||||
struct ContainerWidgetPrivate
|
||||
{
|
||||
// Elements inside container.
|
||||
@ -42,15 +45,16 @@ struct ContainerWidgetPrivate
|
||||
|
||||
|
||||
// Layout stuff
|
||||
QGridLayout* mainLayout = nullptr;
|
||||
QGridLayout* MainLayout = nullptr;
|
||||
Qt::Orientation orientation = Qt::Horizontal;
|
||||
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;
|
||||
QWidget* LeftBorderDropArea;
|
||||
};
|
||||
QPointer<DropOverlay> SectionDropOverlay;
|
||||
QPointer<DropOverlay> ContainerDropOverlay;
|
||||
//QWidget* LeftBorderDropArea;
|
||||
}; // struct ContainerWidgetPrivate
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -22,7 +22,13 @@ class ADS_EXPORT_API DropOverlay : public QFrame
|
||||
friend class DropOverlayCross;
|
||||
|
||||
public:
|
||||
DropOverlay(QWidget* parent);
|
||||
enum eMode
|
||||
{
|
||||
ModeSectionOverlay,
|
||||
ModeContainerOverlay
|
||||
};
|
||||
|
||||
DropOverlay(QWidget* parent, eMode Mode = ModeSectionOverlay);
|
||||
virtual ~DropOverlay();
|
||||
|
||||
void setAllowedAreas(DropAreas areas);
|
||||
@ -67,19 +73,22 @@ public:
|
||||
DropOverlayCross(DropOverlay* overlay);
|
||||
virtual ~DropOverlayCross();
|
||||
|
||||
void setAreaWidgets(const QHash<DropArea, QWidget*>& widgets);
|
||||
DropArea cursorLocation() const;
|
||||
void setupOverlayCross(DropOverlay::eMode Mode);
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e);
|
||||
void setAreaWidgets(const QHash<DropArea, QWidget*>& widgets);
|
||||
|
||||
private:
|
||||
void reset();
|
||||
QPoint areaGridPosition(const DropArea area);
|
||||
|
||||
private:
|
||||
DropOverlay* _overlay;
|
||||
QHash<DropArea, QWidget*> _widgets;
|
||||
QGridLayout* _grid;
|
||||
DropOverlay::eMode m_Mode = DropOverlay::ModeSectionOverlay;
|
||||
DropOverlay* m_DropOverlay;
|
||||
QHash<DropArea, QWidget*> m_DropIndicatorWidgets;
|
||||
QGridLayout* m_GridLayout;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
|
@ -41,22 +41,22 @@ ContainerWidget::ContainerWidget(QWidget *parent) :
|
||||
QFrame(parent),
|
||||
d(new ContainerWidgetPrivate())
|
||||
{
|
||||
d->LeftBorderDropArea = DropOverlay::createDropIndicatorWidget(LeftBorderDropArea);
|
||||
d->LeftBorderDropArea->setVisible(false);
|
||||
d->LeftBorderDropArea->setWindowTitle("LeftBorderDropArea");
|
||||
d->SectionDropOverlay = new DropOverlay(this, DropOverlay::ModeSectionOverlay);
|
||||
d->ContainerDropOverlay = new DropOverlay(this, DropOverlay::ModeContainerOverlay);
|
||||
d->ContainerDropOverlay->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
d->ContainerDropOverlay->setWindowFlags(d->ContainerDropOverlay->windowFlags() | Qt::WindowTransparentForInput);
|
||||
|
||||
d->dropOverlay = new DropOverlay(this);
|
||||
d->mainLayout = new QGridLayout();
|
||||
d->mainLayout->setContentsMargins(4, 4, 4, 4);
|
||||
d->mainLayout->setSpacing(0);
|
||||
setLayout(d->mainLayout);
|
||||
d->MainLayout = new QGridLayout();
|
||||
d->MainLayout->setContentsMargins(0, 1, 0, 0);
|
||||
d->MainLayout->setSpacing(0);
|
||||
setLayout(d->MainLayout);
|
||||
}
|
||||
|
||||
ContainerWidget::~ContainerWidget()
|
||||
{
|
||||
// Note: It's required to delete in 2 steps
|
||||
// Remove from list, and then delete.
|
||||
// Because the destrcutor of objects wants to modfiy the current
|
||||
// Because the destrcutor of objects wants to modify the current
|
||||
// iterating list as well... :-/
|
||||
while (!d->sections.isEmpty())
|
||||
{
|
||||
@ -430,7 +430,7 @@ QList<SectionContent::RefPtr> ContainerWidget::contents() const
|
||||
|
||||
QPointer<DropOverlay> ContainerWidget::dropOverlay() const
|
||||
{
|
||||
return d->dropOverlay;
|
||||
return d->SectionDropOverlay;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@ -444,14 +444,38 @@ SectionWidget* ContainerWidget::newSectionWidget()
|
||||
return sw;
|
||||
}
|
||||
|
||||
SectionWidget* ContainerWidget::insertNewSectionWidget(
|
||||
const InternalContentData& data, SectionWidget* targetSection, SectionWidget* ret,
|
||||
Qt::Orientation Orientation, int InsertIndexOffset)
|
||||
{
|
||||
QSplitter* targetSectionSplitter = findParentSplitter(targetSection);
|
||||
SectionWidget* sw = newSectionWidget();
|
||||
sw->addContent(data, true);
|
||||
if (targetSectionSplitter->orientation() == Orientation)
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index + InsertIndexOffset, sw);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
QSplitter* s = newSplitter(Orientation);
|
||||
s->addWidget(sw);
|
||||
s->addWidget(targetSection);
|
||||
targetSectionSplitter->insertWidget(index, s);
|
||||
}
|
||||
ret = sw;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, SectionWidget* targetSection, DropArea area, bool autoActive)
|
||||
{
|
||||
ADS_Expects(targetSection != NULL);
|
||||
|
||||
SectionWidget* ret = NULL;
|
||||
SectionWidget* section_widget = nullptr;
|
||||
|
||||
// If no sections exists yet, create a default one and always drop into it.
|
||||
if (d->sections.count() <= 0)
|
||||
if (d->sections.isEmpty())
|
||||
{
|
||||
targetSection = newSectionWidget();
|
||||
addSection(targetSection);
|
||||
@ -463,120 +487,32 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case TopDropArea:
|
||||
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, false);
|
||||
break;
|
||||
case RightDropArea:
|
||||
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, true);
|
||||
break;
|
||||
case TopDropArea:return dropContentOuterHelper(d->MainLayout, data, Qt::Vertical, false);
|
||||
case RightDropArea: return dropContentOuterHelper(d->MainLayout, data, Qt::Horizontal, true);
|
||||
case CenterDropArea:
|
||||
case BottomDropArea:
|
||||
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, true);
|
||||
break;
|
||||
case LeftDropArea:
|
||||
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, false);
|
||||
break;
|
||||
case BottomDropArea:return dropContentOuterHelper(d->MainLayout, data, Qt::Vertical, true);
|
||||
case LeftDropArea: return dropContentOuterHelper(d->MainLayout, data, Qt::Horizontal, false);
|
||||
default:
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return ret;
|
||||
return section_widget;
|
||||
}
|
||||
|
||||
QSplitter* targetSectionSplitter = findParentSplitter(targetSection);
|
||||
|
||||
// Drop logic based on area.
|
||||
switch (area)
|
||||
{
|
||||
case TopDropArea:
|
||||
{
|
||||
SectionWidget* sw = newSectionWidget();
|
||||
sw->addContent(data, true);
|
||||
if (targetSectionSplitter->orientation() == Qt::Vertical)
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index, sw);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
QSplitter* s = newSplitter(Qt::Vertical);
|
||||
s->addWidget(sw);
|
||||
s->addWidget(targetSection);
|
||||
targetSectionSplitter->insertWidget(index, s);
|
||||
}
|
||||
ret = sw;
|
||||
break;
|
||||
}
|
||||
case RightDropArea:
|
||||
{
|
||||
SectionWidget* sw = newSectionWidget();
|
||||
sw->addContent(data, true);
|
||||
if (targetSectionSplitter->orientation() == Qt::Horizontal)
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index + 1, sw);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = targetSectionSplitter->indexOf(targetSection);
|
||||
QSplitter* s = newSplitter(Qt::Horizontal);
|
||||
s->addWidget(targetSection);
|
||||
s->addWidget(sw);
|
||||
targetSectionSplitter->insertWidget(index, s);
|
||||
}
|
||||
ret = sw;
|
||||
break;
|
||||
}
|
||||
case BottomDropArea:
|
||||
{
|
||||
SectionWidget* sw = newSectionWidget();
|
||||
sw->addContent(data, true);
|
||||
if (targetSectionSplitter->orientation() == Qt::Vertical)
|
||||
{
|
||||
int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index + 1, sw);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = targetSectionSplitter->indexOf(targetSection);
|
||||
QSplitter* s = newSplitter(Qt::Vertical);
|
||||
s->addWidget(targetSection);
|
||||
s->addWidget(sw);
|
||||
targetSectionSplitter->insertWidget(index, s);
|
||||
}
|
||||
ret = sw;
|
||||
break;
|
||||
}
|
||||
case LeftDropArea:
|
||||
{
|
||||
SectionWidget* sw = newSectionWidget();
|
||||
sw->addContent(data, true);
|
||||
if (targetSectionSplitter->orientation() == Qt::Horizontal)
|
||||
{
|
||||
int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index, sw);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSplitter* s = newSplitter(Qt::Horizontal);
|
||||
s->addWidget(sw);
|
||||
int index = targetSectionSplitter->indexOf(targetSection);
|
||||
targetSectionSplitter->insertWidget(index, s);
|
||||
s->addWidget(targetSection);
|
||||
}
|
||||
ret = sw;
|
||||
break;
|
||||
}
|
||||
case TopDropArea:return insertNewSectionWidget(data, targetSection, section_widget, Qt::Vertical, 0);
|
||||
case RightDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Horizontal, 1);
|
||||
case BottomDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Vertical, 1);
|
||||
case LeftDropArea: return insertNewSectionWidget(data, targetSection, section_widget, Qt::Horizontal, 0);
|
||||
case CenterDropArea:
|
||||
{
|
||||
targetSection->addContent(data, autoActive);
|
||||
ret = targetSection;
|
||||
break;
|
||||
}
|
||||
targetSection->addContent(data, autoActive);
|
||||
return targetSection;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
return section_widget;
|
||||
}
|
||||
|
||||
void ContainerWidget::addSection(SectionWidget* section)
|
||||
@ -587,7 +523,7 @@ void ContainerWidget::addSection(SectionWidget* section)
|
||||
if (!d->splitter)
|
||||
{
|
||||
d->splitter = newSplitter(d->orientation);
|
||||
d->mainLayout->addWidget(d->splitter, 0, 0);
|
||||
d->MainLayout->addWidget(d->splitter, 0, 0);
|
||||
}
|
||||
if (d->splitter->indexOf(section) != -1)
|
||||
{
|
||||
@ -712,7 +648,7 @@ QByteArray ContainerWidget::saveHierarchy() const
|
||||
saveFloatingWidgets(out);
|
||||
|
||||
// Save state of sections and contents
|
||||
if (d->mainLayout->count() <= 0 || d->sections.isEmpty())
|
||||
if (d->MainLayout->count() <= 0 || d->sections.isEmpty())
|
||||
{
|
||||
// Looks like the user has hidden all contents and no more sections
|
||||
// are available. We can simply write a list of all hidden contents.
|
||||
@ -726,12 +662,12 @@ QByteArray ContainerWidget::saveHierarchy() const
|
||||
out << iter.value().data.content->uniqueName();
|
||||
}
|
||||
}
|
||||
else if (d->mainLayout->count() == 1)
|
||||
else if (d->MainLayout->count() == 1)
|
||||
{
|
||||
out << 1; // Mode
|
||||
|
||||
// There should only be one!
|
||||
QLayoutItem* li = d->mainLayout->itemAt(0);
|
||||
QLayoutItem* li = d->MainLayout->itemAt(0);
|
||||
if (!li->widget())
|
||||
qFatal("Not a widget in d->mainLayout, this shouldn't happen.");
|
||||
|
||||
@ -1023,8 +959,8 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
||||
d->sections = sections;
|
||||
|
||||
// Delete old objects
|
||||
QLayoutItem* old = d->mainLayout->takeAt(0);
|
||||
d->mainLayout->addWidget(d->splitter);
|
||||
QLayoutItem* old = d->MainLayout->takeAt(0);
|
||||
d->MainLayout->addWidget(d->splitter);
|
||||
delete old;
|
||||
qDeleteAll(oldFloatings);
|
||||
qDeleteAll(oldSections);
|
||||
@ -1236,19 +1172,26 @@ void ContainerWidget::onActionToggleSectionContentVisibility(bool visible)
|
||||
}
|
||||
|
||||
|
||||
void ContainerWidget::hideContainerOverlay()
|
||||
{
|
||||
d->ContainerDropOverlay->hideDropOverlay();
|
||||
}
|
||||
|
||||
|
||||
void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos)
|
||||
{
|
||||
std::cout << "moveFloatingWidget" << std::endl;
|
||||
// Mouse is over the container widget
|
||||
if (rect().contains(mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
std::cout << "over Container" << std::endl;
|
||||
d->LeftBorderDropArea->show();
|
||||
d->LeftBorderDropArea->raise();
|
||||
d->ContainerDropOverlay->showDropOverlay(this);
|
||||
d->ContainerDropOverlay->raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "-----------------" << std::endl;
|
||||
d->LeftBorderDropArea->hide();
|
||||
d->ContainerDropOverlay->hideDropOverlay();
|
||||
}
|
||||
|
||||
// Mouse is over a SectionWidget
|
||||
@ -1256,12 +1199,12 @@ void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos)
|
||||
if (sectionwidget)
|
||||
{
|
||||
qInfo() << "over sectionWidget";
|
||||
d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
d->dropOverlay->showDropOverlay(sectionwidget);
|
||||
d->SectionDropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
d->SectionDropOverlay->showDropOverlay(sectionwidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->dropOverlay->hideDropOverlay();
|
||||
d->SectionDropOverlay->hideDropOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1290,9 +1233,9 @@ FloatingWidget* ContainerWidget::startFloating(SectionWidget* sectionwidget, int
|
||||
}
|
||||
deleteEmptySplitter(this);
|
||||
|
||||
QRect Rect = rect();
|
||||
QPoint Pos(Rect.left(), Rect.center().y());
|
||||
d->LeftBorderDropArea->move(mapToGlobal(Pos));
|
||||
d->ContainerDropOverlay->setAllowedAreas(OuterAreas);
|
||||
d->ContainerDropOverlay->showDropOverlay(this);
|
||||
d->ContainerDropOverlay->raise();
|
||||
return fw;
|
||||
}
|
||||
|
||||
|
@ -35,72 +35,61 @@ static QPixmap createDropIndicatorPixmap(const QPalette& pal, const QSizeF& size
|
||||
p.fillRect(baseRect, backgroundColor);
|
||||
|
||||
// Drop area rect.
|
||||
if (true)
|
||||
p.save();
|
||||
QRectF areaRect;
|
||||
QLineF areaLine;
|
||||
QLinearGradient gradient;
|
||||
switch (dropArea)
|
||||
{
|
||||
p.save();
|
||||
QRectF areaRect;
|
||||
QLineF areaLine;
|
||||
QLinearGradient gradient;
|
||||
switch (dropArea)
|
||||
{
|
||||
case TopDropArea:
|
||||
case TopBorderDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
break;
|
||||
case RightDropArea:
|
||||
case RightBorderDropArea:
|
||||
areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
break;
|
||||
case BottomDropArea:
|
||||
case BottomBorderDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.topRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
break;
|
||||
case LeftDropArea:
|
||||
case LeftBorderDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (areaRect.isValid())
|
||||
{
|
||||
gradient.setColorAt(0.f, areaBackgroundColor);
|
||||
gradient.setColorAt(1.f, areaBackgroundColor.lighter(120));
|
||||
p.fillRect(areaRect, gradient);
|
||||
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
pen.setStyle(Qt::DashLine);
|
||||
p.setPen(pen);
|
||||
p.drawLine(areaLine);
|
||||
}
|
||||
p.restore();
|
||||
case TopDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
break;
|
||||
case RightDropArea:
|
||||
areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
break;
|
||||
case BottomDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.topRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
break;
|
||||
case LeftDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Border
|
||||
if (true)
|
||||
if (areaRect.isValid())
|
||||
{
|
||||
p.save();
|
||||
gradient.setColorAt(0.f, areaBackgroundColor);
|
||||
gradient.setColorAt(1.f, areaBackgroundColor.lighter(120));
|
||||
p.fillRect(areaRect, gradient);
|
||||
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
pen.setWidth(1);
|
||||
|
||||
pen.setStyle(Qt::DashLine);
|
||||
p.setPen(pen);
|
||||
p.drawRect(baseRect.adjusted(0, 0, -pen.width(), -pen.width()));
|
||||
p.restore();
|
||||
p.drawLine(areaLine);
|
||||
}
|
||||
p.restore();
|
||||
|
||||
p.save();
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
pen.setWidth(1);
|
||||
|
||||
p.setPen(pen);
|
||||
p.drawRect(baseRect.adjusted(0, 0, -pen.width(), -pen.width()));
|
||||
p.restore();
|
||||
return pm;
|
||||
}
|
||||
|
||||
@ -120,7 +109,7 @@ QWidget* DropOverlay::createDropIndicatorWidget(DropArea dropArea)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
DropOverlay::DropOverlay(QWidget* parent) :
|
||||
DropOverlay::DropOverlay(QWidget* parent, eMode Mode) :
|
||||
QFrame(parent),
|
||||
_allowedAreas(InvalidDropArea),
|
||||
_cross(new DropOverlayCross(this)),
|
||||
@ -129,21 +118,14 @@ DropOverlay::DropOverlay(QWidget* parent) :
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowOpacity(0.2);
|
||||
setWindowTitle("DropOverlay");
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
|
||||
// Cross with default drop area widgets.
|
||||
QHash<DropArea, QWidget*> areaWidgets;
|
||||
areaWidgets.insert(ADS_NS::TopDropArea, createDropIndicatorWidget(TopDropArea)); //createDropWidget(":/img/split-top.png"));
|
||||
areaWidgets.insert(ADS_NS::RightDropArea, createDropIndicatorWidget(RightDropArea));//createDropWidget(":/img/split-right.png"));
|
||||
areaWidgets.insert(ADS_NS::BottomDropArea, createDropIndicatorWidget(BottomDropArea));//createDropWidget(":/img/split-bottom.png"));
|
||||
areaWidgets.insert(ADS_NS::LeftDropArea, createDropIndicatorWidget(LeftDropArea));//createDropWidget(":/img/split-left.png"));
|
||||
areaWidgets.insert(ADS_NS::CenterDropArea, createDropIndicatorWidget(CenterDropArea));//createDropWidget(":/img/dock-center.png"));
|
||||
|
||||
_cross->setAreaWidgets(areaWidgets);
|
||||
_cross->setupOverlayCross(Mode);
|
||||
_cross->setVisible(false);
|
||||
setVisible(false);
|
||||
}
|
||||
@ -291,84 +273,136 @@ void DropOverlay::moveEvent(QMoveEvent* e)
|
||||
_cross->move(e->pos());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static QPair<QPoint, int> gridPosForArea(const DropArea area)
|
||||
static int areaAlignment(const DropArea area)
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case ADS_NS::TopDropArea:
|
||||
return qMakePair(QPoint(0, 1), (int) Qt::AlignHCenter | Qt::AlignBottom);
|
||||
case ADS_NS::RightDropArea:
|
||||
return qMakePair(QPoint(1, 2), (int) Qt::AlignLeft | Qt::AlignVCenter);
|
||||
case ADS_NS::BottomDropArea:
|
||||
return qMakePair(QPoint(2, 1), (int) Qt::AlignHCenter | Qt::AlignTop);
|
||||
case ADS_NS::LeftDropArea:
|
||||
return qMakePair(QPoint(1, 0), (int) Qt::AlignRight | Qt::AlignVCenter);
|
||||
case ADS_NS::CenterDropArea:
|
||||
return qMakePair(QPoint(1, 1), (int) Qt::AlignCenter);
|
||||
default:
|
||||
return QPair<QPoint, int>();
|
||||
case ADS_NS::TopDropArea: return (int) Qt::AlignHCenter | Qt::AlignBottom;
|
||||
case ADS_NS::RightDropArea: return (int) Qt::AlignLeft | Qt::AlignVCenter;
|
||||
case ADS_NS::BottomDropArea: return (int) Qt::AlignHCenter | Qt::AlignTop;
|
||||
case ADS_NS::LeftDropArea: return (int) Qt::AlignRight | Qt::AlignVCenter;
|
||||
case ADS_NS::CenterDropArea: return (int) Qt::AlignCenter;
|
||||
default: return Qt::AlignCenter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QPoint DropOverlayCross::areaGridPosition(const DropArea area)
|
||||
{
|
||||
if (DropOverlay::ModeSectionOverlay == m_Mode)
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case ADS_NS::TopDropArea: return QPoint(1, 2);
|
||||
case ADS_NS::RightDropArea: return QPoint(2, 3);
|
||||
case ADS_NS::BottomDropArea: return QPoint(3, 2);
|
||||
case ADS_NS::LeftDropArea: return QPoint(2, 1);
|
||||
case ADS_NS::CenterDropArea: return QPoint(2, 2);
|
||||
default: return QPoint();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case ADS_NS::TopDropArea: return QPoint(0, 2);
|
||||
case ADS_NS::RightDropArea: return QPoint(2, 4);
|
||||
case ADS_NS::BottomDropArea: return QPoint(4, 2);
|
||||
case ADS_NS::LeftDropArea: return QPoint(2, 0);
|
||||
case ADS_NS::CenterDropArea: return QPoint(2, 2);
|
||||
default: return QPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DropOverlayCross::DropOverlayCross(DropOverlay* overlay) :
|
||||
QWidget(overlay->parentWidget()),
|
||||
_overlay(overlay),
|
||||
_widgets()
|
||||
m_DropOverlay(overlay)
|
||||
{
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowTitle("DropOverlayCross");
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
_grid = new QGridLayout();
|
||||
_grid->setContentsMargins(0, 0, 0, 0);
|
||||
_grid->setSpacing(6);
|
||||
|
||||
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);
|
||||
m_GridLayout = new QGridLayout();
|
||||
m_GridLayout->setSpacing(6);
|
||||
setLayout(m_GridLayout);
|
||||
}
|
||||
|
||||
DropOverlayCross::~DropOverlayCross()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DropOverlayCross::setupOverlayCross(DropOverlay::eMode Mode)
|
||||
{
|
||||
m_Mode = Mode;
|
||||
|
||||
QHash<DropArea, QWidget*> areaWidgets;
|
||||
areaWidgets.insert(TopDropArea, DropOverlay::createDropIndicatorWidget(TopDropArea));
|
||||
areaWidgets.insert(RightDropArea, DropOverlay::createDropIndicatorWidget(RightDropArea));
|
||||
areaWidgets.insert(BottomDropArea, DropOverlay::createDropIndicatorWidget(BottomDropArea));
|
||||
areaWidgets.insert(LeftDropArea, DropOverlay::createDropIndicatorWidget(LeftDropArea));
|
||||
areaWidgets.insert(CenterDropArea, DropOverlay::createDropIndicatorWidget(CenterDropArea));
|
||||
|
||||
setAreaWidgets(areaWidgets);
|
||||
}
|
||||
|
||||
|
||||
void DropOverlayCross::setAreaWidgets(const QHash<DropArea, QWidget*>& widgets)
|
||||
{
|
||||
// Delete old widgets.
|
||||
QMutableHashIterator<DropArea, QWidget*> i(_widgets);
|
||||
QMutableHashIterator<DropArea, QWidget*> i(m_DropIndicatorWidgets);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
QWidget* widget = i.value();
|
||||
_grid->removeWidget(widget);
|
||||
m_GridLayout->removeWidget(widget);
|
||||
delete widget;
|
||||
i.remove();
|
||||
}
|
||||
|
||||
// Insert new widgets into grid.
|
||||
_widgets = widgets;
|
||||
QHashIterator<DropArea, QWidget*> i2(_widgets);
|
||||
m_DropIndicatorWidgets = widgets;
|
||||
QHashIterator<DropArea, QWidget*> i2(m_DropIndicatorWidgets);
|
||||
while (i2.hasNext())
|
||||
{
|
||||
i2.next();
|
||||
const DropArea area = i2.key();
|
||||
QWidget* widget = i2.value();
|
||||
const QPair<QPoint, int> opts = gridPosForArea(area);
|
||||
_grid->addWidget(widget, opts.first.x(), opts.first.y(), (Qt::Alignment) opts.second);
|
||||
QPoint p = areaGridPosition(area);
|
||||
m_GridLayout->addWidget(widget, p.x(), p.y(), (Qt::Alignment) areaAlignment(area));
|
||||
}
|
||||
|
||||
if (DropOverlay::ModeSectionOverlay == m_Mode)
|
||||
{
|
||||
m_GridLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_GridLayout->setRowStretch(0, 1);
|
||||
m_GridLayout->setRowStretch(1, 0);
|
||||
m_GridLayout->setRowStretch(2, 0);
|
||||
m_GridLayout->setRowStretch(3, 0);
|
||||
m_GridLayout->setRowStretch(4, 1);
|
||||
|
||||
m_GridLayout->setColumnStretch(0, 1);
|
||||
m_GridLayout->setColumnStretch(1, 0);
|
||||
m_GridLayout->setColumnStretch(2, 0);
|
||||
m_GridLayout->setColumnStretch(3, 0);
|
||||
m_GridLayout->setColumnStretch(4, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GridLayout->setContentsMargins(4, 4, 4, 4);
|
||||
m_GridLayout->setRowStretch(0, 0);
|
||||
m_GridLayout->setRowStretch(1, 1);
|
||||
m_GridLayout->setRowStretch(2, 1);
|
||||
m_GridLayout->setRowStretch(3, 1);
|
||||
m_GridLayout->setRowStretch(4, 0);
|
||||
|
||||
m_GridLayout->setColumnStretch(0, 0);
|
||||
m_GridLayout->setColumnStretch(1, 1);
|
||||
m_GridLayout->setColumnStretch(2, 1);
|
||||
m_GridLayout->setColumnStretch(3, 1);
|
||||
m_GridLayout->setColumnStretch(4, 0);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
@ -376,11 +410,11 @@ void DropOverlayCross::setAreaWidgets(const QHash<DropArea, QWidget*>& widgets)
|
||||
DropArea DropOverlayCross::cursorLocation() const
|
||||
{
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
QHashIterator<DropArea, QWidget*> i(_widgets);
|
||||
QHashIterator<DropArea, QWidget*> i(m_DropIndicatorWidgets);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
if (_overlay->allowedAreas().testFlag(i.key())
|
||||
if (m_DropOverlay->allowedAreas().testFlag(i.key())
|
||||
&& i.value()
|
||||
&& i.value()->isVisible()
|
||||
&& i.value()->geometry().contains(pos))
|
||||
@ -393,24 +427,24 @@ DropArea DropOverlayCross::cursorLocation() const
|
||||
|
||||
void DropOverlayCross::showEvent(QShowEvent*)
|
||||
{
|
||||
resize(_overlay->size());
|
||||
move(_overlay->pos());
|
||||
resize(m_DropOverlay->size());
|
||||
move(m_DropOverlay->pos());
|
||||
}
|
||||
|
||||
void DropOverlayCross::reset()
|
||||
{
|
||||
QList<DropArea> allAreas;
|
||||
allAreas << ADS_NS::TopDropArea << ADS_NS::RightDropArea << ADS_NS::BottomDropArea << ADS_NS::LeftDropArea << ADS_NS::CenterDropArea;
|
||||
const DropAreas allowedAreas = _overlay->allowedAreas();
|
||||
allAreas << ADS_NS::TopDropArea << ADS_NS::RightDropArea
|
||||
<< ADS_NS::BottomDropArea << ADS_NS::LeftDropArea << ADS_NS::CenterDropArea;
|
||||
const DropAreas allowedAreas = m_DropOverlay->allowedAreas();
|
||||
|
||||
// Update visibility of area widgets based on allowedAreas.
|
||||
for (int i = 0; i < allAreas.count(); ++i)
|
||||
{
|
||||
const QPair<QPoint, int> opts = gridPosForArea(allAreas.at(i));
|
||||
|
||||
QLayoutItem* item = _grid->itemAtPosition(opts.first.x(), opts.first.y());
|
||||
QWidget* w = NULL;
|
||||
if (item && (w = item->widget()) != NULL)
|
||||
QPoint p = areaGridPosition(allAreas.at(i));
|
||||
QLayoutItem* item = m_GridLayout->itemAtPosition(p.x(), p.y());
|
||||
QWidget* w = nullptr;
|
||||
if (item && (w = item->widget()) != nullptr)
|
||||
{
|
||||
w->setVisible(allowedAreas.testFlag(allAreas.at(i)));
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "ads/FloatingWidget.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) :
|
||||
@ -77,14 +79,15 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
SectionWidget* section = NULL;
|
||||
ContainerWidget* cw = findParentContainerWidget(this);
|
||||
|
||||
// Drop contents of FloatingWidget into SectionWidget.
|
||||
if (m_FloatingWidget)
|
||||
// Drop contents of FloatingWidget into container or section widget
|
||||
if (m_FloatingWidget && cw->rect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
{
|
||||
SectionWidget* sw = cw->sectionAt(cw->mapFromGlobal(ev->globalPos()));
|
||||
DropArea loc = InvalidDropArea;
|
||||
if (sw)
|
||||
{
|
||||
cw->d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
DropArea loc = cw->d->dropOverlay->showDropOverlay(sw);
|
||||
cw->d->SectionDropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
DropArea loc = cw->d->SectionDropOverlay->showDropOverlay(sw);
|
||||
if (loc != InvalidDropArea)
|
||||
{
|
||||
InternalContentData data;
|
||||
@ -94,27 +97,20 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
cw->dropContent(data, sw, loc, true);
|
||||
}
|
||||
}
|
||||
// Mouse is over a outer-edge drop area
|
||||
else
|
||||
{
|
||||
/*DropArea dropArea = ADS_NS::InvalidDropArea;
|
||||
if (cw->outerTopDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::TopDropArea;
|
||||
if (cw->outerRightDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::RightDropArea;
|
||||
if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::BottomDropArea;
|
||||
if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::LeftDropArea;
|
||||
|
||||
if (dropArea != ADS_NS::InvalidDropArea)
|
||||
// mouse is over container
|
||||
if (InvalidDropArea == loc)
|
||||
{
|
||||
DropArea loc = cw->d->ContainerDropOverlay->cursorLocation();
|
||||
std::cout << "Cursor location: " << loc << std::endl;
|
||||
if (loc != InvalidDropArea)
|
||||
{
|
||||
InternalContentData data;
|
||||
m_FloatingWidget->takeContent(data);
|
||||
m_FloatingWidget->deleteLater();
|
||||
m_FloatingWidget.clear();
|
||||
cw->dropContent(data, NULL, dropArea, true);
|
||||
}*/
|
||||
cw->dropContent(data, nullptr, loc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of tab moving, change order now
|
||||
@ -135,12 +131,15 @@ void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
}
|
||||
|
||||
if (!m_DragStartPosition.isNull())
|
||||
{
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
// Reset
|
||||
m_DragStartPosition = QPoint();
|
||||
m_TabMoving = false;
|
||||
cw->d->dropOverlay->hideDropOverlay();
|
||||
cw->d->SectionDropOverlay->hideDropOverlay();
|
||||
cw->hideContainerOverlay();
|
||||
QFrame::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user