lilypond-0.0.49
[lilypond.git] / src / complexwalker.cc
blobe3bcade138846f7afa1b5961d4d5439237fefe76
1 /*
2 complexwalker.cc -- implement Complex_walker
4 source file of the LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
9 #include "associter.hh"
10 #include "script.hh"
11 #include "musicalrequest.hh"
12 #include "staffcolumn.hh"
13 #include "voice.hh"
14 #include "pscore.hh"
15 #include "complexstaff.hh"
16 #include "debug.hh"
17 #include "voicegroupregs.hh"
18 #include "voiceregs.hh"
19 #include "complexwalker.hh"
20 #include "misc.hh"
21 #include "commandrequest.hh"
22 #include "walkregs.hh"
25 void
26 Complex_walker::announce_element(Staff_elem_info info)
28 info.group_regs_l_ = find_voice_group((Voice*)info.voice_l_);
29 announce_info_arr_.push(info);
32 void
33 Complex_walker::do_announces()
35 Request dummy_req;
36 for (int i = 0; i < announce_info_arr_.size(); i++){
37 Staff_elem_info info = announce_info_arr_[i];
39 if (!info.req_l_)
40 info.req_l_ = &dummy_req;
42 walk_regs_p_->acknowledge_element(info);
43 for (iter_top(voice_reg_list_,j); j.ok(); j++) {
44 j->acknowledge_element(info);
46 for (iter_top ( group_reg_list_, j); j.ok(); j++) {
47 j->acknowledge_element(info);
52 Voice_registers *
53 Complex_walker::find_voice_reg(Voice*v_l)const
55 for (iter_top(voice_reg_list_, i); i.ok(); i++) {
56 if (i->voice_l_ == v_l)
57 return i;
59 return 0;
62 Voice_registers*
63 Complex_walker::get_voice_reg(Voice*v_l)
65 Voice_registers *regs_p=find_voice_reg(v_l);
66 if (regs_p)
67 return regs_p;
69 regs_p = new Voice_registers(this,v_l);
70 voice_reg_list_.bottom().add (regs_p);
71 return regs_p;
74 Voice_group_registers *
75 Complex_walker::find_voice_group(Voice* v_l)const
77 if (!voice_group_map_.elt_query(v_l))
78 return 0;
79 else return voice_group_map_[v_l];
82 Voice_group_registers *
83 Complex_walker::find_voice_group(const char *id)const
85 for (iter_top(group_reg_list_, i); i.ok(); i++)
86 if (i->group_id_str_ == id)
87 return i;
88 return 0;
92 Voice_group_registers *
93 Complex_walker::get_voice_group(Voice *v_l)
95 Voice_group_registers *group_p = find_voice_group(v_l);
96 if (group_p)
97 return group_p;
99 group_p = new Voice_group_registers(this);
100 group_reg_list_.bottom().add(group_p);
101 voice_group_map_[v_l] = group_p;
102 return group_p;
106 Voice_group_registers *
107 Complex_walker::get_voice_group(const char* id)
109 Voice_group_registers *group_p = find_voice_group(id);
110 if (group_p)
111 return group_p;
112 group_p = new Voice_group_registers(this,id);
113 group_reg_list_.bottom().add(group_p);
114 return group_p;
117 void
118 Complex_walker::do_change_group(Voice * v, String group_id_str)
120 voice_group_map_[v] = get_voice_group(group_id_str);
123 bool
124 Complex_walker::try_command_request(Command_req *req_l)
126 bool b=false;
127 Voice *voice_l = (Voice*)req_l->elt_l_->voice_l_; // ugh
128 if (req_l->groupchange()){
129 do_change_group(voice_l, req_l->groupchange()->newgroup_str_);
130 b|= true;
131 } else if(req_l->groupfeature()) {
132 Voice_group_registers* reg_l = get_voice_group(voice_l);
133 b |= reg_l->try_request(req_l);
134 } else {
135 b |= walk_regs_p_->try_request(req_l);
137 return b;
140 void
141 Complex_walker::try_request(Request*req)
143 bool b=false;
144 Voice *voice_l = (Voice*)req->elt_l_->voice_l_; // ahh. This sux
146 if (req->command()) {
147 b = try_command_request(req->command());
148 } else if (Voice_registers::acceptable_request_b(req)) {
149 Voice_registers *vregs_l = get_voice_reg(voice_l);
150 b = vregs_l->try_request(req);
151 } else if (Voice_group_registers::acceptable_request_b(req)){
152 Voice_group_registers* reg_l = get_voice_group(voice_l);
153 b = reg_l->try_request(req);
156 if (!b)
157 warning("junking request: " + String(req->name()),
158 req->defined_ch_c_l_);
161 void
162 Complex_walker::process_requests()
164 Staff_column*c =ptr();
166 for (int i=0; i < c->commandreq_l_arr_.size(); i++) {
167 try_request(c->commandreq_l_arr_[i]);
170 for (int i=0; i < c->musicalreq_l_arr_.size(); i++) {
171 try_request(c->musicalreq_l_arr_[i]);
174 regs_process_requests();
175 do_announces();
178 void
179 Complex_walker::regs_process_requests()
181 walk_regs_p_->process_requests();
182 for (iter_top(voice_reg_list_, j); j.ok(); j++) {
183 j->process_requests();
185 for (iter_top(group_reg_list_, j); j.ok(); j++)
186 j->process_requests();
189 void
190 Complex_walker::typeset_element(Staff_elem *elem_p)
192 if (!elem_p)
193 return;
194 if (elem_p->spanner())
195 pscore_l_->typeset_spanner(elem_p->spanner(), staff()->pstaff_l_);
196 else
197 ptr()->typeset_musical_item(elem_p->item());
200 Complex_walker::Complex_walker(Complex_staff*s)
201 : Staff_walker(s, s->pstaff_l_->pscore_l_)
203 walk_regs_p_ = new Walker_registers(this);
204 do_post_move();
208 Complex_walker::~Complex_walker()
213 Complex_walker::c0_position_i()const
215 return c0_position_i_;
218 void
219 Complex_walker::set_c0_position(int p)
221 c0_position_i_ =p;
224 Complex_staff*
225 Complex_walker::staff()
227 return (Complex_staff*) staff_l_;
231 void
232 Complex_walker::do_pre_move()
234 walk_regs_p_->pre_move_processing();
235 for (iter_top(voice_reg_list_,i); i.ok(); i++) {
236 i->pre_move_processing();
238 for (iter_top (group_reg_list_, j); j.ok(); j++)
239 j->pre_move_processing();
241 ptr()->typeset_breakable_items(prebreak_item_p_arr_,
242 nobreak_item_p_arr_,
243 postbreak_item_p_arr_);
246 void
247 Complex_walker::do_post_move()
249 walk_regs_p_->post_move_processing();
250 for (iter_top(voice_reg_list_,i); i.ok(); i++) {
251 i->post_move_processing();
253 announce_info_arr_.set_size(0);
254 for (iter_top (group_reg_list_, j); j.ok(); j++)
255 j->post_move_processing();
258 Array<Voice_registers*>
259 Complex_walker::get_voice_regs(Voice_group_registers* group_regs_l) const
260 return l_arr;
262 for (Assoc_iter<Voice*,Voice_group_registers*> i(voice_group_map_);
263 i.ok(); i++) {
264 if (i.val() == group_regs_l)
265 l_arr.push(find_voice_reg(i.key()));
269 void
270 Complex_walker::typeset_breakable_item(Item * pre_p , Item * nobreak_p,
271 Item * post_p)
273 if (pre_p)
274 prebreak_item_p_arr_.push(pre_p);
275 if (nobreak_p)
276 nobreak_item_p_arr_.push(nobreak_p);
277 if (post_p)
278 postbreak_item_p_arr_.push(post_p);