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