File indexing completed on 2024-05-05 12:59:28
0001 /******************************************************************************** 0002 * Copyright (C) 2011-2015 by Stephen Allewell * 0003 * steve.allewell@gmail.com * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ********************************************************************************/ 0010 0011 0012 /** 0013 * @file 0014 * Header file for the Editor class. 0015 */ 0016 0017 0018 #ifndef Editor_H 0019 #define Editor_H 0020 0021 0022 #include <QMap> 0023 #include <QPainterPath> 0024 #include <QPair> 0025 #include <QPointF> 0026 #include <QUndoStack> 0027 #include <QWidget> 0028 0029 #include "Commands.h" 0030 0031 0032 class QPaintEvent; 0033 0034 class KCharSelect; 0035 0036 0037 /** 0038 * @brief Manages the editor window allowing user interaction with the various tools. 0039 * 0040 * The Editor class is used to edit the new symbols or the symbols from the loaded library. 0041 * It shows a grid of @ref gridElements of @ref elementSize grouped into @ref elementGroup 0042 * number of elements. 0043 * 0044 * The path is a QPainterPath element and is constructed from the various elements created 0045 * by the tools. The constructed QPainterPath is used to draw the path in the editor so it 0046 * is an accurate representation of the final path. The QPainterPath is deconstructed into 0047 * its individual elements and points for editing. 0048 * 0049 * There are additional attributes used to draw the path, filled or unfilled, the fill rule, 0050 * line width, end cap and join styles can be changed to alter the appearance of the path. 0051 * 0052 * The user interacts with the editor using the various tools. For each tool a number of 0053 * points need to be defined, simple tools like move to and line to only require one point 0054 * whereas cubic to requires three to define the two control points and the end point. 0055 * 0056 * Convenience tools are available for rectangles and ellipses but these are broken down 0057 * into lines and curves in the constructed path. 0058 * 0059 * Points that have been added can be moved to adjust the shape by dragging them around. 0060 * The points will snap to the grid intersections if the snap option is enabled. Otherwise 0061 * they can be positioned anywhere. 0062 * 0063 * Tools are available to rotate or flip the symbol which adjusts the points positions and 0064 * reconstructs the QPainterPath. 0065 * 0066 * Guide lines and circles can be displayed if the current position of the mouse on the 0067 * editor aligns with an existing point either horizontally, vertically or at a pre-defined 0068 * angle, or if the point lies on the same circle as the original where its origin is at 0069 * the center of the grid. 0070 */ 0071 class Editor : public QWidget 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 enum ToolMode {MoveTo, LineTo, CubicTo, Rectangle, Ellipse, Character}; 0077 0078 explicit Editor(QWidget *parent = nullptr); 0079 virtual ~Editor(); 0080 0081 QPair<qint16, Symbol> symbol(); 0082 void setSymbol(const QPair<qint16, Symbol> &pair); 0083 0084 QPainterPath moveTo(const QPointF &to); 0085 QPainterPath lineTo(const QPointF &to); 0086 QPainterPath cubicTo(const QPointF &control1, const QPointF &control2, const QPointF &to); 0087 QPainterPath addRectangle(const QPointF &from, const QPointF &to); 0088 QPainterPath addEllipse(const QPointF &from, const QPointF &to); 0089 void removeLast(const QPainterPath &path); 0090 void movePoint(int index, const QPointF &to); 0091 void rotatePointsLeft(); 0092 void rotatePointsRight(); 0093 void flipPointsHorizontal(); 0094 void flipPointsVertical(); 0095 void setFilled(bool filled); 0096 void setFillRule(Qt::FillRule rule); 0097 void setCapStyle(Qt::PenCapStyle capStyle); 0098 void setJoinStyle(Qt::PenJoinStyle joinStyle); 0099 void setLineWidth(double width); 0100 QPainterPath setPath(const QPainterPath &path); 0101 0102 void clear(); 0103 0104 QUndoStack *undoStack(); 0105 0106 void updateStatusMessage(); 0107 0108 public slots: 0109 void selectTool(QAction *action); 0110 void charSelected(const QChar &character); 0111 void enableSnap(bool enabled); 0112 void enableGuides(bool enabled); 0113 void selectFilled(bool enabled); 0114 void selectFillRule(QAction *action); 0115 void selectCapStyle(QAction *action); 0116 void selectJoinStyle(QAction *action); 0117 void increaseLineWidth(); 0118 void decreaseLineWidth(); 0119 0120 void rotateLeft(); 0121 void rotateRight(); 0122 void flipHorizontal(); 0123 void flipVertical(); 0124 void scalePreferred(); 0125 0126 void readSettings(); 0127 0128 signals: 0129 void message(const QString &text); 0130 void minLineWidth(bool reached); 0131 void maxLineWidth(bool reached); 0132 0133 protected: 0134 virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; 0135 virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; 0136 virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; 0137 0138 virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; 0139 virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; 0140 0141 virtual void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; 0142 0143 private: 0144 void addPoint(const QPointF &point); 0145 QPointF snapPoint(const QPoint &point) const; 0146 QPair<bool, QPointF> snapToGrid(const QPoint &point) const; 0147 QPair<bool, QPointF> snapToGuide(const QPointF &point) const; 0148 QPointF toSymbol(const QPoint &point) const; 0149 bool node(const QPointF &point) const; 0150 QPair<bool, int> nodeUnderCursor(const QPointF &point) const; 0151 void deconstructPainterPath(); 0152 void constructPainterPath(); 0153 void constructGuides(const QPointF &to); 0154 void addGuideLine(const QLineF &line); 0155 void addGuideCircle(double radius); 0156 void addSnapPoint(const QPointF &point); 0157 QLineF projected(const QLineF &line) const; 0158 0159 int m_size; /**< the overall size of the editor */ 0160 0161 bool m_snap; /**< true if snap mode is enabled */ 0162 bool m_fill; /**< true if fill mode is enabled */ 0163 bool m_guides; /**< true if generating guides is enabled */ 0164 0165 QUndoStack m_undoStack; /**< holds the commands that modify the editor contents allowing for undo */ 0166 0167 ToolMode m_toolMode; /**< the current tool selected */ 0168 0169 QList<QPointF> m_points; /**< the points that have been committed relating to the elements in m_elements */ 0170 QList<QPainterPath::ElementType> m_elements; /**< the basic elements making up the path, move, line and curve */ 0171 0172 QList<QPointF> m_activePoints; /**< the points that are being entered for the current command */ 0173 0174 qint16 m_index; /**< the index of the symbol as stored in the library, this is 0 for new symbols */ 0175 QPainterPath m_painterPath; /**< the path from m_symbol currently being edited */ 0176 Symbol m_symbol; /**< the symbol containing the QPainterPath and rendering attributes */ 0177 0178 bool m_dragging; /**< true if currently dragging a point around */ 0179 QPointF m_start; /**< the start position of a drag operation or the start of a rubber band selection */ 0180 QPointF m_tracking; /**< the current position of a drag operation or the position of a rubber band selection */ 0181 QRectF m_rubberBand; /**< a rubber band rectangle in symbol coordinates, is null when not required */ 0182 QPair<bool, int> m_dragPointIndex; /**< represents the list and index of the point being moved, true for m_points, false for m_activePoints */ 0183 0184 QVector<qreal> m_angles; /**< the angles allowed for constructing guide lines */ 0185 QList<QLineF> m_guideLines; /**< the guide lines that have been constructed for a given point */ 0186 QList<qreal> m_guideCircles; /**< the guide circles that have been constructed for a given point */ 0187 QList<QPointF> m_snapPoints; /**< points that intersect with guide lines */ 0188 QLineF m_topEdge; /**< represents the top edge of the editor from 0,0 to 1,0 */ 0189 QLineF m_bottomEdge; /**< represents the bottom edge of the editor from 0,1 to 1,1 */ 0190 QLineF m_leftEdge; /**< represents the left edge of the editor from 0,1 to 0,1 */ 0191 QLineF m_rightEdge; /**< represents the right edge of the editor from 1,0 to 1,1 */ 0192 0193 KCharSelect *m_charSelect; /**< pointer to KCharSelect dialog used to add characters to paths */ 0194 0195 int m_gridElements; /**< The number of grid elements (Configuration::editor_GridElements) */ 0196 int m_elementSize; /**< The size in pixels of an element (Configuration::editor_ElementSize) */ 0197 int m_elementGrouping; /**< The number of cells in a group (Configuration::editor_ElementGroup) */ 0198 double m_pointSize; /**< The size of a point in pixels (Configuration::editor_PointSize) */ 0199 double m_snapThreshold; /**< The distance to check within the range of a point (Configuration::editor_SnapThreshold) */ 0200 int m_borderSize; /**< The number of cell elements used for the border (Configuration::editor_BorderSize) */ 0201 QColor m_preferredSizeColor; /**< The color of the preferred size square (Configuration::editor_PreferredSizeColor) */ 0202 QColor m_guideLineColor; /**< The color of the guide lines (Configuration::editor_GuideLineColor) */ 0203 }; 0204 0205 0206 #endif 0207