From: Chris C. <ca...@al...> - 2004-03-31 08:37:53
|
On Tuesday 30 Mar 2004 10:56 pm, Seb James wrote: > Where is the Composition API coded? base/Composition.h Quick primer: in gui/rosegardenguidoc.h you have your basic Document class, RosegardenGUIDoc. It's the GUI's main container for everything, and in particular it contains a Composition (the container for all notes and events) and a Studio (container for device information, not interested in that at the moment here). The Composition contains all the Segments (corresponding to the blocks you draw on the main canvas), which themselves contain Events for notes, rests, clefs, MIDI controllers etc -- see base/Composition.h, Segment.h, Event.h. Composition also directly contains tempo changes and time signatures -- they are not stored in Segments: you can't have different time sigs in different segments. Events can have arbitrary type and arbitrary properties, and there are various helper classes in base/NotationTypes.h which can construct and examine the common notation types (to avoid having to get the type and property names exactly right yourself). Note that everything in base/ is in the Rosegarden namespace, but classes in gui/ are not. Example: Given an empty Composition (such as that returned by document->getComposition() on a new document), set a 3/4 time sig, add a single empty segment of 30 bars duration, and put a clef in it: composition->addTimeSignature(0, Rosegarden::TimeSignature(3,4)); Rosegarden::Segment *s = new Rosegarden::Segment(); composition->addSegment(s); s->fillWithRests(composition->getBarEnd(30)); Rosegarden::Clef clef(Rosegarden::Clef::Bass); s->insert(clef.getAsEvent(0)); Note that the time signature will replace any that was previously at time zero, and the segment has to be inserted into a composition with the correct time sig before fillWithRests can work correctly. Those last two lines are equivalent to Rosegarden::Event *e = new Rosegarden::Event (Rosegarden::Clef::EventType, 0); e->set<String>(Rosegarden::Clef::ClefPropertyName, Rosegarden::Clef::Bass); s->insert(e); or even (for illustrative purposes only -- never do this) Rosegarden::Event *e = new Rosegarden::Event("clefchange", 0); e->set<String>("clef", "bass"); s->insert(e); Using Clef::getAsEvent is preferred as it's less error-prone and more likely to continue to do the right thing if the clef event gains any further properties. Not that you'll need to know any of this for a while yet. Chris |