]> git.donarmstrong.com Git - lilypond.git/blob - rhythmstaf.cc
release: 0.0.5
[lilypond.git] / rhythmstaf.cc
1 #include "request.hh"
2 #include "debug.hh"
3 #include "linestaff.hh"
4 #include "staff.hh"
5 #include "pstaff.hh"
6 #include "pscore.hh"
7 #include "command.hh"
8 #include "molecule.hh"
9 #include "rhythmstaf.hh"
10 #include "lookupsyms.hh"
11 #include "sccol.hh" 
12
13 Rhythmic_column::Rhythmic_column(Score_column*s, Rhythmic_staff *rs)
14     : Staff_column(s)
15 {
16     the_note = 0;
17     staff_ = rs;
18 }
19
20 Rhythmic_staff::Rhythmic_staff()
21 {
22     theline = new Linestaff(1);
23 }
24 void
25 Rhythmic_staff::set_output(PScore* ps )
26 {
27     pscore_ = ps;
28     pscore_->add(theline);
29 }
30
31 // should integrate handling of BREAK commands into Staff_column
32 void
33 Rhythmic_column::process_commands( )
34 {
35     int breakstat = BREAK_END - BREAK_PRE;
36     for (int i = 0 ; i < s_commands.sz(); i++) {
37         Command *com = s_commands[i];
38         switch (com->code){
39         case INTERPRET:
40             break;
41         case BREAK_PRE:
42         case BREAK_MIDDLE:
43         case BREAK_POST:
44         case BREAK_END:
45             score_column->set_breakable();
46             breakstat = com->code- BREAK_PRE;
47             break;
48             
49         case TYPESET:
50             typeset_command ( com , breakstat);
51             break;
52         default :
53             break;
54         }
55         
56     }
57 }
58 /**
59  accept:
60
61     BREAK: all
62     TYPESET: bar, meter
63
64     */
65
66
67
68 void
69 Rhythmic_column::process_requests()
70 {
71     for (int i = 0 ; i < v_elts.sz(); i ++)
72         for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
73             Request *rq= rqc;
74             if (rq->rhythmic()){
75                 if (the_note){
76                     WARN << "too many notes.\n";
77                     return;
78                 }
79                 the_note = rq;
80             }
81             break;
82         }
83 }
84
85
86 void
87 Rhythmic_column::typeset_command(Command *com, int breakst)
88 {
89     Item *i = new Item;
90     Symbol s;
91
92     if (com -> args[0] ==  "BAR" ) {
93         s = Lookup::bar(com->args[1]);  
94     } else if (com->args[0] == "METER") {
95         Parametric_symbol *p = Lookup::meter("general");
96         svec<String> arg( com->args);
97         arg.del(0);
98         s = p->eval(arg);
99     } else
100         assert(false);
101
102     Molecule * m =new Molecule(Atom(s));
103     {
104         Interval wid;
105         svec<Item*> sv(staff_->pscore_->
106                        select_items(staff_->theline, score_column->pcol));
107         for (int j=0; j<sv.sz(); j++) {
108             wid.unite(sv[j]->output->extent().x);
109         }
110         if (!wid.empty())
111             m->translate(Offset(wid.max,0));
112     }
113     i->output=m;
114     staff_->pscore_->typeset_item(i, score_column->pcol,
115                                   staff_->theline,breakst);
116 }
117
118 void
119 Rhythmic_column::typeset_req(Request *rq)
120 {
121     Item *i = new Item;
122     Symbol s;
123     int dots=0;
124
125     if (rq->note())
126         s = Lookup::ball(rq->note()->balltype);
127     if (rq->rhythmic())
128         dots=rq->rhythmic()->dots;
129     if (rq->rest())
130         s = Lookup::rest(rq->rest()->balltype);
131
132     Molecule *m = new Molecule(Atom(s));
133     if (dots) {
134         Symbol d = Lookup::dots(dots);
135         Molecule dm;
136         dm.add(Atom(d));
137         m->add_right(dm);
138     }
139     i->output=m;
140     staff_->pscore_->typeset_item(i, score_column->pcol, staff_->theline );
141 }
142
143 void
144 Rhythmic_staff::grant_requests()
145 {
146     for  (PCursor<Staff_column*> cc(cols); cc.ok(); cc++) {
147         Rhythmic_column *rp = (Rhythmic_column*)*cc;
148         if (rp->the_note)
149             rp->typeset_req( rp->the_note);
150     }
151 }
152
153 Staff_column*
154 Rhythmic_staff::create_col(Score_column*s)
155 {
156     Rhythmic_column *rc = new Rhythmic_column(s,this);
157
158     return rc;
159 }
160
161 Staff *
162 get_new_rhythmstaff()
163 {
164     return new Rhythmic_staff;
165 }