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