lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Accessing a grob from within a music function


From: Urs Liska
Subject: Re: Accessing a grob from within a music function
Date: Thu, 16 Mar 2017 16:15:52 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.6.0


Am 16.03.2017 um 15:50 schrieb David Nalesnik:
> On Thu, Mar 16, 2017 at 9:29 AM, Urs Liska <address@hidden> wrote:
>>
>> Am 16.03.2017 um 14:55 schrieb David Nalesnik:
>>> Urs,
>>>
>>> On Thu, Mar 16, 2017 at 8:47 AM, Urs Liska <address@hidden> wrote:
>>>> Hi David,
>>>>
>>>>
>>>> Am 16.03.2017 um 14:40 schrieb David Nalesnik:
>>>>> Hi Urs,
>>>>>
>>>>> On Thu, Mar 16, 2017 at 8:23 AM, Urs Liska <address@hidden> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I'm trying to write a function to push a note column like this:
>>>>>>
>>>>>> pushLeftBroken =
>>>>>> #(define-music-function ()()
>>>>>>    #{
>>>>>>      \once \override NoteColumn.X-offset = 3
>>>>>>    #})
>>>>>>
>>>>>> But I need to make that "3" depend on some characteristics of the actual
>>>>>> note column. Basically I need the width of the note column, including
>>>>>> attached accidentals.
>>>>>>
>>>>>> I know how to get to the accidental(s) within a note column, but if I'm
>>>>>> not mistaken there's no actual grob inside that.
>>>>>>
>>>>>> Probably music-function isn't the right approach?
>>>>>>
>>>>>> What I need is a way to say something like
>>>>>>
>>>>>> \once \override NoteColumn.X-offset = #(+ 3
>>>>>> extent-of-all-accidentals-in-the-note-column)
>>>>>>
>>>>> In the majority of cases you can follow a trail of pointers.  From the
>>>>> NoteColumn, you can get noteheads or AccidentalPlacement, from
>>>>> noteheads you can get to accidentals.
>>>>> \version "2.19.56"
>>>>>
>>>>> {
>>>>>   \override NoteColumn.X-offset =
>>>>>   #(lambda (nc)
>>>>>      (let ((notes (ly:grob-array->list (ly:grob-object nc 'note-heads))))
>>>>>        (pretty-print (grob::all-objects nc))
>>>>>        (pretty-print (grob::all-objects (car notes)))))
>>>>>   <cis'' dis'' fis'' gis''>1
>>>>> }
>>>>>
>>>>> I presume that travelling up the chain of parentage -- to a
>>>>> PaperColumn -- would get you more grobs ('elements object property).
>>>>>
>>>>> -David
>>>> Thank you, this will give me all I need.
>> Unfortunately I have to take that back.
>> Usually (when writing the stencil callback) I can access the horizontal
>> position of elements (to determine their distances) with
>> ly:grob-relative-coordinate and ly:grob-system.
>> But in this function (ly:grob-system nc) returns an empty list, which
>> probably means that I'm too early to access that property yet.
> ly:grob-system returns System grobs after line-breaking has occurred.

Which is what I was thinking.

>
> Try this:
>
> #(define get-system
>    (lambda (grob)
>      (cond
>       ((not (ly:grob? grob)) '())
>       ((grob::has-interface grob 'system-interface) grob)
>       (else (get-system (ly:grob-parent grob Y))))))

This indeed brings me further, as it *does* give me access to the system
and to ly:grob-relative-coordinate.
Unfortunately it behaves differently, see below.

>
>> What I need is a way to push the notecolumn to the right by a fixed
>> amount *plus* the horizontal extent of the accidentals. The problem is
>> that if I simply push by the fixed amount it seems not to actually use
>> that. Obviously first the override pushes and then the accidentals
>> themselves push even further (see attachment):
> I don't think I understand.
>
> What I see is that X-offset must reach a certain threshold to show a
> noticeable result, after which there clearly aren't dual pushes.  (The
> last line has accidentals and note column 3 ss to the right of the
> second.)

Let's assume the accidentals take up 6 ss in the example (just a rough
visual guess).
Overriding the X-offset with any value <= 6 doesn't have any effect.
Overriding with any value > 6 pushes the note column by (- value 6).
So: if I need the empty space to be 3 ss I'd have to override X-offset
with 9.
The problem is that I don't know the extent of the accidentals so I
don't have a reliable push of everything.

>> \version "2.19.54"
>>
>> {
>>   <cis'' dis'' eis'' fis''>
>> }
>> {
>>   \once \override NoteColumn.X-offset = 7
>>   <cis'' dis'' eis'' fis''>
>> }
>> {
>>   \once \override NoteColumn.X-offset = 10
>>   <cis'' dis'' eis'' fis''>
>> }
>>
>> But as you can see in the image I need the empty space to have a fixed
>> amount, and so I'd need to figure out the value (+ fixed-amount
>> accidentals-width).
> Wait, you don't want the accidentals to follow the note column?

No, no, I *do* want to push them together, in order to have some space
to the left of the chord.

With your (get-system) method I can actually push the note column
reliably - but now the accidentals keep their position ...

It seems I'm having a problem with the fact that LilyPond does still try
to optimize the layout, so the accidentals and the note heads don't
really move in sync. Sometimes the accidentals move over the notes,
sometimes the notes move alone ...

Pretty confusing, at least for me.
Urs

>
> Sorry for my obtuseness.
>
> -David

-- 
address@hidden
https://openlilylib.org
http://lilypondblog.org




reply via email to

[Prev in Thread] Current Thread [Next in Thread]