/* This file is part of LilyPond, the GNU music typesetter. Copyright (C) 2000--2015 Han-Wen Nienhuys , Erik Sandberg 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. You should have received a copy of the GNU General Public License along with LilyPond. If not, see . */ #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" #include "translator.icc" class Percent_repeat_engraver : public Engraver { void typeset_perc (); public: TRANSLATOR_DECLARATIONS (Percent_repeat_engraver); protected: Stream_event *percent_event_; // moment (global time) where percent started Moment start_mom_; // moment (global time) where percent should end Moment stop_mom_; Spanner *percent_; Spanner *percent_counter_; Grob *first_command_column_; Moment command_moment_; virtual void finalize (); void listen_percent (Stream_event *); void start_translation_timestep (); void stop_translation_timestep (); void process_music (); }; Percent_repeat_engraver::Percent_repeat_engraver () { percent_ = 0; percent_counter_ = 0; percent_event_ = 0; first_command_column_ = 0; command_moment_ = Moment (-1); } void Percent_repeat_engraver::start_translation_timestep () { if (now_mom ().main_part_ != command_moment_.main_part_) { first_command_column_ = unsmob (get_property ("currentCommandColumn")); command_moment_ = now_mom (); } if (stop_mom_.main_part_ == now_mom ().main_part_) { if (percent_) typeset_perc (); percent_event_ = 0; } } void Percent_repeat_engraver::listen_percent (Stream_event *ev) { 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 { /* print a warning: no assignment happens because percent_event_ != 0 */ ASSIGN_EVENT_ONCE (percent_event_, ev); } } void Percent_repeat_engraver::process_music () { if (percent_event_ && now_mom ().main_part_ == start_mom_.main_part_) { 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 (!scm_is_null (count) && 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::finalize () { if (percent_) { percent_event_->origin ()->warning (_ ("unterminated percent repeat")); percent_->suicide (); percent_counter_->suicide (); } } void Percent_repeat_engraver::typeset_perc () { 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 () { } void Percent_repeat_engraver::boot () { ADD_LISTENER (Percent_repeat_engraver, percent); } ADD_TRANSLATOR (Percent_repeat_engraver, /* doc */ "Make whole measure repeats.", /* create */ "PercentRepeat " "PercentRepeatCounter ", /* read */ "countPercentRepeats " "currentCommandColumn " "repeatCountVisibility ", /* write */ "" );