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