#pragma execution_character_set("utf-8")
#include "selectwidget.h"
SelectWidget::SelectWidget(QWidget *parent) : QWidget(parent)
{
drawPoint = false;
padding = 5;
borderWidth = 1;
pointSize = 8;
pointColor = QColor(34, 163, 168);
pointStyle = PointStyle:: PointStyle_Rect;
pressed = false;
pressedLeft = false;
pressedRight = false;
pressedTop = false;
pressedBottom = false;
pressedLeftTop = false;
pressedRightTop = false;
pressedLeftBottom = false;
pressedRightBottom = false;
widget = 0;
// 增加:控件的类型的和指针
m_Type = VALUE_TYPE::Type_Unknown;
m_pProperty = nullptr;
// 扩展属性
m_pPropertyEx = nullptr;
//设置鼠标追踪为真,并绑定事件过滤器,可以获取焦点用于按键移动位置
this->setMouseTracking(true);
//安装事件过滤器,识别鼠标拖动和拉伸大小
this->installEventFilter(this);
//设置焦点策略,以便鼠标按下获取焦点并手柄可见
this->setFocusPolicy(Qt::StrongFocus);
}
///
/// 拦截所属的控件事件
///
///
///
///
bool SelectWidget::eventFilter(QObject *watched, QEvent *event)
{
// 拦截键盘事件
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = dynamic_cast(event);
if (keyEvent->key() == Qt::Key_Left)
{
this->move(this->pos() - QPoint(1, 0));
} else if (keyEvent->key() == Qt::Key_Right)
{
this->move(this->pos() + QPoint(1, 0));
} else if (keyEvent->key() == Qt::Key_Up)
{
this->move(this->pos() - QPoint(0, 1));
} else if (keyEvent->key() == Qt::Key_Down)
{
this->move(this->pos() + QPoint(0, 1));
} else if (keyEvent->key() == Qt::Key_Delete)
{
emit widgetDelete(widget);
widget->deleteLater();
this->deleteLater();
widget = 0;
}
//重新设置附带窗体的位置和大小
if (widget != 0) {
widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
}
return QWidget::eventFilter(watched, event);
}
QMouseEvent *mouseEvent = static_cast(event);
if (mouseEvent->type() == QEvent::MouseButtonPress)
{
//记住当前控件坐标和宽高以及鼠标按下的坐标
rectX = this->x();
rectY = this->y();
rectW = this->width();
rectH = this->height();
lastPos = mouseEvent->pos();
//判断按下的手柄的区域位置
if (rectLeft.contains(lastPos)) {
pressedLeft = true;
} else if (rectRight.contains(lastPos)) {
pressedRight = true;
} else if (rectTop.contains(lastPos)) {
pressedTop = true;
} else if (rectBottom.contains(lastPos)) {
pressedBottom = true;
} else if (rectLeftTop.contains(lastPos)) {
pressedLeftTop = true;
} else if (rectRightTop.contains(lastPos)) {
pressedRightTop = true;
} else if (rectLeftBottom.contains(lastPos)) {
pressedLeftBottom = true;
} else if (rectRightBottom.contains(lastPos)) {
pressedRightBottom = true;
} else {
pressed = true;
}
if (widget != 0)
{
emit widgetPressed(widget);
}
}
else if (mouseEvent->type() == QEvent::MouseMove)
{
//根据当前鼠标位置,计算XY轴移动了多少
QPoint pos = mouseEvent->pos();
int dx = pos.x() - lastPos.x();
int dy = pos.y() - lastPos.y();
//根据按下处的位置判断是否是移动控件还是拉伸控件
if (pressed)
{
this->move(this->x() + dx, this->y() + dy);
}
else if (pressedLeft)
{
int resizeW = this->width() - dx;
if (this->minimumWidth() <= resizeW)
{
this->setGeometry(this->x() + dx, rectY, resizeW, rectH);
}
}
else if (pressedRight)
{
this->setGeometry(rectX, rectY, rectW + dx, rectH);
}
else if (pressedTop)
{
int resizeH = this->height() - dy;
if (this->minimumHeight() <= resizeH)
{
this->setGeometry(rectX, this->y() + dy, rectW, resizeH);
}
}
else if (pressedBottom)
{
this->setGeometry(rectX, rectY, rectW, rectH + dy);
}
else if (pressedLeftTop)
{
int resizeW = this->width() - dx;
int resizeH = this->height() - dy;
if (this->minimumWidth() <= resizeW) {
this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
}
if (this->minimumHeight() <= resizeH) {
this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
}
}
else if (pressedRightTop)
{
int resizeW = rectW + dx;
int resizeH = this->height() - dy;
if (this->minimumHeight() <= resizeH) {
this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
}
}
else if (pressedLeftBottom)
{
int resizeW = this->width() - dx;
int resizeH = rectH + dy;
if (this->minimumWidth() <= resizeW) {
this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
}
if (this->minimumHeight() <= resizeH) {
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
}
}
else if (pressedRightBottom)
{
int resizeW = rectW + dx;
int resizeH = rectH + dy;
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
}
//重新设置附带窗体的位置和大小
if (widget != 0)
{
widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
}
// 2022-3-20修改,如果和上次的区域区域有变化,则发出控件移动信号,用于向属性表同步
if( this->geometry()!= oldGeometry )
{
// emit widgetMove(widget);
oldGeometry = this->geometry();
}
}
else if (mouseEvent->type() == QEvent::MouseButtonRelease)
{
pressed = false;
pressedLeft = false;
pressedRight = false;
pressedTop = false;
pressedBottom = false;
pressedLeftTop = false;
pressedRightTop = false;
pressedLeftBottom = false;
pressedRightBottom = false;
if (widget != 0)
{
emit widgetRelease(widget);
}
}
return QWidget::eventFilter(watched, event);
}
void SelectWidget::resizeEvent(QResizeEvent *)
{
// qDebug() << "SelectWidget::resizeEvent";
//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
double width = this->width();
double height = this->height();
//左侧描点区域
rectLeft = QRectF(0, int( height / 2.0 - pointSize / 2.0), pointSize, pointSize);
//上侧描点区域
rectTop = QRectF(int(width / 2 - pointSize / 2), 0, pointSize, pointSize);
//右侧描点区域
rectRight = QRectF(int(width - pointSize),int( height / 2 - pointSize / 2), pointSize, pointSize);
//下侧描点区域
rectBottom = QRectF(int(width / 2 - pointSize / 2), height - pointSize, pointSize, pointSize);
//左上角描点区域
rectLeftTop = QRectF(0, 0, pointSize, pointSize);
//右上角描点区域
rectRightTop = QRectF(int(width - pointSize), 0, pointSize, pointSize);
//左下角描点区域
rectLeftBottom = QRectF(0, int(height - pointSize), pointSize, pointSize);
//右下角描点区域
rectRightBottom = QRectF(width - pointSize, height - pointSize, pointSize, pointSize);
}
void SelectWidget::mouseMoveEvent(QMouseEvent *e)
{
// qDebug() << "SelectWidget::mouseMoveEvent";
//计算当前鼠标位置是否在某个区域内,自动更新鼠标形状
QPoint p = e->pos();
if (rectLeft.contains(p)) {
this->setCursor(Qt::SizeHorCursor);
} else if (rectTop.contains(p)) {
this->setCursor(Qt::SizeVerCursor);
} else if (rectRight.contains(p)) {
this->setCursor(Qt::SizeHorCursor);
} else if (rectBottom.contains(p)) {
this->setCursor(Qt::SizeVerCursor);
} else if (rectLeftTop.contains(p)) {
this->setCursor(Qt::SizeFDiagCursor);
} else if (rectRightTop.contains(p)) {
this->setCursor(Qt::SizeBDiagCursor);
} else if (rectLeftBottom.contains(p)) {
this->setCursor(Qt::SizeBDiagCursor);
} else if (rectRightBottom.contains(p)) {
this->setCursor(Qt::SizeFDiagCursor);
} else {
this->setCursor(Qt::ArrowCursor);
}
}
void SelectWidget::paintEvent(QPaintEvent *)
{
if (!drawPoint) {
return;
}
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
painter.setBrush(pointColor);
if (pointStyle == PointStyle::PointStyle_Rect)
{
drawRect(&painter);
} else if (pointStyle == PointStyle:: PointStyle_Circle)
{
drawCircle(&painter);
}
if (borderWidth > 0)
{
drawBorder(&painter);
}
}
void SelectWidget::drawRect(QPainter *painter)
{
//逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
painter->save();
painter->drawRect(rectLeft);
painter->drawRect(rectRight);
painter->drawRect(rectTop);
painter->drawRect(rectBottom);
painter->drawRect(rectLeftTop);
painter->drawRect(rectRightTop);
painter->drawRect(rectLeftBottom);
painter->drawRect(rectRightBottom);
painter->restore();
}
void SelectWidget::drawCircle(QPainter *painter)
{
//逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
painter->save();
painter->drawEllipse(rectLeft);
painter->drawEllipse(rectRight);
painter->drawEllipse(rectTop);
painter->drawEllipse(rectBottom);
painter->drawEllipse(rectLeftTop);
painter->drawEllipse(rectRightTop);
painter->drawEllipse(rectLeftBottom);
painter->drawEllipse(rectRightBottom);
painter->restore();
}
void SelectWidget::drawBorder(QPainter *painter)
{
painter->save();
QPen pen;
pen.setWidth(borderWidth);
pen.setColor(pointColor);
painter->setPen(pen);
painter->setBrush(Qt::NoBrush);
QRectF borderRect( int( pointSize / 2), int(pointSize / 2), int(width() - pointSize), int (height() - pointSize));
painter->drawRect(borderRect);
painter->restore();
}
bool SelectWidget::getDrawPoint() const
{
return this->drawPoint;
}
int SelectWidget::getPadding() const
{
return this->padding;
}
int SelectWidget::getBorderWidth() const
{
return this->borderWidth;
}
int SelectWidget::getPointSize() const
{
return this->pointSize;
}
QColor SelectWidget::getPointColor() const
{
return this->pointColor;
}
SelectWidget::PointStyle SelectWidget::getPointStyle() const
{
return this->pointStyle;
}
QWidget *SelectWidget::getWidget() const
{
return widget;
}
QSize SelectWidget::sizeHint() const
{
return QSize(200, 200);
}
QSize SelectWidget::minimumSizeHint() const
{
return QSize(30, 30);
}
void SelectWidget::setDrawPoint(bool drawPoint)
{
if (this->drawPoint != drawPoint) {
this->drawPoint = drawPoint;
update();
}
}
void SelectWidget::setPadding(int padding)
{
if (this->padding != padding) {
this->padding = padding;
update();
}
}
void SelectWidget::setBorderWidth(int borderWidth)
{
if (this->borderWidth != borderWidth) {
this->borderWidth = borderWidth;
update();
}
}
void SelectWidget::setPointSize(int pointSize)
{
if (this->pointSize != pointSize) {
this->pointSize = pointSize;
update();
}
}
void SelectWidget::setPointColor(const QColor &pointColor)
{
if (this->pointColor != pointColor) {
this->pointColor = pointColor;
update();
}
}
void SelectWidget::setPointStyle(const SelectWidget::PointStyle &pointStyle)
{
if (this->pointStyle != pointStyle) {
this->pointStyle = pointStyle;
update();
}
}
void SelectWidget::setWidget(QWidget *widget)
{
this->widget = widget;
this->widget->setVisible(true);
this->setVisible(true);
//设置最小尺寸
this->setMinimumSize(30, 30);
//设置当前窗体大小为跟随窗体的大小增加部分
this->resize(this->widget->size() + QSize(padding * 2, padding * 2));
//将当前窗体移到偏移位置
this->move(this->widget->pos() - QPoint(padding, padding));
}