]> git.donarmstrong.com Git - lilypond.git/blob - request.hh
release: 0.0.8
[lilypond.git] / request.hh
1 // LilyPond's second egg of columbus!
2 #ifndef REQUEST_HH
3 #define REQUEST_HH
4
5 #include "glob.hh"
6 #include "string.hh"
7
8 /// a voice element wants something printed
9 struct Request {
10     Voice_element*elt;          // indirection.
11     
12     /****************/
13
14     virtual void print()const ;
15     virtual Note_req *note() {return 0;}
16     virtual Stem_req *stem() {return 0;}
17     virtual Rest_req *rest() {return 0;}
18     virtual  Rhythmic_req*rhythmic() { return 0;}
19     Request(Voice_element*);
20     Request();
21     virtual Real duration() const { return 0.0; }
22     virtual Request* clone() const =0;
23 };
24
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) 
31
32     Please refer to the documentation of the Child classes of
33     #Request# for explanation of each request type.
34
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.
42
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.
48
49     After #Staff# made up her mind (Would #Staff# be a smart
50     name? How about #struct Susan {}# :-), 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.  */
54         
55
56 /// a request with a duration
57 struct Rhythmic_req : Request {
58     int balltype;
59     int dots;
60     
61     /****************/
62
63     Real duration() const;
64     Rhythmic_req(Voice_element*);
65     Rhythmic_req*rhythmic() { return this;}
66     void print ()const;
67     Request*clone() const;
68 };
69
70 /// Put a note of specified type, height, and with accidental on the staff.
71 struct Note_req : Rhythmic_req {
72     char name;
73     int octave;
74     int accidental;
75     bool forceacc;
76     
77     /****************/
78
79     // return height from central c (in halflines)
80     int height()const; 
81     Note_req(Voice_element*v);
82     Note_req*note() { return this;}
83     virtual void print() const;
84     Request*clone() const;
85 };
86 /**
87 Staff has to decide if the ball should be hanging left or right. This
88 influences the horizontal dimensions of a column, and this  is why
89 request processing should be done before horizontal spacing.
90
91 Other voices' frivolities may cause the need for accidentals, so this
92 is also for the Staff to decide. The Staff can decide on positioning
93 based on ottava commands and the appropriate clef.
94 */
95
96
97 ///Put a rest on the staff.
98 struct Rest_req : Rhythmic_req {
99     void print()const;
100     Rest_req(Voice_element*v) : Rhythmic_req(v) {  }
101     Rest_req * rest() { return this;}
102     Request*clone() const ;
103 };
104 /**
105 Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
106 */
107
108 /// attach a stem to the noteball
109 struct Stem_req : Request {
110     /// 4,8,16, ..
111     int stem_number;
112     virtual Stem_req *stem() {return this;}
113     Stem_req(Voice_element*v, int s) : Request(v) { stem_number = s; }
114     Request*clone() const;
115 };
116
117
118 #if 0
119
120 ///Put a lyric above or below (?) this staff.
121 struct Lyric_req : Request {
122     String text;
123 };
124
125
126 ///Put a script above or below this ``note''    
127 struct Script_req : Request {
128     int orientation;
129     Symbol sym;
130 };
131 /**
132 eg upbow, downbow. Why a request? These symbols may conflict with slurs and brackets, so this
133 also a request
134 */
135
136
137
138
139 ///Draw a (Guitar) chord above or below this ``note''
140 struct Chord : Request {
141         // don't know how this looks.
142 };
143 /**
144 Why a request?
145 Because everything else is done in requests.
146 */
147
148
149 /// for absolute dynamics
150 enum Loudness {
151     FFF, FF, F, MF, MP, P, PP, PPP
152 } ;
153
154 /// requests to start or stop something.
155 struct Span_req : Request {
156     /// should the spanner start or stop, or is it unwanted?
157     enum {
158         NOSPAN, START, STOP
159     } spantype ;
160 };
161 /**
162  This type of request typically results in the creation of a #Spanner#
163 */
164
165
166 ///Start / stop a beam at this note.
167 struct Beam_req : Span_req {
168     int nplet;
169 };
170 /** Staff will have to combine this with the stem_request, since the
171     number of flags that a stem wants to carry will determine the
172     number of beams.  if #nplet# is set, the staff will try to put an
173     appropriate number over the beam
174
175     [what to do  if the nplet fields of start and stop conflict?]
176     */
177
178 ///Start / stop a slur or a bracket.
179 struct Bracket_req : Span_req {
180     int nplet;
181 };
182 /**
183 Start/stop a bracket at this note. if #nplet# is set, the staff will
184 try to put an appropriate number over the bracket
185 */
186
187 /// a slur
188 struct Slur_req : Span_req {
189     
190 };
191
192 /// helper in the hierarchy
193 struct Dynamic {
194     Real subtime;
195 };
196 /** Each dynamic is bound to one note ( a crescendo spanning multiple
197     notes is thought to be made of two "dynamics": a start and a stop).
198     Dynamic changes can occur in a smaller time than the length of its
199     note, therefore fore each Dynamic request carries a time, measured
200     from the start of its note.
201
202     This subfield would come in handy, if mpp96 was adapted for midi
203     support.
204     
205     Dynamic should have been derived from request, but I don't want to
206     fuss with virtual baseclasses.  */
207
208 /// do a crescendo
209 struct Cresc_req : Span_req, Dynamic {
210     
211 };
212
213 /// do a decrescendo
214 struct Decresc_req : Span_req, Dynamic {
215     
216 };
217
218 /// do a dynamic like "fff" or "mp"
219 struct Absdynamic_req : Request, Dynamic {
220         Loudness loudness;
221 };
222 #endif
223 #endif