Jean is correct in telling you why your approach does not work. The system is 
not something that is created in a certain timestep, but rather as a single 
grob at the begin of translation and then broken down afterward, basically 
copying the properties of the original System grob.

However while it is correct that we cannot use \override on already created 
grobs we can still change such values as long as we can get a reference to the 
grob. In this case this is quite easy. The System grob is X parent to the 
PaperColumn and Y parent to VerticalAlignment and thus an ancestor of pretty 
much any grob on the page. This means we can use the after-line-breaking 
callback of a grob to modify the System grob this particular grob is a 
descendant of.

Have a look at the appended file for details.

Cheers,
Valentin

Am Mittwoch, 18. Mai 2022, 16:02:30 CEST schrieb Jean Abou Samra:
> Le 18/05/2022 à 15:44, Rip _Mus a écrit :
> > Good morning,
> > I really appreciate your solutions and I'm trying to impress box only
> > on some systems of the score.
> > So I'm trying to do something like \once \override
> > Score.System.stencil = ...
> > But there is no response. I've tried also with \overrideProperty, but
> > nothing happens.
> > Do you have any advice for me?
> 
> Because there is actually only one system when you do the \override.
> It spans the whole score. You can't \override a grob's properties once
> it has been created, and the System was created at the very beginning.
> It is only much later that it is broken into several smaller systems.
> You could use \alterBroken if it supported callbacks, but it doesn't
> (well, they may or may not work or work partially depending on internal
> details) so you need to do the work yourself:
> 
> 
> \version "2.22.2"
> 
> #(define ((box-system-parts thickness padding parts) grob)
>     (let ((my-index (list-index (lambda (g)
>                                   (eq? g grob))
>                                 (ly:spanner-broken-into
>                                  (ly:grob-original grob)))))
>       (if (memv my-index parts)
>           (box-stencil
>            (ly:make-stencil
>             '()
>             (ly:grob-extent grob grob X)
>             (ly:grob-extent grob grob Y))
>            thickness
>            padding)
>           '())))
> 
> \layout {
>    \context {
>      \Score
>      \override System.stencil =
>        #(box-system-parts
>          0.2 ; thickness
>          0.3 ; padding
>          '(0 2 3))
>    }
> }
> 
> \repeat unfold 5 {
>    c'1
>    \break
> }
> 
> 
> Valentin's approach could also be adapted to do this.
> 
> Best,
> Jean

%%% DEFINITIONS FOR IMPROVED BOXING (NOT NESCESSARY BUT SPECIFYING THICKNESS AND PADDING WILL NOT WORK WITHOUT THIS!)
#(define*-public ((box-grob-stencil-with-thickness #:optional (thick 0.1) (pad 0)) grob)
  (let* ((xext (ly:grob-extent grob grob 0))
         (yext (ly:grob-extent grob grob 1))
         (xext (interval-widen xext pad))
         (yext (interval-widen yext pad)))
    (ly:stencil-add
      (make-filled-box-stencil (interval-widen xext thick) (cons (- (car yext) thick) (car yext)))
      (make-filled-box-stencil (interval-widen xext thick) (cons (cdr yext) (+ (cdr yext) thick)))
      (make-filled-box-stencil (cons (cdr xext) (+ (cdr xext) thick)) yext)
      (make-filled-box-stencil (cons (- (car xext) thick) (car xext)) yext))))

#(define-public (box-grob-stencil grob)
   (let* ((det (ly:grob-property grob 'details))
          (thick (assoc-get 'box-thickness det 0.1))
          (pad (assoc-get 'box-padding det 0)))
     ((box-grob-stencil-with-thickness thick pad) grob)))


%%% DEFINITION FOR BOXING SYSTEMS
#(define (find-parent-system grob)
   (if (null? grob)
       grob
       (if (grob::has-interface grob 'system-interface)
           grob
           (let ((X-dir (find-parent-system (ly:grob-parent grob X))))
             (if (null? X-dir)
                 (find-parent-system (ly:grob-parent grob Y))
                 X-dir)))))

boxCurrentSystem = <>
  -\tweak
  after-line-breaking
  #(lambda (grob)
     (let ((sys (find-parent-system grob)))
       (ly:grob-set-property! sys 'stencil box-grob-stencil)))
  -\tweak
  stencil
  ##f
  -\markup""

boxCurrentSystemWith =
#(define-music-function (thick pad) (number? number?)
   #{
     <>
     -\tweak
     after-line-breaking
     #(lambda (grob)
        (let* ((sys (find-parent-system grob))
               (det (ly:grob-property sys 'details))
               (det (cons* (cons 'box-thickness thick)
                           (cons 'box-padding pad)
                           det)))
          (ly:grob-set-property! sys 'stencil box-grob-stencil)
          (ly:grob-set-property! sys 'details det)))
     -\tweak
     stencil
     ##f
     -\markup""
   #})


%%% EXAMPLE
{
  c1 \break
  \boxCurrentSystem
  c \break
  c \break
  \boxCurrentSystemWith #0.4 #1
  c
}

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to