PowerDesigner/include/graphicsItem/graphicsBaseItem.h

212 lines
6.4 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.

#ifndef GRAPHICSBASEITEM_H
#define GRAPHICSBASEITEM_H
#include "itemControlHandle.h"
#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QPen>
//基类采用模板形式QGraphicsItem是默认值,也可以是别的类型比如QGraphicsItemGroup这样不同的基类继承可以共用一些高层的行为定义
template <typename BaseType = QGraphicsItem>
class AbstractShapeType : public BaseType
{
public:
explicit AbstractShapeType(QGraphicsItem *parent = 0)
: BaseType(parent)
{
m_pen = QPen(Qt::NoPen);
m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
m_dWidth = m_dHeight = 0;
m_pMovingCopy = nullptr;
}
virtual ~AbstractShapeType()
{
for (size_t i = 0; i < m_vecHanle.size(); i++)
{
ItemControlHandle* pHandle = m_vecHanle[i];
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
}
}
public:
QPen pen() { return m_pen; }
void setPen(const QPen &pen) { m_pen = pen; }
QColor penColor() { return m_pen.color(); }
void setPenColor(const QColor &color) { m_pen.setColor(color); }
QBrush brush() { return m_brush; }
void setBrush(const QBrush &brush) { m_brush = brush; }
QColor brushColor() { return m_brush.color(); }
void setBrushColor(const QColor &color) { m_brush.setColor(color); }
double width() { return m_dWidth; }
void setWidth(double width)
{
m_dWidth = width;
updateCoordinate();
}
double height() { return m_dHeight; }
void setHeight(double height)
{
m_dHeight = height;
updateCoordinate();
}
int collidesWithHandle(const QPointF& point)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
QPointF pt = (*it)->mapFromScene(point);
if((*it)->contains(pt))
return (*it)->getTag();
}
return HandleTag::H_none;
}
//移动副本相关
virtual void createMovingCopy() {}
virtual void removeMovingCopy() {}
virtual void moveMovingCopy(const QPointF&) {}
virtual void resize(int,double, double, const QPointF&) {}
virtual void move(const QPointF&) {}
virtual void editShape(int, const QPointF&) {}
virtual void updateCoordinate() {}
//handle相关
virtual int handleCount() { return m_vecHanle.count(); }
virtual void setHandleVisible(bool bVisible)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if(bVisible)
(*it)->show();
else
(*it)->hide();
}
}
virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
{
QPointF pt;
//编号从1开始因此下标需要-1
switch (nHandle)
{
case H_leftTop:
pt = m_vecHanle.at(H_rightBottom - 1)->pos();
break;
case H_top:
pt = m_vecHanle.at(H_bottom - 1)->pos();
break;
case H_rightTop:
pt = m_vecHanle.at(H_leftBottom - 1)->pos();
break;
case H_right:
pt = m_vecHanle.at(H_left - 1)->pos();
break;
case H_rightBottom:
pt = m_vecHanle.at(H_leftTop - 1)->pos();
break;
case H_bottom:
pt = m_vecHanle.at(H_top - 1)->pos();
break;
case H_leftBottom:
pt = m_vecHanle.at(H_rightTop - 1)->pos();
break;
case H_left:
pt = m_vecHanle.at(H_right - 1)->pos();
break;
default:
break;
}
return pt;
}
virtual void updateHandles()
{
int nMargin = 5;
const QRectF& boundRect = this->boundingRect();
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
switch ((*it)->getTag()) {
case H_leftTop:
(*it)->move(boundRect.x() - nMargin, boundRect.y() - nMargin);
break;
case H_top:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() - nMargin);
break;
case H_rightTop:
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() - nMargin);
break;
case H_right:
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() * 0.5 + nMargin);
break;
case H_rightBottom:
(*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() + nMargin);
break;
case H_bottom:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height()+ nMargin);
break;
case H_leftBottom:
(*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() + nMargin);
break;
case H_left:
(*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() * 0.5);
break;
default:
break;
}
}
}
protected:
virtual QRectF boundingRect() const { return m_boundingRect; }
virtual QPainterPath shape()
{
QPainterPath path;
return path;
}
protected:
QPen m_pen;
QBrush m_brush;
double m_dWidth;
double m_dHeight;
QRectF m_boundingRect;
QGraphicsPathItem* m_pMovingCopy; //图元移动时的副本
QPointF m_movingIniPos; //移动副本开始移动初始点
QVector<ItemControlHandle*> m_vecHanle;
};
class GraphicsBaseItem : public QObject, public AbstractShapeType<QGraphicsItem>
{
Q_OBJECT
public:
GraphicsBaseItem(QGraphicsItem *parent);
virtual ~GraphicsBaseItem();
virtual void createMovingCopy();
virtual void removeMovingCopy();
virtual void moveMovingCopy(const QPointF&);
//多边形、线段等点选创建的对象需要的函数
virtual void addPoint(const QPointF&) {}
virtual bool endDrawing() { return true; }
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
};
#endif