1 /* 2 * Copyright 2012, 2013 Thomas Schöps 3 * Copyright 2014, 2015 Kai Pastor 4 * 5 * This file is part of OpenOrienteering. 6 * 7 * OpenOrienteering is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * OpenOrienteering is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 22 #ifndef OPENORIENTEERING_DRAW_RECTANGLE_H 23 #define OPENORIENTEERING_DRAW_RECTANGLE_H 24 25 #include <vector> 26 27 #include <QObject> 28 #include <QPoint> 29 #include <QString> 30 31 #include "core/map_coord.h" 32 #include "tools/draw_line_and_area_tool.h" 33 34 #include <QPointer> 35 #include <QScopedPointer> 36 37 class QAction; 38 class QCursor; 39 class QKeyEvent; 40 class QMouseEvent; 41 class QPainter; 42 class QToolButton; 43 44 namespace OpenOrienteering { 45 46 class ConstrainAngleToolHelper; 47 class KeyButtonBar; 48 class MapEditorController; 49 class MapWidget; 50 class SnappingToolHelper; 51 52 53 /** 54 * Tool to draw rectangular PathObjects (but also 45 degree angles). 55 */ 56 class DrawRectangleTool : public DrawLineAndAreaTool 57 { 58 Q_OBJECT 59 public: 60 DrawRectangleTool(MapEditorController* editor, QAction* tool_action, bool is_helper_tool); 61 ~DrawRectangleTool() override; 62 63 void init() override; 64 const QCursor& getCursor() const override; 65 66 bool mousePressEvent(QMouseEvent* event, const MapCoordF& map_coord, MapWidget* widget) override; 67 bool mouseMoveEvent(QMouseEvent* event, const MapCoordF& map_coord, MapWidget* widget) override; 68 bool mouseReleaseEvent(QMouseEvent* event, const MapCoordF& map_coord, MapWidget* widget) override; 69 bool mouseDoubleClickEvent(QMouseEvent* event, const MapCoordF& map_coord, MapWidget* widget) override; 70 71 bool keyPressEvent(QKeyEvent* event) override; 72 bool keyReleaseEvent(QKeyEvent* event) override; 73 74 void draw(QPainter* painter, MapWidget* widget) override; 75 76 protected slots: 77 void updateDirtyRect(); 78 79 protected: 80 void finishDrawing() override; 81 void abortDrawing() override; 82 83 /** 84 * Deletes the last drawn point. 85 * 86 * Calls updateRectangle() which will set the than-last point 87 * to constrained_pos_map. 88 */ 89 void undoLastPoint(); 90 91 /** Picks a direction from an existing object. */ 92 void pickDirection(const MapCoordF& coord, MapWidget* widget); 93 94 /** Checks if the current drawing direction is parallel to the angle. */ 95 bool drawingParallelTo(double angle) const; 96 97 /** 98 * Updates the preview after cursor position changes. 99 * May call updateRectangle() internally. 100 */ 101 void updateHover(bool mouse_down); 102 103 /** 104 * Calculates the closing vector. 105 * 106 * The "closing vector" gives the direction from the current drawing position 107 * perpendicular to the start point. 108 */ 109 MapCoordF calculateClosingVector() const; 110 111 /** 112 * Deletes all points from the preview path which were introduced to close 113 * it temporarily (for preview visualization). 114 */ 115 void deleteClosePoint(); 116 117 /** 118 * Recalculates the rectangle shape based on the current input. 119 * 120 * This will set the "last" point to constrained_pos_map. 121 */ 122 void updateRectangle(); 123 124 void updateStatusText(); 125 126 QPoint click_pos; 127 MapCoordF click_pos_map; 128 QPoint cur_pos; 129 MapCoordF cur_pos_map; 130 MapCoordF constrained_pos_map; 131 bool dragging; 132 bool draw_dash_points = true; 133 bool shift_pressed = false; 134 bool ctrl_pressed = false; 135 bool picked_direction = false; 136 bool snapped_to_line = false; 137 MapCoord snapped_to_line_a; 138 MapCoord snapped_to_line_b; 139 140 /** 141 * This can be set to true when a mouse button is pressed down to disable all 142 * actions for the next mouse button release. 143 */ 144 bool no_more_effect_on_click = false; 145 146 /** 147 * List of angles for first, second, etc. edge. 148 * Includes the currently edited angle. 149 * The index of currently edited point in preview_path is angles.size(). 150 */ 151 std::vector< double > angles; 152 153 /** Vector in forward drawing direction */ 154 MapCoordF forward_vector; 155 156 QScopedPointer<ConstrainAngleToolHelper> angle_helper; 157 QScopedPointer<SnappingToolHelper> snap_helper; 158 MapWidget* cur_map_widget; 159 160 QPointer<KeyButtonBar> key_button_bar; 161 QPointer<QToolButton> dash_points_button; 162 }; 163 164 165 } // namespace OpenOrienteering 166 #endif 167