X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpercent-repeat-engraver.cc;h=b2ba05f1ecd5ff99cfe0c6f35dd9c7a71cee0830;hb=5bbfc22fce036b9b69df5e420de93e11da23c05e;hp=3090e9b615cce4ab84fe4f5d109bbf0b7a40d555;hpb=304b5f3aa7eee7b0ff8d4ba7526a1410735f6e74;p=lilypond.git diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index 3090e9b615..b2ba05f1ec 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -1,222 +1,187 @@ -/* - new-chord-tremolo-engraver.cc -- implement Chord_tremolo_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2000--2004 Han-Wen Nienhuys - - */ +/* + This file is part of LilyPond, the GNU music typesetter. -#include "engraver.hh" -#include "repeated-music.hh" -#include "engraver-group-engraver.hh" -#include "global-context.hh" -#include "warn.hh" -#include "misc.hh" -#include "spanner.hh" -#include "item.hh" -#include "percent-repeat-iterator.hh" -#include "bar-line.hh" + Copyright (C) 2000--2014 Han-Wen Nienhuys , Erik Sandberg -#include "score-engraver.hh" -#include "context.hh" + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -/** - This acknowledges repeated music with "percent" style. It typesets - a % sign. + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . +*/ - TODO: +#include "engraver.hh" +#include "global-context.hh" +#include "international.hh" +#include "item.hh" +#include "side-position-interface.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "warn.hh" - - BEAT case: Create items for single beat repeats, i.e. c4 / / / +#include "translator.icc" - - DOUBLE_MEASURE case: attach a % to an appropriate barline. - -*/ class Percent_repeat_engraver : public Engraver { void typeset_perc (); + public: TRANSLATOR_DECLARATIONS (Percent_repeat_engraver); + protected: - Repeated_music * repeat_; + Stream_event *percent_event_; - /// moment (global time) where beam started. + // moment (global time) where percent started Moment start_mom_; + // moment (global time) where percent should end Moment stop_mom_; - /// location within measure where beam started. - Moment beam_start_location_; - Moment next_moment_; - Moment body_length_; + Spanner *percent_; + Spanner *percent_counter_; - enum { - UNKNOWN, - MEASURE, - DOUBLE_MEASURE, - } repeat_sign_type_ ; + Grob *first_command_column_; + Moment command_moment_; - Item * double_percent_; - Spanner * perc_; - Spanner * finished_perc_; -protected: virtual void finalize (); - virtual bool try_music (Music*); - virtual void stop_translation_timestep (); - virtual void start_translation_timestep (); - virtual void process_music (); + DECLARE_TRANSLATOR_LISTENER (percent); + + void start_translation_timestep (); + void stop_translation_timestep (); + void process_music (); }; Percent_repeat_engraver::Percent_repeat_engraver () { - perc_ = 0; - finished_perc_ = 0; - repeat_ =0; + percent_ = 0; + percent_counter_ = 0; + percent_event_ = 0; - double_percent_ = 0; + first_command_column_ = 0; + command_moment_ = Moment (-1); } -bool -Percent_repeat_engraver::try_music (Music * m) +void +Percent_repeat_engraver::start_translation_timestep () { - Repeated_music * rp = dynamic_cast (m); - if (rp - && rp->get_property ("iterator-ctor") - == Percent_repeat_iterator::constructor_proc - && !repeat_) + if (now_mom ().main_part_ != command_moment_.main_part_) { - body_length_ = rp->body_get_length (); - int count = rp->repeat_count (); - - Moment now = now_mom (); - start_mom_ = now; - stop_mom_ = start_mom_ + Moment (count) * body_length_; - next_moment_ = start_mom_ + body_length_; - - SCM m = get_property ("measureLength"); - Moment meas_len; - if (unsmob_moment (m)) - meas_len = *unsmob_moment (m); - - if (meas_len == body_length_) - repeat_sign_type_ = MEASURE; - else if (Moment (2)* meas_len == body_length_) - { - repeat_sign_type_ = DOUBLE_MEASURE; - next_moment_ += meas_len ; - } - else - { - warning (_ ("Don't know how to handle a percent repeat of this length.")); - return false; - } - - repeat_ = rp; - - - Global_context *global = get_global_context (); - for (int i = 0; i < count; i++) - global->add_moment_to_process (next_moment_ + Moment (i) * body_length_); - - return true; + first_command_column_ + = Grob::unsmob (get_property ("currentCommandColumn")); + command_moment_ = now_mom (); } - return false; + if (stop_mom_.main_part_ == now_mom ().main_part_) + { + if (percent_) + typeset_perc (); + percent_event_ = 0; + } } +IMPLEMENT_TRANSLATOR_LISTENER (Percent_repeat_engraver, percent); void -Percent_repeat_engraver::process_music () +Percent_repeat_engraver::listen_percent (Stream_event *ev) { - if (repeat_ && now_mom () == next_moment_) + if (!percent_event_) + { + Moment body_length = get_event_length (ev); + start_mom_ = now_mom (); + stop_mom_ = now_mom () + body_length; + get_global_context ()->add_moment_to_process (stop_mom_); + percent_event_ = ev; + } + else { - if (repeat_sign_type_ == MEASURE) - { - finished_perc_ = perc_; - typeset_perc (); - perc_ = make_spanner ("PercentRepeat"); - SCM col =get_property ("currentCommandColumn"); - perc_->set_bound (LEFT, unsmob_grob (col)); - announce_grob (perc_, repeat_->self_scm ()); - } - else if (repeat_sign_type_ == DOUBLE_MEASURE) - { - double_percent_ = make_item ("DoublePercentRepeat"); - announce_grob (double_percent_, repeat_->self_scm ()); - /* - forbid breaks on a % line. Should forbid all breaks, really. - */ - - get_score_engraver ()->forbid_breaks (); // guh. Use properties! - } - next_moment_ = next_moment_ + body_length_; - - get_global_context ()->add_moment_to_process (next_moment_); + print a warning: no assignment happens because + percent_event_ != 0 + */ + ASSIGN_EVENT_ONCE (percent_event_, ev); } } void -Percent_repeat_engraver::finalize () +Percent_repeat_engraver::process_music () { - typeset_perc (); - if (perc_) + if (percent_event_ + && now_mom ().main_part_ == start_mom_.main_part_) { - repeat_->origin ()->warning (_ ("unterminated percent repeat")); - perc_->suicide (); + if (percent_) + typeset_perc (); + + percent_ = make_spanner ("PercentRepeat", percent_event_->self_scm ()); + + Grob *col = first_command_column_; + percent_->set_bound (LEFT, col); + + SCM count = percent_event_->get_property ("repeat-count"); + if (count != SCM_EOL && to_boolean (get_property ("countPercentRepeats")) + && check_repeat_count_visibility (context (), count)) + { + percent_counter_ = make_spanner ("PercentRepeatCounter", + percent_event_->self_scm ()); + + SCM text = scm_number_to_string (count, scm_from_int (10)); + percent_counter_->set_property ("text", text); + percent_counter_->set_bound (LEFT, col); + Side_position_interface::add_support (percent_counter_, percent_); + percent_counter_->set_parent (percent_, Y_AXIS); + percent_counter_->set_parent (percent_, X_AXIS); + } + else + percent_counter_ = 0; } } void -Percent_repeat_engraver::typeset_perc () +Percent_repeat_engraver::finalize () { - if (finished_perc_) - { - SCM col =get_property ("currentCommandColumn"); - finished_perc_->set_bound (RIGHT, unsmob_grob (col)); - typeset_grob (finished_perc_); - finished_perc_ = 0; - } - - if (double_percent_) + if (percent_) { - typeset_grob (double_percent_); - double_percent_ = 0; + percent_event_->origin ()->warning (_ ("unterminated percent repeat")); + percent_->suicide (); + percent_counter_->suicide (); } } - - - void -Percent_repeat_engraver::start_translation_timestep () +Percent_repeat_engraver::typeset_perc () { - if (stop_mom_ == now_mom ()) - { - if (perc_) - { - finished_perc_ = perc_; - typeset_perc (); - } - repeat_ = 0; - perc_ = 0; - repeat_sign_type_ = UNKNOWN; - } -} + Grob *col = first_command_column_; + percent_->set_bound (RIGHT, col); + percent_ = 0; + + if (percent_counter_) + percent_counter_->set_bound (RIGHT, col); + percent_counter_ = 0; +} void Percent_repeat_engraver::stop_translation_timestep () { - typeset_perc (); } +ADD_TRANSLATOR (Percent_repeat_engraver, + /* doc */ + "Make whole measure repeats.", + /* create */ + "PercentRepeat " + "PercentRepeatCounter ", + /* read */ + "countPercentRepeats " + "currentCommandColumn " + "repeatCountVisibility ", -ENTER_DESCRIPTION (Percent_repeat_engraver, -/* descr */ "Make whole bar and double bar repeats.", -/* creats*/ "PercentRepeat DoublePercentRepeat", -/* accepts */ "repeated-music", -/* acks */ "", -/* reads */ "measureLength currentCommandColumn", -/* write */ ""); + /* write */ + "" + );