DiagramDesigner/diagramCavas/include/graphicsItem/electricConnectLineItem.h

98 lines
4.3 KiB
C++

#ifndef ELECTRICCONNECTLINEITEM_H
#define ELECTRICCONNECTLINEITEM_H
#include <QPainterPath>
#include <QUuid>
#include "graphicsBaseItem.h"
class ElectricConnectLineItem : public GraphicsProjectModelItem
{
public:
enum UShapeType {
UShape_Unknown,
UShape_TopOpen, // 开口向上
UShape_BottomOpen, // 开口向下
UShape_LeftOpen, // 开口向左
UShape_RightOpen // 开口向右
};
public:
ElectricConnectLineItem(QGraphicsItem *parent = 0);
ElectricConnectLineItem(const ElectricConnectLineItem&); //暂不拷贝位置关系,由线自己计算
virtual ~ElectricConnectLineItem();
virtual ElectricConnectLineItem* clone() const override;
void setStartPoint(const QPointF& p);
void setEndPoint(const QPointF& p);
QPainterPath getPoints(void) const { return m_points; }
void startDrag(const QPointF& scenePos);
void updateDrag(const QPointF& scenePos);
void endDrag();
void setLastPoint(const QPointF& point);
void setPath(const QPainterPath& path);
QPainterPath path() const;
void resetCurLine(){_curLine = QPoint();}
void calculatePath();
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
protected:
void initial();
private:
//路径计算相关
void generateAvoidancePath(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacleShapes); // 使用形状进行避障
double calculatePathLength(const QList<QPointF>& path);
bool lineIntersectsRect(const QLineF& line, const QRectF& rect) const;
bool isSegmentSafe(const QPointF& p1, const QPointF& p2,const QList<QRectF>& components);
bool isPathSafe(const QList<QPointF>& path,const QList<QRectF>& components);
bool segmentPenetratesComponent(const QLineF& segment,const QRectF& component);
QRectF getTotalComponentsBounds(const QList<QRectF>& components);
void collectRectilinearPaths(const QPointF& start, const QPointF& end,const QList<QRectF>& components,QMultiMap<double, QList<QPointF>>& paths);
void addPathIfRectilinear(const QList<QPointF>& path,QMultiMap<double, QList<QPointF>>& paths);
void collectBypassPaths(const QPointF& start, const QPointF& end,const QList<QRectF>& components,QMultiMap<double, QList<QPointF>>& paths);
void generateForcedRectilinearBypass(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
QRectF findFirstBlockingComponent(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
//线段拖拽相关
double distancePointToLine(const QLineF& line, const QPointF& point) const;
void ensureEnoughPointsForDrag();
void debugPathState(const QString& context) const;
QVector<QLineF> extractSegmentsFromPainterPath() const;
void collectBoundaryBypassPaths(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacles,QMultiMap<double, QList<QPointF>>& paths);
void collectBoundaryPath(const QPointF& start, const QPointF& end,const QList<QRectF>& obstacles,QMultiMap<double, QList<QPointF>>& paths,const QRectF& bounds, bool useTop);
QRectF getSceneBounds() const;
QList<QPointF> generateForcedBypass(const QPointF& start, const QPointF& end,const QList<QRectF>& components);
// 拖拽实现
int findSegmentAt(const QList<QPointF>& points,const QPointF& itemPos) const;
double distanceToSegment(const QLineF& segment, const QPointF& point) const;
void fixConnections(int segmentIndex, bool isVertical);
QList<QPointF> extractPointsFromPath() const;
QList<QPointF> extractPointsFromPath(const QPainterPath& path) const;
void applyPointsToPath(const QList<QPointF>& points);
void fixConnections(QList<QPointF>& points, int segmentIndex, bool isVertical);
void validateAndFixPath();
void updateBoundingRect();
private:
QPainterPath m_points;
QList<QPointF> m_lstPoints;
QPoint _curLine; //参数1用点序号表示的当前线段起始点,参数2表示线段方向
struct DragState {
bool isActive = false;
int segmentIndex = -1;
bool isVertical = false;
QPointF startScenePos;
QPainterPath originalPath;
};
DragState m_dragData;
};
#endif