lilypond-0.0.5
[lilypond.git] / request.hh
blobf2dc5f7144f2c6eb3473f965ba9f78815a4df2e2
1 // mpp96's second egg of columbus!
2 #ifndef REQUEST_HH
3 #define REQUEST_HH
5 #include "glob.hh"
6 #include "string.hh"
8 struct Request {
9 Voice_element*elt;
10 #if 0
11 enum {
12 UNKNOWN, NOTE, REST, LYRIC, SCRIPT, CHORD, BEAM,
13 BRACKET, STEM, SLUR, CRESC, DECRESC, ABSDYNAMIC
14 } tag;
15 #endif
16 virtual void print()const ;
17 virtual Note_req *note() {return 0;}
18 virtual Rest_req *rest() {return 0;}
19 virtual Rhythmic_req*rhythmic() { return 0;}
20 Request(Voice_element*);
21 Request();
22 virtual Real duration() const { return 0.0; }
25 /**
26 Any Voice_element can do a number of requests. A request is done
27 to the #Staff# which contains the #Voice_element#. The staff decides
28 whether to to honor the request, ignore it, or merge it with other
29 requests. Merging of requests is preferably done with other
30 requests done by members of the same voicegroups (beams, brackets, stems)
32 Please refer to the documentation of the Child classes of
33 #Request# for explanation of each request type.
35 The result of a request will be an #Item# or a #Spanner#, which
36 will be put on a #PStaff#. Note that the #PStaff# and the original
37 #Staff# need not have anything in common. For example, the
38 ``double'' piano Staff could interpret commands which juggle
39 melodies across the left and right hand, and may put the result in
40 two five-line PStaffs (maybe with extra PStaffs to carry the dynamic
41 signs and any lyric.
43 The class #Staff# should be thought as a container for the
44 #Voice#s, and an interpreter for #Request#s and #Command#s.
45 Different staffs can produce different outputs; a melodious voice
46 which is put into a percussion-Staff, will be typeset as the rythm of
47 that voice.
49 After #Staff# made up her mind (Would #Staff# be a smart
50 name? How about #struct Lily {}# :-), the resultant items and
51 spanners are put on the PScore, and pointers to these items are
52 stored in the #Voice_element#. This construction enables the
53 beams/stems to look up the balls it has to connect to. */
56 struct Rhythmic_req : Request {
57 int balltype;
58 int dots;
59 Real duration() const;
60 Rhythmic_req(Voice_element*);
61 Rhythmic_req*rhythmic() { return this;}
64 /// Put a note of specified type, height, and with accidental on the staff.
65 struct Note_req : Rhythmic_req {
66 char name;
67 int octave;
68 int accidental;
69 bool forceacc;
70 Note_req(Voice_element*v);
71 Note_req*note() { return this;}
73 /**
74 Staff has to decide if the ball should be hanging left or right. This
75 influences the horizontal dimensions of a column, and this is why
76 request processing should be done before horizontal spacing.
78 Other voices' frivolities may cause the need for accidentals, so this
79 is also for the Staff to decide. The Staff can decide on positioning
80 based on ottava commands and the appropriate clef.
84 ///Put a rest on the staff.
85 struct Rest_req : Rhythmic_req {
87 Rest_req(Voice_element*v) : Rhythmic_req(v) { }
88 Rest_req * rest() { return this;}
90 /**
91 Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
94 #if 0
96 ///Put a lyric above or below (?) this staff.
97 struct Lyric_req : Request {
98 String text;
102 ///Put a script above or below this ``note''
103 struct Script_req : Request {
104 int orientation;
105 Symbol sym;
108 eg upbow, downbow. Why a request? These symbols may conflict with slurs and brackets, so this
109 also a request
115 ///Draw a (Guitar) chord above or below this ``note''
116 struct Chord : Request {
117 // don't know how this looks.
120 Why a request?
121 Because everything else is done in requests.
125 /// for absolute dynamics
126 enum Loudness {
127 FFF, FF, F, MF, MP, P, PP, PPP
130 /// attach a stem to the noteball
131 struct Stem_req : Request {
132 /// 4,8,16, ..
133 int stem_number ;
135 /// requests to start or stop something.
136 struct Span_req : Request {
137 /// should the spanner start or stop, or is it unwanted?
138 enum {
139 NOSPAN, START, STOP
140 } spantype ;
143 This type of request typically results in the creation of a #Spanner#
147 ///Start / stop a beam at this note.
148 struct Beam_req : Span_req {
149 int nplet;
151 /** Staff will have to combine this with the stem_request, since the
152 number of flags that a stem wants to carry will determine the
153 number of beams. if #nplet# is set, the staff will try to put an
154 appropriate number over the beam
156 [what to do if the nplet fields of start and stop conflict?]
159 ///Start / stop a slur or a bracket.
160 struct Bracket_req : Span_req {
161 int nplet;
164 Start/stop a bracket at this note. if #nplet# is set, the staff will
165 try to put an appropriate number over the bracket
168 /// a slur
169 struct Slur_req : Span_req {
173 /// helper in the hierarchy
174 struct Dynamic {
175 Real subtime;
177 /** Each dynamic is bound to one note ( a crescendo spanning multiple
178 notes is thought to be made of two "dynamics": a start and a stop).
179 Dynamic changes can occur in a smaller time than the length of its
180 note, therefore fore each Dynamic request carries a time, measured
181 from the start of its note.
183 This subfield would come in handy, if mpp96 was adapted for midi
184 support.
186 Dynamic should have been derived from request, but I don't want to
187 fuss with virtual baseclasses. */
189 /// do a crescendo
190 struct Cresc_req : Span_req, Dynamic {
194 /// do a decrescendo
195 struct Decresc_req : Span_req, Dynamic {
199 /// do a dynamic like "fff" or "mp"
200 struct Absdynamic_req : Request, Dynamic {
201 Loudness loudness;
203 #endif
204 #endif