File indexing completed on 2024-05-19 05:40:34

0001 #include "controller/item_controllers/pathcontroller.h"
0002 
0003 #include "worker/utilshelper.h"
0004 #include <QVariant>
0005 
0006 namespace vmap
0007 {
0008 
0009 QPainterPath vectorToPath(const std::vector<QPointF>& points, bool closeUp= false)
0010 {
0011     QPainterPath path;
0012     bool first= true;
0013     QPointF start;
0014     for(QPointF p : points)
0015     {
0016         if(first)
0017         {
0018             first= false;
0019             start= p;
0020             path.moveTo(p);
0021         }
0022         else
0023             path.lineTo(p);
0024     }
0025 
0026     if(closeUp)
0027         path.lineTo(start);
0028     return path;
0029 }
0030 PathController::PathController(const std::map<QString, QVariant>& params, VectorialMapController* ctrl, QObject* parent)
0031     : VisualItemController(VisualItemController::PATH, params, ctrl, parent)
0032 {
0033 
0034     helper::utils::setParamIfAny<Core::SelectableTool>(Core::vmapkeys::KEY_TOOL, params,
0035                                                        [this](Core::SelectableTool tool)
0036                                                        {
0037                                                            m_tool= tool;
0038                                                            m_penLine= (m_tool == Core::PEN);
0039                                                        });
0040     helper::utils::setParamIfAny<bool>(Core::vmapkeys::KEY_PENLINE, params, [this](bool b) { m_penLine= b; });
0041     helper::utils::setParamIfAny<bool>(Core::vmapkeys::KEY_FILLED, params, [this](bool b) { setFilled(b); });
0042     helper::utils::setParamIfAny<bool>(Core::vmapkeys::KEY_CLOSED, params, [this](bool b) { setClosed(b); });
0043     helper::utils::setParamIfAny<std::vector<QPointF>>(
0044         Core::vmapkeys::KEY_POINTS, params, [this](const std::vector<QPointF>& points) { setPoints(points); });
0045     helper::utils::setParamIfAny<int>(Core::vmapkeys::KEY_PENWIDTH, params, [this](int b) { m_penWidth= b; });
0046 
0047     if(!m_penLine && m_points.empty())
0048         addPoint(QPointF(0, 0));
0049 
0050     connect(this, &PathController::pointsChanged, this, [this] { setModified(); });
0051     connect(this, &PathController::pointCountChanged, this, [this] { setModified(); });
0052     connect(this, &PathController::penWidthChanged, this, [this] { setModified(); });
0053     connect(this, &PathController::closedChanged, this, [this] { setModified(); });
0054     connect(this, &PathController::filledChanged, this, [this] { setModified(); });
0055 }
0056 
0057 PathController::~PathController()
0058 {
0059     qDebug() << "destruction path controller";
0060 }
0061 
0062 bool PathController::filled() const
0063 {
0064     return m_filled;
0065 }
0066 
0067 bool PathController::closed() const
0068 {
0069     return m_closed;
0070 }
0071 
0072 quint16 PathController::penWidth() const
0073 {
0074     return m_penWidth;
0075 }
0076 
0077 quint64 PathController::pointCount() const
0078 {
0079     return static_cast<quint64>(m_points.size());
0080 }
0081 
0082 const std::vector<QPointF>& PathController::points() const
0083 {
0084     return m_points;
0085 }
0086 
0087 QPointF PathController::pointAt(quint64 corner) const
0088 {
0089     if(corner != qBound(static_cast<quint64>(0), corner, pointCount()))
0090         return {};
0091 
0092     return m_points[static_cast<std::size_t>(corner)];
0093 }
0094 
0095 bool PathController::penLine() const
0096 {
0097     return m_penLine;
0098 }
0099 void PathController::addPoint(const QPointF& po)
0100 {
0101     m_points.push_back(po);
0102     m_pointPositonEditing= true;
0103     emit pointCountChanged(static_cast<int>(m_points.size()));
0104     emit pointAdded(po, static_cast<int>(m_points.size()) - 1);
0105 }
0106 
0107 QPainterPath PathController::path() const
0108 {
0109     return vectorToPath(points(), closed());
0110 }
0111 
0112 void PathController::aboutToBeRemoved()
0113 {
0114     emit removeItem();
0115 }
0116 
0117 void PathController::endGeometryChange()
0118 {
0119     VisualItemController::endGeometryChange();
0120 
0121     if(m_pointPositonEditing && m_penLine)
0122     {
0123         setInitialized(true);
0124         m_pointPositonEditing= false;
0125         emit pointCountChanged(static_cast<int>(m_points.size()));
0126     }
0127     else if(m_pointPositonEditing)
0128     {
0129         m_pointPositonEditing= false;
0130         emit pointPositionEditFinished(m_modifiedPointIdx, pointAt(static_cast<quint64>(m_modifiedPointIdx)));
0131         m_modifiedPointIdx= -1;
0132     }
0133 }
0134 
0135 void PathController::setCorner(const QPointF& move, int corner, Core::TransformType tt)
0136 {
0137     if(m_points.empty())
0138         return;
0139     if(corner != qBound(0, corner, static_cast<int>(m_points.size() - 1)))
0140         return;
0141 
0142     m_points[static_cast<std::size_t>(corner)]+= move;
0143     emit positionChanged(corner, m_points[static_cast<std::size_t>(corner)]);
0144     m_pointPositonEditing= true;
0145     m_modifiedPointIdx= corner;
0146 }
0147 
0148 void PathController::setPoint(const QPointF& p, int corner)
0149 {
0150     if(m_points.empty())
0151         return;
0152     if(corner != qBound(0, corner, static_cast<int>(m_points.size())))
0153         return;
0154 
0155     m_points[static_cast<std::size_t>(corner)]= p;
0156     emit positionChanged(corner, m_points[static_cast<std::size_t>(corner)]);
0157 }
0158 
0159 QRectF PathController::rect() const
0160 {
0161     return path().boundingRect();
0162 }
0163 
0164 void PathController::setFilled(bool filled)
0165 {
0166     if(m_filled == filled)
0167         return;
0168 
0169     m_filled= filled;
0170     emit filledChanged(m_filled);
0171 }
0172 
0173 void PathController::setClosed(bool closed)
0174 {
0175     if(m_closed == closed)
0176         return;
0177 
0178     m_closed= closed;
0179     emit closedChanged(m_closed);
0180 }
0181 
0182 
0183 void PathController::setPoints(const std::vector<QPointF>& points)
0184 {
0185     if(points == m_points)
0186         return;
0187     m_points.clear();
0188     m_points= points;
0189     emit pointsChanged();
0190 }
0191 
0192 } // namespace vmap