]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff-symbol-engraver.cc
* lily/tab-staff-symbol-engraver.cc: derive from Engraver, not
[lilypond.git] / lily / staff-symbol-engraver.cc
1 /*
2   staff-symbol-engraver.cc -- implement Staff_symbol_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "spanner.hh"
10 #include "engraver.hh"
11
12 class Staff_symbol_engraver : public Engraver
13 {
14 public:
15   TRANSLATOR_DECLARATIONS (Staff_symbol_engraver);
16
17 protected:
18   Drul_array<Music *> span_events_;
19   Spanner *span_;
20   Spanner *finished_span_;
21   bool first_start_;
22
23 protected:
24   virtual void start_spanner ();
25   virtual void stop_spanner ();
26
27   void stop_translation_timestep ();
28   virtual bool try_music (Music *);
29   virtual ~Staff_symbol_engraver ();
30   DECLARE_ACKNOWLEDGER (grob);
31   virtual void finalize ();
32   void process_music ();
33 };
34
35 Staff_symbol_engraver::~Staff_symbol_engraver ()
36 {
37   assert (!span_);
38 }
39
40 Staff_symbol_engraver::Staff_symbol_engraver ()
41 {
42   finished_span_ = 0;
43   first_start_ = true;
44   span_ = 0;
45   span_events_[LEFT] = 0;
46   span_events_[RIGHT] = 0;
47 }
48
49 bool
50 Staff_symbol_engraver::try_music (Music *music)
51 {
52   Direction d = to_dir (music->get_property ("span-direction"));
53   if (d)
54     {
55       span_events_[d] = music;
56       return true;
57     }
58
59   return false;
60 }
61
62 void
63 Staff_symbol_engraver::process_music ()
64 {
65   if (span_events_[STOP])
66     {
67       finished_span_ = span_;
68       span_ = 0;
69       if (first_start_)
70         first_start_ = false;
71     }
72
73   if (span_events_[START]
74       || (first_start_ && !span_events_[STOP]))
75     start_spanner ();
76 }
77
78 void
79 Staff_symbol_engraver::start_spanner ()
80 {
81   if (!span_)
82     {
83       span_ = make_spanner ("StaffSymbol", SCM_EOL);
84       span_->set_bound (LEFT,
85                         unsmob_grob (get_property ("currentCommandColumn")));
86     }
87 }
88
89 void
90 Staff_symbol_engraver::stop_spanner ()
91 {
92   if (!finished_span_)
93     return;
94
95   if (!finished_span_->get_bound (RIGHT))
96     finished_span_->set_bound (RIGHT, unsmob_grob (get_property ("currentCommandColumn")));
97   
98   announce_end_grob (finished_span_,
99                      span_events_[STOP]
100                      ? span_events_[STOP]->self_scm ()
101                      : SCM_EOL);
102   
103   finished_span_ = 0;
104 }
105
106 void
107 Staff_symbol_engraver::stop_translation_timestep ()
108 {
109   if ((span_events_[START] || first_start_)
110       && span_)
111     {
112       first_start_ = false;
113     }
114
115   span_events_[START] = 0;
116   span_events_[STOP] = 0;
117   stop_spanner ();
118 }
119
120 void
121 Staff_symbol_engraver::finalize ()
122 {
123   finished_span_ = span_;
124   span_ = 0;
125   stop_spanner ();
126 }
127
128 /*
129   Todo: staff-symbol-referencer iface.
130 */
131 void
132 Staff_symbol_engraver::acknowledge_grob (Grob_info s)
133 {
134   /*
135     Perhaps should try to take SeparationItem as bound of the staff
136     symbol?
137   */
138   if (span_ || finished_span_)
139     {
140       Spanner *my = span_ ? span_ : finished_span_;
141       s.grob ()->set_object ("staff-symbol", my->self_scm ());
142     }
143 }
144
145 #include "translator.icc"
146
147 ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob);
148
149 ADD_TRANSLATOR (Staff_symbol_engraver,
150                 /* doc */ "Create the constellation of five (default) "
151                 "staff lines.",
152                 /* create */ "StaffSymbol",
153                 /* accept */ "staff-span-event",
154                 /* read */ "",
155                 /* write */ "");