parent
04d29f2e9c
commit
8dc0e39b03
@ -0,0 +1,38 @@
|
|||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
#include "toolform.h"
|
||||||
|
#include "ui_toolform.h"
|
||||||
|
|
||||||
|
ToolForm::ToolForm(QWidget* adsorbWidget, AdsorbPositions adsorbPos)
|
||||||
|
: MagneticWidget(adsorbWidget, adsorbPos)
|
||||||
|
, ui(new Ui::ToolForm)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
setWindowFlags(Qt::FramelessWindowHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolForm::~ToolForm()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolForm::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
m_dragPosition = event->globalPos() - frameGeometry().topLeft();
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolForm::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolForm::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->buttons() & Qt::LeftButton) {
|
||||||
|
move(event->globalPos() - m_dragPosition);
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef TOOLFORM_H
|
||||||
|
#define TOOLFORM_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "magneticwidget.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ToolForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ToolForm : public MagneticWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ToolForm(QWidget* adsorbWidget, AdsorbPositions adsorbPos);
|
||||||
|
~ToolForm();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ToolForm *ui;
|
||||||
|
QPoint m_dragPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TOOLFORM_H
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ToolForm</class>
|
||||||
|
<widget class="QWidget" name="ToolForm">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>118</width>
|
||||||
|
<height>497</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -0,0 +1,196 @@
|
|||||||
|
#include <QDebug>
|
||||||
|
#include <QMoveEvent>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
#include "magneticwidget.h"
|
||||||
|
#include "ui_magneticwidget.h"
|
||||||
|
|
||||||
|
MagneticWidget::MagneticWidget(QWidget* adsorbWidget, AdsorbPositions adsorbPos)
|
||||||
|
: QWidget(Q_NULLPTR)
|
||||||
|
, m_adsorbPos(adsorbPos)
|
||||||
|
, m_adsorbWidget(adsorbWidget)
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_adsorbWidget);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
connect(m_adsorbWidget, &QWidget::destroyed, this, &QWidget::close);
|
||||||
|
m_adsorbWidget->installEventFilter(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MagneticWidget::~MagneticWidget()
|
||||||
|
{
|
||||||
|
if (m_adsorbWidget) {
|
||||||
|
m_adsorbWidget->removeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MagneticWidget::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if (watched != m_adsorbWidget || !event) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_adsorbed && QEvent::Move == event->type()) {
|
||||||
|
move(m_adsorbWidget->pos() - m_relativePos);
|
||||||
|
}
|
||||||
|
if (m_adsorbed && QEvent::Resize == event->type()) {
|
||||||
|
QRect parentRect;
|
||||||
|
QRect targetRect;
|
||||||
|
getGeometry(parentRect, targetRect);
|
||||||
|
QPoint pos(parentRect.left(), parentRect.top());
|
||||||
|
switch (m_curAdsorbPosition) {
|
||||||
|
case AP_OUTSIDE_LEFT:
|
||||||
|
pos.setX(pos.x() - width());
|
||||||
|
pos.setY(pos.y() - m_relativePos.y());
|
||||||
|
break;
|
||||||
|
case AP_OUTSIDE_RIGHT:
|
||||||
|
pos.setX(pos.x() + m_adsorbWidget->width());
|
||||||
|
pos.setY(pos.y() - m_relativePos.y());
|
||||||
|
break;
|
||||||
|
case AP_OUTSIDE_TOP:
|
||||||
|
pos.setX(pos.x() - m_relativePos.x());
|
||||||
|
pos.setY(pos.y() - targetRect.height());
|
||||||
|
break;
|
||||||
|
case AP_OUTSIDE_BOTTOM:
|
||||||
|
pos.setX(pos.x() - m_relativePos.x());
|
||||||
|
pos.setY(pos.y() + parentRect.height());
|
||||||
|
break;
|
||||||
|
case AP_INSIDE_LEFT:
|
||||||
|
pos.setY(pos.y() - m_relativePos.y());
|
||||||
|
break;
|
||||||
|
case AP_INSIDE_RIGHT:
|
||||||
|
pos.setX(parentRect.right() - targetRect.width());
|
||||||
|
pos.setY(pos.y() - m_relativePos.y());
|
||||||
|
break;
|
||||||
|
case AP_INSIDE_TOP:
|
||||||
|
pos.setX(pos.x() - m_relativePos.x());
|
||||||
|
break;
|
||||||
|
case AP_INSIDE_BOTTOM:
|
||||||
|
pos.setX(pos.x() - m_relativePos.x());
|
||||||
|
pos.setY(parentRect.bottom() - targetRect.height());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
move(pos);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MagneticWidget::moveEvent(QMoveEvent *event)
|
||||||
|
{
|
||||||
|
if (!m_adsorbWidget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect parentRect;
|
||||||
|
QRect targetRect;
|
||||||
|
getGeometry(parentRect, targetRect);
|
||||||
|
|
||||||
|
int parentLeft = parentRect.left();
|
||||||
|
int parentRight = parentRect.right();
|
||||||
|
int parentTop = parentRect.top();
|
||||||
|
int parentBottom = parentRect.bottom();
|
||||||
|
int targetLeft = targetRect.left();
|
||||||
|
int targetRight = targetRect.right();
|
||||||
|
int targetTop = targetRect.top();
|
||||||
|
int targetBottom = targetRect.bottom();
|
||||||
|
|
||||||
|
QPoint finalPosition = pos();
|
||||||
|
int adsorbDistance = 30;
|
||||||
|
|
||||||
|
m_adsorbed = false;
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_INSIDE_LEFT
|
||||||
|
&& parentRect.intersects(targetRect)
|
||||||
|
&& qAbs(parentLeft - targetLeft) < adsorbDistance) {
|
||||||
|
finalPosition.setX(parentLeft);
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_INSIDE_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_OUTSIDE_RIGHT
|
||||||
|
&& parentRect.intersects(targetRect.translated(-adsorbDistance, 0))
|
||||||
|
&& qAbs(parentRight - targetLeft) < adsorbDistance) {
|
||||||
|
finalPosition.setX(parentRight);
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_OUTSIDE_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_OUTSIDE_LEFT
|
||||||
|
&& parentRect.intersects(targetRect.translated(adsorbDistance, 0))
|
||||||
|
&& qAbs(parentLeft - targetRight) < adsorbDistance) {
|
||||||
|
finalPosition.setX(parentLeft - targetRect.width());
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_OUTSIDE_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_INSIDE_RIGHT
|
||||||
|
&& parentRect.intersects(targetRect)
|
||||||
|
&& qAbs(parentRight - targetRight) < adsorbDistance) {
|
||||||
|
finalPosition.setX(parentRight - targetRect.width());
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_INSIDE_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_INSIDE_TOP
|
||||||
|
&& parentRect.intersects(targetRect)
|
||||||
|
&& qAbs(parentTop - targetTop) < adsorbDistance) {
|
||||||
|
finalPosition.setY(parentTop);
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_INSIDE_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_OUTSIDE_TOP
|
||||||
|
&& parentRect.intersects(targetRect.translated(0, adsorbDistance))
|
||||||
|
&& qAbs(parentTop - targetBottom) < adsorbDistance) {
|
||||||
|
finalPosition.setY(parentTop - targetRect.height());
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_OUTSIDE_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_OUTSIDE_BOTTOM
|
||||||
|
&& parentRect.intersects(targetRect.translated(0, -adsorbDistance))
|
||||||
|
&& qAbs(parentBottom - targetTop) < adsorbDistance) {
|
||||||
|
finalPosition.setY(parentBottom);
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_OUTSIDE_BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbPos & AP_INSIDE_BOTTOM
|
||||||
|
&& parentRect.intersects(targetRect)
|
||||||
|
&& qAbs(parentBottom - targetBottom) < adsorbDistance) {
|
||||||
|
finalPosition.setY(parentBottom - targetRect.height());
|
||||||
|
m_adsorbed |= true;
|
||||||
|
m_curAdsorbPosition = AP_INSIDE_BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_adsorbed) {
|
||||||
|
m_relativePos = m_adsorbWidget->pos() - pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
move(finalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MagneticWidget::getGeometry(QRect &relativeWidgetRect, QRect &targetWidgetRect)
|
||||||
|
{
|
||||||
|
QRect parentRect = m_adsorbWidget->geometry();
|
||||||
|
QRect targetRect = geometry();
|
||||||
|
|
||||||
|
if (!m_adsorbWidget->windowFlags().testFlag(Qt::FramelessWindowHint)) {
|
||||||
|
// title bar height
|
||||||
|
int titleBarHeight = m_adsorbWidget->style()->pixelMetric(QStyle::PM_TitleBarHeight);
|
||||||
|
parentRect.translate(0, -titleBarHeight);
|
||||||
|
parentRect.setHeight(parentRect.height() + titleBarHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!windowFlags().testFlag(Qt::FramelessWindowHint)) {
|
||||||
|
// title bar height
|
||||||
|
int titleBarHeight = style()->pixelMetric(QStyle::PM_TitleBarHeight);
|
||||||
|
targetRect.translate(0, -titleBarHeight);
|
||||||
|
targetRect.setHeight(targetRect.height() + titleBarHeight);
|
||||||
|
}
|
||||||
|
relativeWidgetRect = parentRect;
|
||||||
|
targetWidgetRect = targetRect;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
#ifndef MAGNETICWIDGET_H
|
||||||
|
#define MAGNETICWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a magnetic widget
|
||||||
|
* window title bar support not good
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MagneticWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum AdsorbPosition {
|
||||||
|
AP_OUTSIDE_LEFT = 0x01, // 吸附外部左边框
|
||||||
|
AP_OUTSIDE_TOP = 0x02, // 吸附外部上边框
|
||||||
|
AP_OUTSIDE_RIGHT = 0x04, // 吸附外部右边框
|
||||||
|
AP_OUTSIDE_BOTTOM = 0x08, // 吸附外部下边框
|
||||||
|
AP_INSIDE_LEFT = 0x10, // 吸附内部左边框
|
||||||
|
AP_INSIDE_TOP = 0x20, // 吸附内部上边框
|
||||||
|
AP_INSIDE_RIGHT = 0x40, // 吸附内部右边框
|
||||||
|
AP_INSIDE_BOTTOM = 0x80, // 吸附内部下边框
|
||||||
|
AP_ALL = 0xFF, // 全吸附
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(AdsorbPositions, AdsorbPosition)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MagneticWidget(QWidget* adsorbWidget, AdsorbPositions adsorbPos = AP_ALL);
|
||||||
|
~MagneticWidget();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
void moveEvent(QMoveEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getGeometry(QRect& relativeWidgetRect, QRect& targetWidgetRect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AdsorbPositions m_adsorbPos = AP_ALL;
|
||||||
|
QPoint m_relativePos;
|
||||||
|
bool m_adsorbed = false;
|
||||||
|
QPointer<QWidget> m_adsorbWidget;
|
||||||
|
AdsorbPosition m_curAdsorbPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(MagneticWidget::AdsorbPositions)
|
||||||
|
#endif // MAGNETICWIDGET_H
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MagneticWidget</class>
|
||||||
|
<widget class="QWidget" name="MagneticWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>80</x>
|
||||||
|
<y>110</y>
|
||||||
|
<width>93</width>
|
||||||
|
<height>28</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PushButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
FORMS += \
|
||||||
|
$$PWD/magneticwidget.ui
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/magneticwidget.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/magneticwidget.cpp
|
||||||
Loading…
Reference in new issue