DiagramDesigner/diagramCavas/source/graphicsItem/graphicsRectItem.cpp

231 lines
7.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "graphicsItem/graphicsRectItem.h"
//#include "graphicsItem/itemControlHandle.h"
#include "graphicsItem/handleRect.h"
#include <QPainter>
#include <QStyleOption>
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 HandleRect(this);
pHandle1->setType(T_editShape);
pHandle1->setTag(H_edit);
m_vecHanle.insert(H_edit,pHandle1);
//纵轴Y控制点
ItemControlHandle* pHandle2 = new HandleRect(this);
pHandle2->setType(T_editShape);
pHandle2->setTag(H_edit+1);
m_vecHanle.insert(H_edit+1,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
if(m_vecHanle.contains(H_edit -1))
{
m_vecHanle[H_edit -1]->move(boundingRect.right() - boundingRect.width() * m_dRatioX, boundingRect.top());
}
if(m_vecHanle.contains(H_edit + 1 -1))
{
m_vecHanle[H_edit + 1 -1]->move(boundingRect.right(), boundingRect.top() + boundingRect.height() * m_dRatioY);
}
}
}
void GraphicsRectItem::updateCoordinate() //当执行了resie和editShape函数后boundingRect发生了变换需要将item的原点(以中心点为原点)校准至boundingRect.center()
{
if (!parentItem())
{
QPointF pt1, pt2, delta;
pt1 = mapToScene(QPointF(0, 0));
pt2 = mapToScene(m_boundingRect.center());
delta = pt1 - pt2;
prepareGeometryChange();
//将boundingRect设置成中心点和原点也是默认变换原点这样三点重合有助于简化计算
m_boundingRect = QRectF(-m_dWidth / 2, -m_dHeight / 2, m_dWidth, m_dHeight);
//setTransformOriginPoint(m_boundingRect.center()); //变换中心默认为item的(0,0)点,所以不执行这句话也没有问题
//更新bouondingRect后重回会显示位置会有变化需要做对应的移动
moveBy(-delta.x(), -delta.y());
updateHandles();
}
m_lastBoudingRect = m_boundingRect;
//qDebug() << "itemPos:" << mapToParent(pos());
}
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);
if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框
{
int nPenWidth = 1;
painter->setPen(QPen(QColor(135,206,235,180))); //蓝色的外框
painter->setBrush(QBrush(QColor(135,206,235,180)));
/*double dx = m_boundingRect_selected.x();
double dy = m_boundingRect_selected.y();
double dWidth = m_boundingRect_selected.width();
double dHeight = m_boundingRect_selected.height();
//画弧线0度是3点钟方向
if(dWidth > dHeight)
{
painter->drawRect(m_boundingRect_selected);
painter->drawChord(dx-dHeight*0.5,dy,dHeight,dHeight,90*16,180*16);
painter->drawChord(dx+dWidth-dHeight*0.5,dy,dHeight,dHeight,(-90)*16,180*16);
}
else if(dWidth < dHeight)
{
painter->drawRect(m_boundingRect_selected);
painter->drawChord(dx,dy-dWidth*0.5,dWidth,dWidth,0*16,180*16);
painter->drawChord(dx,dy+dHeight-dWidth*0.5,dWidth,dWidth,180*16,180*16);
//painter->drawChord(dx+dWidth-dHeight*0.5,dy,dHeight,dHeight,(-90)*16,180*16);
}
else
{
painter->drawEllipse(QPointF(dx+dWidth*0.5,dy+dHeight*0.5),dHeight*0.5,dHeight*0.5);
}*/
painter->drawRect(m_boundingRect_selected);
//绘制变换原点
QPointF originPoint = transformOriginPoint();
//qDebug() << "originPoint:" << originPoint;
painter->setBrush(Qt::red);
painter->drawEllipse(originPoint, 4, 4);
}
}
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)
{
QPointF ptOnItem = mapFromParent(ptMouse);
switch (nHandle)
{
//横轴X控制点
case H_edit:
{
double dMouseX = ptOnItem.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 = ptOnItem.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();
}