mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-01-12 16:20:25 +08:00
Added suppport for floating widgets with native toolbar to support the windows desktop docking and split system
This commit is contained in:
parent
0716020ab4
commit
a4de5c5560
@ -22,9 +22,13 @@ class CFloatingTitleWidget : public QFrame
|
||||
Q_OBJECT
|
||||
private:
|
||||
QPoint m_DragStartPosition;
|
||||
QPoint m_DragStartMousePosition;
|
||||
FloatingWidget* floatingWidget() const;
|
||||
MainContainerWidget* mainContainerWidget() const;
|
||||
void moveFloatingWidget(QMouseEvent* ev, MainContainerWidget* MainContainer);
|
||||
void moveFloatingWidget(QMouseEvent* ev);
|
||||
|
||||
private slots:
|
||||
void onMaximizeButtonClicked();
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent* ev);
|
||||
@ -46,6 +50,7 @@ class FloatingWidget : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
friend class MainContainerWidget;
|
||||
friend class CFloatingTitleWidget;
|
||||
|
||||
public:
|
||||
FloatingWidget(MainContainerWidget* container, SectionContent::RefPtr sc, SectionTitleWidget* titleWidget, SectionContentWidget* contentWidget, QWidget* parent = NULL);
|
||||
@ -73,6 +78,9 @@ public://private:
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *event) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
virtual bool event(QEvent *e);
|
||||
void updateDropOverlays(const QPoint& GlobalPos);
|
||||
|
||||
private slots:
|
||||
void onCloseButtonClicked();
|
||||
@ -83,8 +91,7 @@ private:
|
||||
SectionTitleWidget* _titleWidget;
|
||||
SectionContentWidget* _contentWidget;
|
||||
CContainerWidget* m_ContainerWidget;
|
||||
|
||||
//QBoxLayout* _titleLayout;
|
||||
bool m_DraggingActive = false;
|
||||
unsigned int m_zOrderIndex = 0;
|
||||
static unsigned int zOrderCounter;
|
||||
};
|
||||
|
@ -28,7 +28,8 @@ public:
|
||||
{
|
||||
None = 0,
|
||||
Closeable = 1,
|
||||
AllFlags = Closeable
|
||||
Maximizable = 2,
|
||||
AllFlags = Closeable | Maximizable
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QStyle>
|
||||
#include <QLabel>
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include "ads/SectionTitleWidget.h"
|
||||
#include "ads/SectionContentWidget.h"
|
||||
@ -31,23 +32,40 @@ CFloatingTitleWidget::CFloatingTitleWidget(SectionContent::Flags Flags, Floating
|
||||
Label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
Label->setAlignment(Qt::AlignLeft);
|
||||
Layout->addWidget(Label, 1, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
Layout->setSpacing(0);
|
||||
setLayout(Layout);
|
||||
|
||||
if (Flags.testFlag(SectionContent::Maximizable))
|
||||
{
|
||||
QPushButton* Button = new QPushButton();
|
||||
Button->setObjectName("maximizeButton");
|
||||
Button->setFlat(true);
|
||||
Button->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton));
|
||||
Button->setToolTip(tr("Close"));
|
||||
Button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
Layout->addWidget(Button);
|
||||
connect(Button, SIGNAL(clicked(bool)), this, SLOT(onMaximizeButtonClicked()));
|
||||
}
|
||||
|
||||
if (Flags.testFlag(SectionContent::Closeable))
|
||||
{
|
||||
QPushButton* closeButton = new QPushButton();
|
||||
closeButton->setObjectName("closeButton");
|
||||
closeButton->setFlat(true);
|
||||
closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
closeButton->setToolTip(tr("Close"));
|
||||
closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
closeButton->setToolTip(tr("Maximize"));
|
||||
closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
Layout->addWidget(closeButton);
|
||||
connect(closeButton, SIGNAL(clicked(bool)), this, SIGNAL(closeButtonClicked()));
|
||||
Layout->setContentsMargins(6, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (Flags == 0)
|
||||
{
|
||||
Layout->setContentsMargins(6, 6, 6, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
Layout->setContentsMargins(6, 6, 6, 6);
|
||||
Layout->setContentsMargins(6, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +85,8 @@ void CFloatingTitleWidget::mousePressEvent(QMouseEvent* ev)
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
ev->accept();
|
||||
//m_DragStartPosition = ev->pos();
|
||||
m_DragStartPosition = floatingWidget()->pos();
|
||||
m_DragStartMousePosition = ev->globalPos();
|
||||
return;
|
||||
}
|
||||
QFrame::mousePressEvent(ev);
|
||||
@ -88,62 +107,37 @@ void CFloatingTitleWidget::mouseMoveEvent(QMouseEvent* ev)
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint Pos = QCursor::pos();
|
||||
// TODO make a member with the main container widget and assign it on
|
||||
// creation
|
||||
MainContainerWidget* MainContainerWidget = mainContainerWidget();
|
||||
auto Containers = MainContainerWidget->m_Containers;
|
||||
CContainerWidget* TopContainer = nullptr;
|
||||
for (auto ContainerWidget : Containers)
|
||||
{
|
||||
if (!ContainerWidget->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
floatingWidget()->updateDropOverlays(ev->globalPos());
|
||||
ev->accept();
|
||||
moveFloatingWidget(ev);
|
||||
}
|
||||
|
||||
if (floatingWidget()->containerWidget() == ContainerWidget)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QPoint MappedPos = ContainerWidget->mapFromGlobal(Pos);
|
||||
if (ContainerWidget->rect().contains(MappedPos))
|
||||
{
|
||||
std::cout << "Container " << ContainerWidget << " contains maousepos" << std::endl;
|
||||
if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
|
||||
{
|
||||
TopContainer = ContainerWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CFloatingTitleWidget::moveFloatingWidget(QMouseEvent* ev)
|
||||
{
|
||||
const QPoint DragDistance = ev->globalPos() - m_DragStartMousePosition;
|
||||
const QPoint moveToPos = m_DragStartPosition + DragDistance;
|
||||
floatingWidget()->move(moveToPos);
|
||||
}
|
||||
|
||||
if (TopContainer)
|
||||
|
||||
void CFloatingTitleWidget::onMaximizeButtonClicked()
|
||||
{
|
||||
if (floatingWidget()->isMaximized())
|
||||
{
|
||||
MainContainerWidget->dropOverlay()->showDropOverlay(TopContainer);
|
||||
MainContainerWidget->dropOverlay()->raise();
|
||||
floatingWidget()->showNormal();
|
||||
}
|
||||
else
|
||||
{
|
||||
MainContainerWidget->dropOverlay()->hideDropOverlay();
|
||||
floatingWidget()->showMaximized();
|
||||
}
|
||||
|
||||
ev->accept();
|
||||
moveFloatingWidget(ev, MainContainerWidget);
|
||||
}
|
||||
|
||||
|
||||
void CFloatingTitleWidget::moveFloatingWidget(QMouseEvent* ev, MainContainerWidget* cw)
|
||||
{
|
||||
const QPoint moveToPos = ev->globalPos() - (m_DragStartPosition + QPoint(ADS_WINDOW_FRAME_BORDER_WIDTH, ADS_WINDOW_FRAME_BORDER_WIDTH));
|
||||
floatingWidget()->move(moveToPos);
|
||||
// cw->moveFloatingWidget(moveToPos);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
FloatingWidget::FloatingWidget(MainContainerWidget* container, SectionContent::RefPtr sc, SectionTitleWidget* titleWidget, SectionContentWidget* contentWidget, QWidget* parent) :
|
||||
QWidget(parent, Qt::CustomizeWindowHint | Qt::Tool),
|
||||
QWidget(parent, Qt::Window/*Qt::CustomizeWindowHint | Qt::Tool*/),
|
||||
m_MainContainerWidget(container),
|
||||
_content(sc),
|
||||
_titleWidget(titleWidget),
|
||||
@ -155,12 +149,9 @@ FloatingWidget::FloatingWidget(MainContainerWidget* container, SectionContent::R
|
||||
setLayout(l);
|
||||
|
||||
// Title + Controls
|
||||
CFloatingTitleWidget* TitleBar = new CFloatingTitleWidget(sc->flags(), this);
|
||||
/*CFloatingTitleWidget* TitleBar = new CFloatingTitleWidget(sc->flags(), this);
|
||||
l->insertWidget(0, TitleBar);
|
||||
connect(TitleBar, SIGNAL(closeButtonClicked()), this, SLOT(onCloseButtonClicked()));
|
||||
|
||||
//l->addWidget(contentWidget, 1);
|
||||
//contentWidget->show();
|
||||
connect(TitleBar, SIGNAL(closeButtonClicked()), this, SLOT(onCloseButtonClicked()));*/
|
||||
|
||||
m_ContainerWidget = new CContainerWidget(m_MainContainerWidget, this);
|
||||
l->addWidget(m_ContainerWidget, 1);
|
||||
@ -236,10 +227,87 @@ void FloatingWidget::changeEvent(QEvent *event)
|
||||
}
|
||||
|
||||
|
||||
void FloatingWidget::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
QWidget::moveEvent(event);
|
||||
if (m_DraggingActive)
|
||||
{
|
||||
std::cout << "Dragging" << std::endl;
|
||||
updateDropOverlays(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FloatingWidget::event(QEvent *e)
|
||||
{
|
||||
//std::cout << "FloatingWidget::event " << e->type() << std::endl;
|
||||
if ((e->type() == QEvent::NonClientAreaMouseButtonPress))
|
||||
{
|
||||
if (QGuiApplication::mouseButtons() == Qt::LeftButton)
|
||||
{
|
||||
m_DraggingActive = true;
|
||||
}
|
||||
}
|
||||
else if ((e->type() == QEvent::NonClientAreaMouseButtonRelease) && m_DraggingActive)
|
||||
{
|
||||
m_DraggingActive = false;
|
||||
std::cout << "Dropped" << std::endl;
|
||||
}
|
||||
else if (e->type() == QEvent::WindowActivate)
|
||||
{
|
||||
m_DraggingActive = true;
|
||||
std::cout << "QEvent::WindowActivate MouseButtons " << QGuiApplication::mouseButtons() << std::endl;
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
|
||||
unsigned int FloatingWidget::zOrderIndex() const
|
||||
{
|
||||
return m_zOrderIndex;
|
||||
}
|
||||
|
||||
|
||||
void FloatingWidget::updateDropOverlays(const QPoint& GlobalPos)
|
||||
{
|
||||
// TODO make a member with the main container widget and assign it on
|
||||
// creation
|
||||
MainContainerWidget* MainContainerWidget = mainContainerWidget();
|
||||
auto Containers = MainContainerWidget->m_Containers;
|
||||
CContainerWidget* TopContainer = nullptr;
|
||||
for (auto ContainerWidget : Containers)
|
||||
{
|
||||
if (!ContainerWidget->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (containerWidget() == ContainerWidget)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
||||
if (ContainerWidget->rect().contains(MappedPos))
|
||||
{
|
||||
std::cout << "Container " << ContainerWidget << " contains mousepos" << std::endl;
|
||||
if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
|
||||
{
|
||||
TopContainer = ContainerWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TopContainer)
|
||||
{
|
||||
MainContainerWidget->dropOverlay()->showDropOverlay(TopContainer);
|
||||
MainContainerWidget->dropOverlay()->raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
MainContainerWidget->dropOverlay()->hideDropOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
|
Loading…
Reference in New Issue
Block a user