2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2002--2011 Juergen Reuter <reuter@ipd.uka.de>
5 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "engraver.hh"
23 #include "note-head.hh"
24 #include "note-column.hh"
25 #include "pointer-group-interface.hh"
27 #include "stream-event.hh"
30 #include "translator.icc"
32 class Cluster_spanner_engraver
: public Engraver
36 TRANSLATOR_DECLARATIONS (Cluster_spanner_engraver
);
37 DECLARE_TRANSLATOR_LISTENER (cluster_note
);
38 DECLARE_ACKNOWLEDGER (note_column
);
39 void stop_translation_timestep ();
40 virtual void process_music ();
41 virtual void finalize ();
43 vector
<Stream_event
*> cluster_notes_
;
46 void typeset_grobs ();
48 Spanner
*finished_spanner_
;
51 Cluster_spanner_engraver::Cluster_spanner_engraver ()
54 finished_spanner_
= 0;
59 Cluster_spanner_engraver::finalize ()
62 finished_spanner_
= spanner_
;
68 Cluster_spanner_engraver::typeset_grobs ()
70 if (finished_spanner_
)
72 if (!finished_spanner_
->get_bound (RIGHT
))
74 finished_spanner_
->set_bound (RIGHT
,
75 finished_spanner_
->get_bound (LEFT
));
79 finished_spanner_
= 0;
84 IMPLEMENT_TRANSLATOR_LISTENER (Cluster_spanner_engraver
, cluster_note
);
86 Cluster_spanner_engraver::listen_cluster_note (Stream_event
*ev
)
88 cluster_notes_
.push_back (ev
);
92 Cluster_spanner_engraver::process_music ()
94 if (cluster_notes_
.size ())
96 SCM c0scm
= get_property ("middleCPosition");
98 int c0
= scm_is_number (c0scm
) ? scm_to_int (c0scm
) : 0;
102 for (vsize i
= 0; i
< cluster_notes_
.size (); i
++)
104 Pitch
*pit
= unsmob_pitch (cluster_notes_
[i
]->get_property ("pitch"));
106 int p
= (pit
? pit
->steps () : 0) + c0
;
108 pmax
= max (pmax
, p
);
109 pmin
= min (pmin
, p
);
112 beacon_
= make_item ("ClusterSpannerBeacon", cluster_notes_
[0]->self_scm ());
113 beacon_
->set_property ("positions",
114 scm_cons (scm_from_int (pmin
),
115 scm_from_int (pmax
)));
118 if (beacon_
&& !spanner_
)
119 spanner_
= make_spanner ("ClusterSpanner", cluster_notes_
[0]->self_scm ());
121 if (beacon_
&& spanner_
)
123 add_bound_item (spanner_
, beacon_
);
124 Pointer_group_interface::add_grob (spanner_
, ly_symbol2scm ("columns"), beacon_
);
129 Cluster_spanner_engraver::stop_translation_timestep ()
132 cluster_notes_
.clear ();
136 Cluster_spanner_engraver::acknowledge_note_column (Grob_info info
)
138 if (!beacon_
&& Note_column::has_interface (info
.grob ()))
140 finished_spanner_
= spanner_
;
145 ADD_ACKNOWLEDGER (Cluster_spanner_engraver
, note_column
);
146 ADD_TRANSLATOR (Cluster_spanner_engraver
,
148 "Engrave a cluster using @code{Spanner} notation.",
152 "ClusterSpannerBeacon ",