PowerDesigner/source/graphicsItem/graphicsRectItem.cpp

180 lines
5.1 KiB
C++
Raw Normal View History

2024-08-16 11:39:30 +08:00
#include "graphicsItem/graphicsRectItem.h"
#include "graphicsItem/itemControlHandle.h"
#include <QPainter>
GraphicsRectItem::GraphicsRectItem(const QRect &rect, bool isRound, QGraphicsItem *parent)
: GraphicsBaseItem(parent), m_bIsRound(isRound), m_dRatioX(1 / 10.0), m_dRatioY(1 / 10.0)
{
m_pen = QPen(Qt::black);
m_brush = QBrush(Qt::NoBrush);
m_lastBoudingRect = rect;
m_boundingRect = rect;
m_dWidth = rect.width();
m_dHeight = rect.height();
if (m_bIsRound) //圆角矩形添加两个圆角大小控制点
{
//横轴X控制点
ItemControlHandle* pHandle1 = new ItemControlHandle(this);
pHandle1->setType(T_editShape);
pHandle1->setTag(H_edit);
m_vecHanle.push_back(pHandle1);
//纵轴Y控制点
ItemControlHandle* pHandle2 = new ItemControlHandle(this);
pHandle2->setType(T_editShape);
pHandle2->setTag(H_edit+1);
m_vecHanle.push_back(pHandle2);
}
}
GraphicsRectItem::~GraphicsRectItem()
{
}
QPainterPath GraphicsRectItem::shape()
{
QPainterPath path;
double dHandleX = 0.0;
double dHandleY = 0.0;
if(m_dRatioX>0)
dHandleX = m_dWidth * m_dRatioX + 0.5;
if(m_dRatioY>0)
dHandleY = m_dHeight * m_dRatioY + 0.5;
if(m_bIsRound)
path.addRoundedRect(m_boundingRect, dHandleX, dHandleY);
else
path.addRect(m_boundingRect);
return path;
}
void GraphicsRectItem::updateHandles()
{
GraphicsBaseItem::updateHandles();
if(m_bIsRound && m_vecHanle.size() == H_edit + 1)
{
const QRectF& boundingRect = this->boundingRect();
//H_edit=9所以index号需要-1
m_vecHanle[H_edit -1]->move(boundingRect.right() - boundingRect.width() * m_dRatioX, boundingRect.top());
m_vecHanle[H_edit + 1 -1]->move(boundingRect.right(), boundingRect.top() + boundingRect.height() * m_dRatioY);
}
}
void GraphicsRectItem::updateCoordinate()
{
QPointF pt1, pt2, delta;
pt1 = mapToScene(transformOriginPoint());
pt2 = mapToScene(m_boundingRect.center());
delta = pt1 - pt2;
if (!parentItem())
{
prepareGeometryChange();
//创建时boundingRect原点不在中心刷新boundingRect并将变换原点设为中心点
m_boundingRect = QRectF(-m_dWidth / 2, -m_dHeight / 2, m_dWidth, m_dHeight);
setTransformOriginPoint(m_boundingRect.center());
//原点坐标变化后跟根据新坐标调整位置
moveBy(-delta.x(), -delta.y());
updateHandles();
}
m_lastBoudingRect = m_boundingRect;
}
void GraphicsRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setPen(m_pen);
painter->setBrush(m_brush);
if(m_bIsRound)
{
double dRadiusX = 0.0;
double dRadiusY = 0.0;
if(m_dRatioX>0)
dRadiusX = m_dWidth * m_dRatioX + 0.5;
if(m_dRatioY>0)
dRadiusY = m_dHeight * m_dRatioY + 0.5;
painter->drawRoundedRect(m_boundingRect, dRadiusX, dRadiusY);
}
else
painter->drawRect(m_boundingRect);
}
void GraphicsRectItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{
switch (nHandle)
{
case H_left:
case H_right:
dSY = 1; //拖拽的是左点右点,为水平缩放,忽略垂直变化
break;
case H_top:
case H_bottom:
dSX = 1; //拖拽的是顶点底点,为垂直缩放,忽略水平变化
break;
default:
break;
}
QTransform trans;
//缩放是以图元原点(中心)位置为基准,所以每帧都先移动移动到想要的基准点,缩放之后再移回
trans.translate(basePoint.x(), basePoint.y());
trans.scale(dSX, dSY);
trans.translate(-basePoint.x(), -basePoint.y());
prepareGeometryChange();
m_boundingRect = trans.mapRect(m_lastBoudingRect);
m_dWidth = m_boundingRect.width();
m_dHeight = m_boundingRect.height();
updateHandles();
}
void GraphicsRectItem::move(const QPointF& point)
{
moveBy(point.x(), point.y());
}
void GraphicsRectItem::editShape(int nHandle,const QPointF& ptMouse)
{
switch (nHandle)
{
//横轴X控制点
case H_edit:
{
double dMouseX = ptMouse.x();
if(dMouseX < m_boundingRect.center().x())
dMouseX = m_boundingRect.center().x();
else if(dMouseX > m_boundingRect.right())
dMouseX = m_boundingRect.right();
double dWidth = m_boundingRect.width();
if(dWidth == 0.0)
dWidth = 1.0;
m_dRatioX = (m_boundingRect.right() - dMouseX) / dWidth;
}
break;
//纵轴Y控制点
case H_edit + 1:
{
double dMouseY = ptMouse.y();
if(dMouseY > m_boundingRect.center().y())
dMouseY = m_boundingRect.center().y();
else if(dMouseY < m_boundingRect.top())
dMouseY = m_boundingRect.top();
double dHeight = m_boundingRect.height();
if(dHeight == 0.0)
dHeight = 1.0;
m_dRatioY = (dMouseY - m_boundingRect.top()) / dHeight;
}
break;
default:
break;
}
prepareGeometryChange();
updateHandles();
}