1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // $Id: canvas.h,v 1.3.2.8 2009/02/02 21:38:01 terminator356 Exp $ 5 // (C) Copyright 1999 Werner Schweer (ws@seh.de) 6 // Additions, modifications (C) Copyright 2011-2013 Tim E. Real (terminator356 on users DOT sourceforge DOT net) 7 // 8 // This program is free software; you can redistribute it and/or 9 // modify it under the terms of the GNU General Public License 10 // as published by the Free Software Foundation; version 2 of 11 // the License, or (at your option) any later version. 12 // 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 // 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 // 22 //========================================================= 23 24 #ifndef __CANVAS_H__ 25 #define __CANVAS_H__ 26 27 #include "citem.h" 28 #include "view.h" 29 #include "tools.h" 30 #include "type_defs.h" 31 32 #include "event_tag_list.h" 33 34 #include <QPoint> 35 #include <QRegion> 36 #include <QRect> 37 38 39 // Forward declarations: 40 class QMenu; 41 class QPainter; 42 class QTimer; 43 class QWheelEvent; 44 class QMouseEvent; 45 class QKeyEvent; 46 47 namespace MusECore { 48 class Undo; 49 } 50 51 namespace MusEGui { 52 53 //--------------------------------------------------------- 54 // Canvas 55 //--------------------------------------------------------- 56 57 class Canvas : public View { 58 Q_OBJECT 59 QTimer *scrollTimer; 60 61 bool doScroll; 62 int scrollSpeed; 63 64 QPoint ev_pos; 65 QPoint ev_global_pos; 66 bool ignore_mouse_move; 67 bool canScrollLeft; 68 bool canScrollRight; 69 bool canScrollUp; 70 bool canScrollDown; 71 72 // CItem *findCurrentItem(const QPoint &cStart); 73 74 // Whether we have grabbed the mouse. 75 bool _mouseGrabbed; 76 // The number of times we have called QApplication::setOverrideCursor(). 77 // This should always be one or zero, anything else is an error, but unforeseen 78 // events might cause us to miss a decrement with QApplication::restoreOverrideCursor(). 79 int _cursorOverrideCount; 80 81 protected: 82 enum DragMode { 83 DRAG_OFF=0, DRAG_NEW, 84 DRAG_MOVE_START, DRAG_MOVE, 85 DRAG_COPY_START, DRAG_COPY, 86 DRAG_CLONE_START, DRAG_CLONE, 87 DRAGX_MOVE, DRAGY_MOVE, 88 DRAGX_COPY, DRAGY_COPY, 89 DRAGX_CLONE, DRAGY_CLONE, 90 DRAG_DELETE, 91 DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO, 92 DRAG_PAN, DRAG_ZOOM 93 }; 94 95 enum DragType { 96 MOVE_MOVE, MOVE_COPY, MOVE_CLONE 97 }; 98 99 enum HScrollDir { 100 HSCROLL_NONE, HSCROLL_LEFT, HSCROLL_RIGHT 101 }; 102 enum VScrollDir { 103 VSCROLL_NONE, VSCROLL_UP, VSCROLL_DOWN 104 }; 105 106 enum MenuIdBase { 107 TOOLS_ID_BASE=10000 108 }; 109 110 CItemMap items; 111 CItemMap moving; 112 CItem* newCItem; 113 CItem* curItem; 114 MusECore::Part* curPart; 115 int curPartId; 116 117 int canvasTools; 118 DragMode drag; 119 QRect lasso; 120 QRegion lassoRegion; 121 QPoint start; 122 QPoint end; 123 QPoint global_start; 124 Tool _tool; 125 unsigned pos[3]; 126 MusECore::ResizeDirection resizeDirection; 127 128 HScrollDir hscrollDir; 129 VScrollDir vscrollDir; 130 int button; 131 Qt::KeyboardModifiers keyState; 132 QMenu* itemPopupMenu; 133 QMenu* canvasPopupMenu; 134 135 bool supportsResizeToTheLeft; 136 bool supportsMultipleResize; 137 138 void setLasso(const QRect& r); 139 void resizeToTheLeft(const QPoint &pos); 140 void resizeSelected(const int &dist, const bool left = false); 141 virtual void setCursor(); 142 virtual void setMouseOverItemCursor(); 143 virtual void viewKeyPressEvent(QKeyEvent* event); 144 virtual void viewKeyReleaseEvent(QKeyEvent* event); 145 virtual void viewMousePressEvent(QMouseEvent* event); 146 virtual void viewMouseMoveEvent(QMouseEvent*); 147 virtual void viewMouseReleaseEvent(QMouseEvent*); 148 virtual void draw(QPainter& p, const QRect& mr, const QRegion& mrg = QRegion()); 149 virtual void wheelEvent(QWheelEvent* e); 150 151 virtual void keyPress(QKeyEvent*); 152 virtual void keyRelease(QKeyEvent*); mousePress(QMouseEvent *)153 virtual bool mousePress(QMouseEvent*) { return true; } 154 virtual void mouseMove(QMouseEvent* event) = 0; 155 // virtual void mouseRelease(const QPoint&) {} mouseRelease(QMouseEvent *)156 virtual void mouseRelease(QMouseEvent*) {} 157 // Resets all mouse operations if detecting missed mouseRelease event (which DOES happen). 158 // Returns true if reset was actually done. 159 virtual bool cancelMouseOps(); 160 virtual void drawParts(QPainter&, bool /*do_cur_part*/, const QRect&, const QRegion& = QRegion()) { } 161 virtual void drawCanvas(QPainter&, const QRect&, const QRegion& = QRegion()) = 0; 162 virtual void drawTopItem(QPainter& p, const QRect& rect, const QRegion& = QRegion()) = 0; 163 virtual void drawMarkers(QPainter& p, const QRect& mr, const QRegion& mrg = QRegion()); 164 virtual void drawItem(QPainter&, const CItem*, const QRect&, const QRegion& = QRegion()) = 0; 165 virtual void drawMoving(QPainter&, const CItem*, const QRect&, const QRegion& = QRegion()) = 0; 166 virtual bool itemSelectionsChanged(MusECore::Undo* operations = 0, bool deselectAll = false) = 0; 167 virtual QPoint raster(const QPoint&) const = 0; 168 virtual int y2pitch(int) const = 0; //CDW 169 virtual int pitch2y(int) const = 0; //CDW 170 virtual int y2height(int) const = 0; 171 virtual int yItemOffset() const = 0; 172 173 virtual CItem* newItem(const QPoint&, int state) = 0; 174 virtual void resizeItem(CItem*, bool noSnap=false, bool ctrl=false) = 0; 175 virtual void newItem(CItem*, bool noSnap=false) = 0; 176 virtual bool deleteItem(CItem*) = 0; 177 178 /*! 179 \brief Virtual member 180 181 Implementing class is responsible for creating a popup to be shown when the user rightclicks an item on the Canvas 182 \param item The canvas item that is rightclicked 183 \return A QPopupMenu* 184 */ genItemPopup(CItem *)185 virtual QMenu* genItemPopup(CItem* /*item*/) { return 0; } 186 187 /*! 188 \brief Pure virtual member 189 190 Implementing class is responsible for creating a popup to be shown when the user rightclicks an empty region of the canvas 191 \return A QPopupMenu* 192 */ 193 QMenu* genCanvasPopup(QMenu* menu = 0); 194 195 /*! 196 \brief Virtual member 197 198 This is the function called when the user has selected an option in the popupmenu generated by genItemPopup() 199 \param item the canvas item the whole thing is about 200 \param n Command type 201 \param pt I think this is the position of the pointer when right mouse button was pressed 202 */ itemPopup(CItem *,int,const QPoint &)203 virtual void itemPopup(CItem* /*item */, int /*n*/, const QPoint& /*pt*/) {} 204 void canvasPopup(int); 205 206 virtual void startDrag(CItem*, DragType) = 0;// {} 207 208 // selection 209 virtual void deselectAll(); 210 virtual void selectItem(CItem* e, bool); 211 212 virtual void deleteItem(const QPoint&); 213 214 // moving 215 void startMoving(const QPoint&, int dir, DragType, bool rasterize = true); 216 void moveItems(const QPoint&, int dir = 0, bool rasterize = true); 217 virtual void endMoveItems(const QPoint&, DragType, int dir, bool rasterize = true) = 0; 218 219 // Returns true if anything was selected. 220 virtual bool selectLasso(bool toggle); 221 itemPressed(const CItem *)222 virtual void itemPressed(const CItem*) {} itemReleased(const CItem *,const QPoint &)223 virtual void itemReleased(const CItem*, const QPoint&) {} itemsReleased()224 virtual void itemsReleased() {} 225 // Called to inform before an item will be moved. 226 // When multiple items are moving, all itemMoving() are called before 227 // all itemMoved(), rather than in pairs for each item. (That helps with 228 // the note playing routines.) The current item will inform first before others. 229 // The item's current moving point contains the position before moving, 230 // while newMP contains the position it will be moved to. itemMoving(const CItem *,const QPoint &)231 virtual void itemMoving(const CItem*, const QPoint& /*newMP*/) { } 232 // Called to inform that an item has just been moved. 233 // The item's current moving point contains the position after moving, 234 // while oldMP contains the old position before it was moved. itemMoved(const CItem *,const QPoint &)235 virtual void itemMoved(const CItem*, const QPoint& /*oldMP*/) {} 236 curPartChanged()237 virtual void curPartChanged() { emit curPartHasChanged(curPart); } 238 239 // If show is true, calls QApplication::restoreOverrideCursor() until _cursorOverrideCount-- is <= 0. 240 // If show is false, calls QApplication::setOverrideCursor with a blank cursor. 241 void showCursor(bool show = true); 242 // Sets or resets the _mouseGrabbed flag and grabs or releases the mouse. 243 void setMouseGrab(bool grabbed = false); 244 CItem *findCurrentItem(const QPoint &cStart); 245 246 public slots: 247 void setTool(int t); 248 virtual void setPos(int, unsigned, bool adjustScrollbar); 249 void scrollTimerDone(void); 250 void redirectedWheelEvent(QWheelEvent*); 251 252 signals: 253 void followEvent(int); 254 void toolChanged(int); 255 void verticalScroll(unsigned); 256 void horizontalScroll(unsigned); 257 void horizontalScrollNoLimit(unsigned); 258 void horizontalZoom(bool zoom_in, const QPoint& glob_pos); 259 void horizontalZoom(int mag, const QPoint& glob_pos); 260 void curPartHasChanged(MusECore::Part*); 261 262 public: 263 Canvas(QWidget* parent, int sx, int sy, const char* name = 0); 264 virtual ~Canvas(); 265 266 // Converts a lasso-style (one-pixel thick) rectangle to a 267 // four-rectangle region union - enough to cover the four sides. 268 // Clears the given region first. 269 void lassoToRegion(const QRect& r_in, QRegion& rg_out) const; 270 271 // Whether we have grabbed the mouse. mouseGrabbed()272 bool mouseGrabbed() const { return _mouseGrabbed; } 273 bool isSingleSelection() const; 274 int selectionSize() const; 275 bool itemsAreSelected() const; 276 // Appends given tag list with item objects according to options. Avoids duplicate events or clone events. 277 // Special: We 'abuse' a controller event's length, normally 0, to indicate visual item length. 278 virtual void tagItems(MusECore::TagEventList* tag_list, const MusECore::EventTagOptionsStruct& options) const; 279 tool()280 Tool tool() const { return _tool; } part()281 MusECore::Part* part() const { return curPart; } 282 void setCurrentPart(MusECore::Part*); setCanvasTools(int n)283 void setCanvasTools(int n) { canvasTools = n; } 284 int getCurrentDrag(); 285 virtual void updateItems() = 0; 286 virtual void updateItemSelections(); 287 }; 288 289 } // namespace MusEGui 290 291 #endif 292 293