]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix 442.
authorJoe Neeman <joeneeman@gmail.com>
Thu, 22 Jul 2010 22:10:51 +0000 (15:10 -0700)
committerJoe Neeman <joeneeman@gmail.com>
Fri, 6 Aug 2010 21:52:39 +0000 (14:52 -0700)
Add an engraver which keeps all of the staves below
it alive together.

input/regression/hara-kiri-alive-with.ly [new file with mode: 0644]
lily/hara-kiri-group-spanner.cc
lily/include/hara-kiri-group-spanner.hh
lily/keep-alive-together-engraver.cc [new file with mode: 0644]
ly/engraver-init.ly
scm/define-grob-properties.scm

diff --git a/input/regression/hara-kiri-alive-with.ly b/input/regression/hara-kiri-alive-with.ly
new file mode 100644 (file)
index 0000000..a916c01
--- /dev/null
@@ -0,0 +1,23 @@
+\version "2.13.29"
+
+\header {
+  texidoc = "Staves in a PianoStaff remain alive as long as any of
+the staves has something interesting."
+}
+
+\layout {
+  \context {
+    \Staff
+    \RemoveEmptyStaves
+    \override VerticalAxisGroup #'remove-first = ##t
+  }
+}
+
+<<
+  \new Staff { c'1 \break c'1 \break c'1 }
+  \new PianoStaff
+  <<
+    \new Staff { d'1 R1 R1 }
+    \new Staff { R1 e'1 R1 }
+  >>
+>>
index 395bcdb553931e0db85b9b0ca7266318e5d09b0a..8f007197cd2bb7f3d10ddfff2a2f2318f4e4604f 100644 (file)
@@ -76,6 +76,20 @@ bool find_in_range (SCM vector, int low, int hi, int min, int max)
 
 bool
 Hara_kiri_group_spanner::request_suicide (Grob *me, int start, int end)
+{
+  if (!request_suicide_alone (me, start, end))
+    return false;
+
+  extract_grob_set (me, "keep-alive-with", friends);
+  for (vsize i = 0; i < friends.size (); ++i)
+    if (friends[i]->is_live () && !request_suicide_alone (friends[i], start, end))
+      return false;
+
+  return true;
+}
+
+bool
+Hara_kiri_group_spanner::request_suicide_alone (Grob *me, int start, int end)
 {
   if (!to_boolean (me->get_property ("remove-empty")))
     return false;
@@ -172,6 +186,7 @@ ADD_INTERFACE (Hara_kiri_group_spanner,
               /* properties */
               "items-worth-living "
               "important-column-ranks "
+              "keep-alive-with "
               "remove-empty "
               "remove-first "
               );
index bdc2cf36fff3d9fff90f15e50ef5e4c9ee7906d9..bea7c3a2210591ab6fca068808e90aabfa2d2008 100644 (file)
@@ -34,6 +34,7 @@ public:
   DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));
   DECLARE_GROB_INTERFACE();
   static bool request_suicide (Grob *me, int start, int end);
+  static bool request_suicide_alone (Grob *me, int start, int end);
   static void consider_suicide (Grob *me);
   static void add_interesting_item (Grob *me, Grob *n);
 };
diff --git a/lily/keep-alive-together-engraver.cc b/lily/keep-alive-together-engraver.cc
new file mode 100644 (file)
index 0000000..f4240cd
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2010 Joe Neeman <joeneeman@gmail.com>
+
+  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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "context.hh"
+#include "dispatcher.hh"
+#include "engraver.hh"
+#include "grob.hh"
+#include "grob-array.hh"
+
+#include "translator.icc"
+
+class Keep_alive_together_engraver: public Engraver
+{
+  vector<Grob*> group_spanners_;
+
+public:
+  TRANSLATOR_DECLARATIONS (Keep_alive_together_engraver);
+  DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
+
+  virtual void finalize ();
+};
+
+Keep_alive_together_engraver::Keep_alive_together_engraver ()
+{
+}
+
+void
+Keep_alive_together_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i)
+{
+  group_spanners_.push_back (i.grob ());
+}
+
+void
+Keep_alive_together_engraver::finalize ()
+{
+  for (vsize i = 0; i < group_spanners_.size (); ++i)
+    {
+      SCM grob_array_scm = Grob_array::make_array ();
+      Grob_array *ga = unsmob_grob_array (grob_array_scm);
+
+      // It would make Hara_kiri_group_spanner::request_suicide a _little_
+      // faster if we removed each grob from its own array. It seems
+      // unnecessary for now, though.
+      ga->set_array (group_spanners_);
+      group_spanners_[i]->set_object ("keep-alive-with", grob_array_scm);
+    }
+}
+
+ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
+
+ADD_TRANSLATOR (Keep_alive_together_engraver,
+               /* doc */
+               "This engraver collects all @code{Hara_kiri_group_spanner}s "
+               "that are created in contexts at or below its own.  "
+               "These spanners are then tied together so that one will "
+               "be removed only if all are removed.  For example, "
+               "if a @code{StaffGroup} uses this engraver, then the staves "
+               "in the group will all be visible as long as there is a note "
+               "in at least one of them.",
+
+               /* create */
+               "",
+
+               /* read */
+               "",
+
+               /* write */
+               ""
+               );
index 7b21ff2fef8c43de6195bc6c016d5b6447dc3781..6ecba2ddf4d372cd8ce1663e3b474ea0215c2cd7 100644 (file)
@@ -316,6 +316,7 @@ instrument names at the start of each system."
 
   \consists "Instrument_name_engraver"
   \consists "Vertical_align_engraver"
+  \consists "Keep_alive_together_engraver"
   topLevelAlignment = ##f
 
   \override StaffGrouper #'between-staff-spacing #'stretchability = #5
index b4952e2a498a78bff07dda94c8bd59ac85e99ec8..8fc2db4904f791edf26fcd769a60de5f1c277dbb 100644 (file)
@@ -950,6 +950,9 @@ in addition to notes and stems.")
      (items-worth-living ,ly:grob-array? "An array of interesting items.  If
 empty in a particular staff, then that staff is erased.")
 
+     (keep-alive-with ,ly:grob-array? "An array of other
+@code{VerticalAxisGroup}s.  If any of them are alive, then we will stay alive.")
+
      (left-items ,ly:grob-array? "DOCME")
      (left-neighbor ,ly:grob? "The right-most column that has a spacing-wish
 for this column.")