X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-head-line-engraver.cc;h=fee6c1e63c9c6fb4a30217b0945140519fa85e90;hb=304b5f3aa7eee7b0ff8d4ba7526a1410735f6e74;hp=9469688536d08bb42032d3bd5b63bdd259b884e4;hpb=a2d1453c850bc637873bdd95bba3f51dd03dfae8;p=lilypond.git diff --git a/lily/note-head-line-engraver.cc b/lily/note-head-line-engraver.cc index 9469688536..fee6c1e63c 100644 --- a/lily/note-head-line-engraver.cc +++ b/lily/note-head-line-engraver.cc @@ -3,110 +3,98 @@ source file of the GNU LilyPond music typesetter - (c) 2000 Jan Nieuwenhuizen + (c) 2000--2004 Jan Nieuwenhuizen */ #include "engraver.hh" #include "group-interface.hh" #include "item.hh" -#include "musical-request.hh" +#include "event.hh" #include "spanner.hh" +#include "stem.hh" #include "rhythmic-head.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" -#include "translator-group.hh" -#include "protected-scm.hh" +#include "context.hh" + /** - Create line-spanner grobs for glissandi (and possibly other) lines - that connect note heads. - */ + Create line-spanner grobs for lines that connect note heads. + TODO: have the line commit suicide if the notes are connected with + either slur or beam. + +*/ class Note_head_line_engraver : public Engraver { public: - VIRTUAL_COPY_CONS (Translator); - Note_head_line_engraver (); + TRANSLATOR_DECLARATIONS (Note_head_line_engraver); protected: virtual void acknowledge_grob (Grob_info); - virtual void create_grobs (); + virtual void process_acknowledged_grobs (); virtual void stop_translation_timestep (); - virtual bool try_music (Music *); private: Spanner* line_; - Request* req_; - Protected_scm heads_; - Translator* last_staff_; + Context* last_staff_; + bool follow_; + Grob* head_; Grob* last_head_; }; Note_head_line_engraver::Note_head_line_engraver () { line_ = 0; - req_ = 0; - heads_ = SCM_EOL; + follow_ = false; + head_ = 0; last_head_ = 0; last_staff_ = 0; } -bool -Note_head_line_engraver::try_music (Music* m) -{ - if (!req_) - { - if (Glissando_req *r = dynamic_cast (m)) - { - req_ = r; - return true; - } - } - return false; -} - void Note_head_line_engraver::acknowledge_grob (Grob_info info) { - if (Rhythmic_head::has_interface (info.elem_l_)) + if (Rhythmic_head::has_interface (info.grob_)) { - if (req_) - heads_ = gh_cons (info.elem_l_->self_scm (), heads_); - else if (to_boolean (get_property ("followThread"))) + head_ = info.grob_; + if (to_boolean (get_property ("followVoice"))) { - Translator* staff = daddy_trans_l_ && daddy_trans_l_->daddy_trans_l_ - ? daddy_trans_l_->daddy_trans_l_->daddy_trans_l_ : 0; - if (staff != last_staff_) + Context * tr = daddy_context_; + while (tr && !tr->is_alias (ly_symbol2scm ( "Staff"))) + tr = tr->daddy_context_ ; + + if (tr + && tr->is_alias (ly_symbol2scm ("Staff")) && tr != last_staff_) { if (last_head_) - heads_ = gh_list (info.elem_l_->self_scm (), - last_head_->self_scm (), SCM_UNDEFINED); - last_staff_ = staff; + follow_ = true; + last_staff_ = tr; } - last_head_ = info.elem_l_; } } } + void -Note_head_line_engraver::create_grobs () +Note_head_line_engraver::process_acknowledged_grobs () { - if (!line_ && scm_ilength (heads_) > 1) + if (!line_ && follow_ && last_head_ && head_) { - /* type Glissando? */ - line_ = new Spanner (get_property ("NoteHeadLine")); - line_->set_bound (LEFT, unsmob_grob (gh_car (heads_))); - line_->set_bound (RIGHT, unsmob_grob (ly_last (heads_))); - - line_->set_parent (unsmob_grob (gh_car (heads_)), X_AXIS); - line_->set_parent (unsmob_grob (gh_car (heads_)), Y_AXIS); - - line_->set_parent (unsmob_grob (ly_last (heads_)), X_AXIS); - line_->set_parent (unsmob_grob (ly_last (heads_)), Y_AXIS); - - announce_grob (line_, req_); - req_ = 0; - heads_ = SCM_EOL; + /* TODO: Don't follow if there's a beam. + + We can't do beam-stuff here, since beam doesn't exist yet. + Should probably store follow_ in line_, and suicide at some + later point */ + if (follow_) + line_ = make_spanner ("VoiceFollower"); + + line_->set_bound (LEFT, last_head_); + line_->set_bound (RIGHT, head_); + + announce_grob (line_, head_->self_scm ()); + + follow_ = false; } } @@ -118,8 +106,19 @@ Note_head_line_engraver::stop_translation_timestep () typeset_grob (line_); line_ = 0; } + if (head_) + last_head_ = head_; + head_ = 0; } -ADD_THIS_TRANSLATOR (Note_head_line_engraver); + +ENTER_DESCRIPTION (Note_head_line_engraver, +/* descr */ "Engrave a line between two note heads, for example a glissando. If " +" followVoice is set, staff switches also generate a line.", +/* creats*/ "Glissando VoiceFollower", +/* accepts */ "glissando-event", +/* acks */ "rhythmic-head-interface", +/* reads */ "followVoice", +/* write */ "");