1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 #ifndef RG_NOTATIONELEMENT_H
19 #define RG_NOTATIONELEMENT_H
20 
21 #include "base/Exception.h"
22 #include "base/ViewElement.h"
23 #include <vector>
24 #include "base/Event.h"
25 
26 
27 class QGraphicsItem;
28 class ItemList;
29 
30 
31 namespace Rosegarden
32 {
33 
34 class Event;
35 
36 
37 /**
38  * The Notation H and V layout is performed on a
39  * NotationElementList. Once this is done, each NotationElement is
40  * given a QGraphicsItem to take care of and place at its own proper
41  * coordinates.
42  *
43  * @see NotationView#showElements()
44  */
45 
46 class NotationElement : public ViewElement
47 {
48 public:
49     typedef Exception NoGraphicsItem;
50 
51     /**
52      * Create a new NotationElement encapsulating the Event in
53      * parameter.  NotationElement does not take ownership of the
54      * event itself.
55      */
56     NotationElement(Event *event);
57 
58     /**
59      * Only destroy the graphical representation of the Event, not the
60      * Event itself
61      */
62     ~NotationElement() override;
63 
64     /**
65      * Returns the time at which the Event is to be displayed in
66      * notation (usually the result of notation quantization on the
67      * raw event time)
68      */
69     timeT getViewAbsoluteTime() const override;
70 
71     /**
72      * Returns the duration with which the Event is to be displayed in
73      * notation (usually the result of notation quantization on the
74      * raw event duration)
75      */
76     timeT getViewDuration() const override;
77 
78     /**
79      * Return the position and horizontal size spanned by the item,
80      * including adjoining space that "belongs" to the item.  This is
81      * used when calculating which element is "under" the mouse
82      * position.  The values are usually more extensive than the
83      * position and size of the displayed element.  These are computed
84      * by NotationHLayout and set to this class using
85      * setLayoutAirspace
86      */
getLayoutAirspace(double & x,double & width)87     void getLayoutAirspace(double &x, double &width) {
88         x = m_airX;
89         width = m_airWidth;
90     }
91 
getSceneAirspace(double & x,double & width)92     void getSceneAirspace(double &x, double &width) {
93         x = m_airX - getLayoutX() + getSceneX();
94         width = m_airWidth;
95     }
96 
97     /// returns the x pos of the associated scene item
98     double getSceneX();
99 
100     /// returns the y pos of the associated scene item
101     double getSceneY();
102 
103     /**
104      * Sets the X coordinate and width of the space "underneath"
105      * this element, i.e. the extents within which a mouse click
106      * or some such might be considered to be interested in this
107      * element as opposed to any other.  These are layout coords
108      */
setLayoutAirspace(double x,double width)109     void setLayoutAirspace(double x, double width) {
110         m_airX = x; m_airWidth = width;
111     }
112 
113     /// Returns true if the wrapped event is a rest
114     bool isRest() const;
115 
116     /// Returns true if the wrapped event is a note
117     bool isNote() const;
118 
119     /// Returns true if the wrapped event is a tuplet
120     bool isTuplet() const;
121 
122     /// Returns true if the wrapped event is a grace note
123     bool isGrace() const;
124 
125     /**
126      * Sets the scene item representing this notation element on screen.
127      *
128      * NOTE: The object takes ownership of its scene item.
129      */
130     void setItem(QGraphicsItem *e, double sceneX, double sceneY);
131 
132     /**
133      * Add an extra scene item associated with this element, for
134      * example where an element has been split across two or more
135      * staff rows.
136      *
137      * The element will take ownership of these scene items and
138      * delete them when it deletes the main scene item.
139      */
140     void addItem(QGraphicsItem *e, double sceneX, double sceneY);
141 
142     /**
143      * Remove the main scene item and any additional ones.
144      */
145     void removeItem();
146 
147     /**
148      * Reset the position of the scene item (which is assumed to
149      * exist already).
150      */
151     void reposition(double sceneX, double sceneY);
152 
153     /**
154      * Return true if setItem has been called more recently
155      * than reposition.  If true, any code that positions this
156      * element will probably not need to regenerate its item as
157      * well, even if other indications suggest otherwise.
158      */
isRecentlyRegenerated()159     bool isRecentlyRegenerated() { return m_recentlyRegenerated; }
160 
161     bool isSelected();
162     void setSelected(bool selected);
163 
164     /**
165      * Return true if the element is a note which lies at exactly the
166      * same place as another note.
167      * Only valid after NotationVLayout::scanStaff() call.
168      * Only a returned true is meaningful (when 2 notes are colliding, the
169      * first element returns false and the second one returns true).
170      */
isColliding()171     bool isColliding() { return m_isColliding; }
172 
setIsColliding(bool value)173     void setIsColliding(bool value) { m_isColliding = value; }
174 
175     /// Returns the associated scene item
getItem()176     QGraphicsItem *getItem() { return m_item; }
177 
178     static NotationElement *getNotationElement(QGraphicsItem *);
179 
180 protected:
181     double m_airX;
182     double m_airWidth;
183     bool m_recentlyRegenerated;
184     bool m_isColliding;
185 
186     /**
187      * The graphical representation of the event
188      */
189     QGraphicsItem *m_item;
190 
191     typedef std::vector<QGraphicsItem *> ItemList;
192     ItemList *m_extraItems;
193 };
194 
195 typedef ViewElementList NotationElementList;
196 
197 
198 
199 }
200 
201 #endif
202