1
0
mirror of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git synced 2025-04-01 02:42:39 +08:00
Qt-Advanced-Docking-System/AdvancedDockingSystem/src/SectionTitleWidget.cpp

228 lines
6.1 KiB
C++

#include "ads/SectionTitleWidget.h"
#include <QString>
#include <QApplication>
#include <QBoxLayout>
#include <QMouseEvent>
#include <QMimeData>
#include <QDrag>
#include <QCursor>
#include <QStyle>
#include <QSplitter>
#ifdef ADS_ANIMATIONS_ENABLED
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#endif
#include "ads/Internal.h"
#include "ads/DropOverlay.h"
#include "ads/SectionContent.h"
#include "ads/SectionWidget.h"
#include "ads/FloatingWidget.h"
#include "ads/ContainerWidget.h"
#include <iostream>
ADS_NAMESPACE_BEGIN
SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) :
QFrame(parent),
m_Content(content),
m_TabMoving(false),
m_IsActiveTab(false)
{
QBoxLayout* l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);
l->addWidget(content->titleWidget());
setLayout(l);
}
SectionTitleWidget::~SectionTitleWidget()
{
layout()->removeWidget(m_Content->titleWidget());
}
bool SectionTitleWidget::isActiveTab() const
{
return m_IsActiveTab;
}
void SectionTitleWidget::setActiveTab(bool active)
{
if (active != m_IsActiveTab)
{
m_IsActiveTab = active;
style()->unpolish(this);
style()->polish(this);
update();
emit activeTabChanged();
}
}
void SectionTitleWidget::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
ev->accept();
m_DragStartPosition = ev->pos();
return;
}
QFrame::mousePressEvent(ev);
}
void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
{
SectionWidget* section = NULL;
ContainerWidget* cw = findParentContainerWidget(this);
// 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->SectionDropOverlay->setAllowedAreas(ADS_NS::AllAreas);
DropArea loc = cw->d->SectionDropOverlay->showDropOverlay(sw);
if (loc != InvalidDropArea)
{
InternalContentData data;
m_FloatingWidget->takeContent(data);
m_FloatingWidget->deleteLater();
m_FloatingWidget.clear();
cw->dropContent(data, sw, loc, true);
}
}
// 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, nullptr, loc, true);
}
}
}
// End of tab moving, change order now
else if (m_TabMoving
&& (section = findParentSectionWidget(this)) != NULL)
{
// Find tab under mouse
QPoint pos = ev->globalPos();
pos = section->mapFromGlobal(pos);
int fromIndex = section->indexOfContent(m_Content);
int toIndex = section->indexOfContentByTitlePos(pos, this);
qInfo() << "fromIndex: " << fromIndex << " toIndex: " << toIndex;
if (-1 == toIndex)
{
toIndex = section->indexOfContent(section->contents().last());
}
section->moveContent(fromIndex, toIndex);
}
if (!m_DragStartPosition.isNull())
{
emit clicked();
}
// Reset
m_DragStartPosition = QPoint();
m_TabMoving = false;
cw->d->SectionDropOverlay->hideDropOverlay();
cw->hideContainerOverlay();
QFrame::mouseReleaseEvent(ev);
}
void SectionTitleWidget::moveFloatingWidget(QMouseEvent* ev, ContainerWidget* cw)
{
const QPoint moveToPos = ev->globalPos() - (m_DragStartPosition + QPoint(ADS_WINDOW_FRAME_BORDER_WIDTH, ADS_WINDOW_FRAME_BORDER_WIDTH));
m_FloatingWidget->move(moveToPos);
cw->moveFloatingWidget(moveToPos);
}
void SectionTitleWidget::startFloating(QMouseEvent* ev, ContainerWidget* cw, SectionWidget* sectionwidget)
{
QPoint moveToPos = ev->globalPos() - (m_DragStartPosition + QPoint(ADS_WINDOW_FRAME_BORDER_WIDTH, ADS_WINDOW_FRAME_BORDER_WIDTH));
m_FloatingWidget = cw->startFloating(sectionwidget, m_Content->uid(), moveToPos);
}
void SectionTitleWidget::moveTab(QMouseEvent* ev)
{
ev->accept();
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QPoint moveToPos = mapToParent(ev->pos()) - m_DragStartPosition;
moveToPos.setY(0/* + top*/);
move(moveToPos);
}
void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev)
{
if (!(ev->buttons() & Qt::LeftButton))
{
QFrame::mouseMoveEvent(ev);
return;
}
ev->accept();
ContainerWidget* cw = findParentContainerWidget(this);
// Move already existing FloatingWidget
if (m_FloatingWidget)
{
moveFloatingWidget(ev, cw);
return;
}
SectionWidget* sectionwidget = findParentSectionWidget(this);
if (!sectionwidget)
{
QFrame::mouseMoveEvent(ev);
return;
}
// move tab
if (m_TabMoving)
{
moveTab(ev);
}
// leave if dragging is not active
if (m_DragStartPosition.isNull())
{
QFrame::mouseMoveEvent(ev);
return;
}
// Begin to drag/float the SectionContent.
if (!sectionwidget->titleAreaGeometry().contains(sectionwidget->mapFromGlobal(ev->globalPos())))
{
startFloating(ev, cw, sectionwidget);
return;
}
// Begin to drag title inside the title area to switch its position inside the SectionWidget.
else if ((ev->pos() - m_DragStartPosition).manhattanLength() >= QApplication::startDragDistance() // Wait a few pixels before start moving
&& sectionwidget->titleAreaGeometry().contains(sectionwidget->mapFromGlobal(ev->globalPos())))
{
m_TabMoving = true;
raise(); // Raise current title-widget above other tabs
return;
}
QFrame::mouseMoveEvent(ev);
}
ADS_NAMESPACE_END