]> git.donarmstrong.com Git - lilypond.git/blob - lily/multi-measure-rest-engraver.cc
release: 1.3.69
[lilypond.git] / lily / multi-measure-rest-engraver.cc
1 /*
2   multi_measure_rest-engraver.cc -- implement Multi_measure_rest_engraver
3
4   (c) 1998--2000 Jan Nieuwenhuizen <janneke@gnu.org>
5        Han-Wen Nienhuys <hanwen@cs.uu.nl>
6 */
7
8 #include "proto.hh"
9 #include "musical-request.hh"
10 #include "multi-measure-rest.hh"
11 #include "paper-column.hh"
12 #include "engraver-group-engraver.hh"
13 #include "bar.hh"
14 #include "staff-symbol-referencer.hh"
15 #include "engraver.hh"
16 #include "moment.hh"
17 #include "spanner.hh"
18
19 /**
20    The name says it all: make multi measure rests 
21  */
22 class Multi_measure_rest_engraver : public Engraver
23 {
24 public:
25   VIRTUAL_COPY_CONS(Translator);
26   Multi_measure_rest_engraver ();
27
28 protected:
29   virtual void acknowledge_element (Score_element_info i);
30   virtual void do_process_music ();
31   virtual bool do_try_music (Music*);
32   virtual void do_pre_move_processing ();
33   virtual void do_post_move_processing ();
34   virtual void do_removal_processing ();
35 private:
36   Span_req * new_req_l_;
37   Span_req * busy_span_req_l_;
38   Span_req * stop_req_l_;
39   int start_measure_i_;
40   Moment start_moment_;
41   
42   Spanner *mmrest_p_;
43   Spanner *lastrest_p_;
44 };
45
46 ADD_THIS_TRANSLATOR (Multi_measure_rest_engraver);
47
48 Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
49 {
50   start_measure_i_ = 0;
51   mmrest_p_  = lastrest_p_ =0;
52   new_req_l_ = busy_span_req_l_ = stop_req_l_ =0;
53 }
54
55 void
56 Multi_measure_rest_engraver::acknowledge_element (Score_element_info i)
57 {
58   Item * item = dynamic_cast<Item*> (i.elem_l_); 
59   if (item && Bar::has_interface (item))
60     {
61       if (mmrest_p_)
62         Multi_measure_rest::add_column (mmrest_p_,item);
63       if (lastrest_p_)
64         Multi_measure_rest::add_column (lastrest_p_,item);
65     }
66 }
67
68 bool
69 Multi_measure_rest_engraver::do_try_music (Music* req_l)
70 {
71   if (Span_req * sp = dynamic_cast<Span_req*> (req_l))
72     {
73       if (sp->span_type_str_ == "rest")
74         {
75           if (sp->span_dir_ == STOP)
76             {
77               stop_req_l_ = sp;
78             }
79           else if (sp->span_dir_ == START && !new_req_l_)
80             {
81               new_req_l_ = sp;
82             }
83           return true;
84         }
85     }
86   return false;
87 }
88
89
90
91 void
92 Multi_measure_rest_engraver::do_process_music ()
93 {
94   if (new_req_l_ && stop_req_l_)
95     stop_req_l_ = 0;
96
97   if (new_req_l_)
98     start_moment_ = now_mom ();
99
100   if (stop_req_l_)
101     {
102       busy_span_req_l_ =0;
103       stop_req_l_ = 0;
104     }
105   
106   if (new_req_l_)
107     {
108       busy_span_req_l_ = new_req_l_;
109       new_req_l_ =0;
110     }
111
112   if (busy_span_req_l_ && !mmrest_p_)
113     {
114       mmrest_p_ = new Multi_measure_rest (get_property ("basicMultiMeasureRestProperties"));
115       Multi_measure_rest::set_interface (mmrest_p_);
116       Staff_symbol_referencer::set_interface (mmrest_p_);
117
118       announce_element (Score_element_info (mmrest_p_, busy_span_req_l_));
119       start_measure_i_
120         = gh_scm2int (get_property ("currentBarNumber"));
121     }
122 }
123
124 void
125 Multi_measure_rest_engraver::do_pre_move_processing ()
126 {
127   SCM smp = get_property ("measurePosition");
128   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
129
130   if (mmrest_p_ && (now_mom () >= start_moment_) 
131     && !mp
132     && (scm_ilength (mmrest_p_->get_elt_property ("columns")) >= 2))
133     {
134       typeset_element (mmrest_p_);
135       /*
136         must keep mmrest_p_ around to set measures_i_
137        */
138     }
139   if (lastrest_p_)
140     {
141       typeset_element (lastrest_p_);
142       lastrest_p_ = 0;
143     }
144
145   if (new_req_l_)
146     {
147       busy_span_req_l_ = new_req_l_;
148       new_req_l_ =0;
149     }
150   
151 }
152
153 void
154 Multi_measure_rest_engraver::do_post_move_processing ()
155 {
156   Moment now (now_mom ());
157   
158   
159   SCM smp = get_property ("measurePosition");
160   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
161   
162   if (mmrest_p_ && !mp)
163     {
164       lastrest_p_ = mmrest_p_;
165       int cur = gh_scm2int (get_property ("currentBarNumber"));
166       lastrest_p_->set_elt_property ("measure-count",
167                                      gh_int2scm (cur - start_measure_i_));
168       mmrest_p_ = 0;
169     }
170 }
171
172
173 void
174 Multi_measure_rest_engraver::do_removal_processing ()
175 {
176   if (mmrest_p_)
177     typeset_element (mmrest_p_);
178   if (lastrest_p_)
179     typeset_element (lastrest_p_);
180 }