Skip to main content
Topic: Connected bar only at end of score (and staffs) - is this possible? (Read 7109 times) previous topic - next topic

Connected bar only at end of score (and staffs) - is this possible?

Ist there any way to get the bars like in the attached example, i.e.
  • unconnected inside the staffs, but
  • connected at the staff ends?
I would also be satisfied if only the closing bar of the whole piece were connected.

(I tried a few tricksy things with a layered staff with transparent connected bars, where the whole staff is collapsed up to the end, and only the last closing bar is after a "cancel collapse"; but if I put this staff above the real staff, the connect does not work (it connects to the next logical staff, i.e. the one on which the hidden one is layered); and if it is below, the layered staff somehow "inherits" the "connect bar lines" property from the one below, so that once again, all bar lines are connected  :( ).

Did I overlook something obvious, or something not so obvious?

H.M.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #1
Hi,
Some time ago, I started to script a User Object to do exactly this... I've never finished it, but I'll re-take the script today afternoon and I'll post something.
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #2
Ok, as I promissed here's a little -extremely simple- user object to achieve what you (we ;)) want.
It's still testing object, so try it and, if you like it and consider it as a good one, I'll upload it into the User Objects Forum.

There's some uncomfortable limitations with it... but the most significative is that it's not authomatic :'( ... so you must enter one instance for each bar in each staff... in a large scores it would for sure it will be a problem.

Anyway... try it and tell me how do you think about ;)
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #3
Nice work Lloyd. Should work for many situations.
A problem in Print Preview if you add this to the beginning of your example:
Code: (nwc) [Select · Download]
!NoteWorthyComposerClip(2.751,Single)
|Boundary|Style:NewSize|Upper:8|Lower:16
!NoteWorthyComposerClip-End
Registered user since 1996

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #4
Sure there's a problem with this, Rick... I'll try to fix it as soon as possible and I'll uploat this into the plugins forum  :))
Thanks for the feedback!
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #5
Wow - works perfect for my score! - thanks a lot ... this also helps me in a discussion we have currently about how to produce good-looking and useful scores for our choir!
I will also need it for a score with about 14 pages = 14*12 = 168 staffs ... it will take a little bit of work to add them manually, but that's ok (also the notes needed to be added manually, and there are many more of them  :) ).

Many thanks!

H.M.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #6
The code for the plugin looks very straightforward and should work as intended (once the presence of boundary change objects is accounted for, per @Rick G.'s suggestion). However, I was wondering whether @Lloyd had considered using a Staffsig object. If that approach were used, only a single instance would be needed per staff.

 

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #7
Quote
had considered using a Staffsig object.

Thanks Mike! I considered it :D ... but I thought there's more than one way to make a system break (as well as the NWC default), so it was faster -and easier- to make it this way. I know it's very uncomfortable to add each instance one by one manually, but I'll work on it ( first on Rick G's suggestion, next on StaffSig function  ;) )
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #8
once the presence of boundary change objects is accounted for,
Easier said than done, I think.
Registered user since 1996

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #9
Quote
Easier said than done, I think.
In fact I think it's not as difficult... maybe I'm worng because I only did a few tests yesterday, but I think it's not really complicated  ::)
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #10
I think it's not really complicated  ::)
I hope you are right. It could be that some new function call(s) were added.
When I last looked at the API, it seemed that that all the Boundary items in the current system have to be identified and the largest value selected. If there was no Boundary item setting the boundary in the first bar of the system, the Boundary item prior to the system that set the boundary would need to be located and used. This seemed too complex for me so I gave up.
Registered user since 1996

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #11
The following questions should maybe be asked under user plugins - but it concerns not a specific plugin but the API, so I continue here ...

Lloyd's plugin was a god's send - but I found that I needed the functionality that it draws the connected bars automatically at the end of each line. The reason is that I typically produce two scores from an arrangement: One for the singers, with the vocal voices only; and one for the director, with vocal voices and (e.g.) piano staffs. Of course, these two scores break their lines at different places ...

... so I set out to do this. I now have a solution (code is below; attached is an example score with the two created PDFs), but I am somewhat flabbergasted why it works, for I do not at all understand two effects of the API:

a) It seems that when printing, the draw event is called once per staff line. I thought that I would have to write a loop for my "draw at each bar that is at the end of a staff line", and already had in place a more or less convoluted logic using getSystemCounter() to find the line breaks ... but the plugin code is actually much simpler. Only - is this so intended? or is my code based on some more or less fishy feature of the API??

// Edit: I re-read the documentation, and it says as the meaning of "StaffSig":
The nearest instance of this object will always be added at the front of each printed staff system...
Now, these "added objects" in turn will trigger a call to the draw method, so - yes, in effect, draw is called once per "printed staff" (what I called "staff line" above). So I'd now say that my code is legal. ... slowly, understanding dawns ...

b) Still, finding that last bar is a little different from what I expected. When I simple wrote

  local found = nextBar:find('last', 'bar')

the current object was the last bar but one! But with the current code, which reads

  local found = nextBar:find('last', 'bar')
  found = nextBar:find('next', 'bar')

I end up at exactly that "last bar" that I want to extend with Lloyd's drawing code. Is this intended - maybe because I am now not at the "last bar", but actually at the first bar of the next staff line, which is just "mimicked back" to the previous line?

Anyway - Lloyd, could we together (or you) make this now a publishable plugin? what else would have to be done?

Here is the code:
Code: [Select · Download]
-- ConnectBarLines2 - derived from Lloyd's ConnectBarLines 
-- Version 0.1

--[[--------------------------------------------------------------------------

This plugin will connect barlines with the staff below. You must specify if the current staff is Upper, Middle or Lower staff in order to draw connections correctly.

--]]--------------------------------------------------------------------------

local userObjTypeName = ...
local nextBar = nwc.drawpos.new()
local afterBar = nwc.drawpos.new()
local drawpos = nwcdraw.user

local object_spec = {
{ id='System', label='Staff Location', type='enum', default='Top Staff', list={'Top Staff', 'Middle Staff', 'Bottom Staff'}},
}

local function do_create(t)
    t.Class = 'StaffSig'
end

local function do_draw(t)
  local w = nwc.toolbox.drawStaffSigLabel('BarLines')
  if not nwcdraw.isDrawing() then return w end
  if drawpos:isHidden() then return end

  local yPosTop = nwcdraw.getStaffProp('BoundaryTop')
  local yPosBottom = nwcdraw.getStaffProp('BoundaryBottom')

  local found = nextBar:find('last', 'bar')
  found = nextBar:find('next', 'bar')

  if found then   
    local x,y = nextBar:xyAnchor()
    local barType = nextBar:objProp('Style')

    if t.System == 'Top Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(barType,y-4,y-yPosBottom)
    elseif t.System == 'Middle Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(barType,y+4,y+yPosTop)
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(barType,y-4,y-yPosBottom)
    elseif t.System == 'Bottom Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(barType,y+4,y+yPosTop)
    end
  end
end

return {
  spec  = object_spec,
  create  = do_create,
  width  = do_draw,
  draw  = do_draw,
}

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #12
Hi H.M.
don't think I forfot about this... but I've been working a lot this summer (musicians' life ::) )

Those corrections over my script were really great, so.........
Quote
Lloyd, could we together (or you) make this now a publishable plugin?
.........of course WE can. If you don't have an ID to publish the plugin, I'll upload to the forum. But.........

Quote
what else would have to be done?
.........the problem with boundary changes is still there, so we can try to fix it before publishing or doing it right now.
It's your choice  ;)  so, please, tell me what you want.

And, of course, if someone else has any idea to improove this object it will be welcome!!
[...] y el mayor bien es pequeño: que toda la vida es sueño, y los sueños, sueños son.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #13
OK - multiple points:

a) I think I found a non-deterministic bug in either "nwcdraw.barSegment" or our ConnectBarLines code: The upper segment must be drawn with nwcdraw.barSegment(barType,y+yPosTop,y+4), not with nwcdraw.barSegment(barType,y+4,y+yPosTop). In my somewhat extended experiments, the latter code at some point stopped drawing anything; and the documentation says "Y1 and Y2 determine the upper and lower end points for the bar segment" - it does not specify that happens if Y1 is below Y2. Still, it worked up to now ... so something might be fishy in nwcdraw ...

b) I have a horrendous piece of code that searches backwards to matching Boundary objects to get the current upper and lower heights (see below; attached is also my test score). I have no idea why this actually searches to the beginning of the whole score - I copied it from Mike's NWC's "BarCounter", which can do this. In my much simpler first attempt, :find only searched in the printed part of the staff, i.e., not far enough - I would be happy if someone could (somewhere else?) explain to me why my "find('prior', ...) stopped much sooner, and what the code does ...
... but it seems that my code does not find what it should. I'll try to find out what goes on there (but tomorrow morning, we will be on our way back from the Bretagne to Germany, so it might take two or three days ...).

c) What do we want?
1) should there still be a "Standard" functionality that works only on the immediately following bar?
2) should the object draw something in edit mode (right now, my modification is totally silent ... but one could draw e.g. "BrokenSingle" bars everywhere to indicated what would happen at the right end of each printed staff?)

and finally
d) is this the right place to discuss this sort of (very) experimental programming? - or should I continue this somewhere else on the forum or in private messages?

Edit: Lloyd & me will continue this offline somewhat ... when something working turns up, we'll be back ...

H.M.

Current experimental code of "ConnectBarLines" that tries to heed Boundary heights - but does not ...

Code: [Select · Download]
-- Version 0.1

--[[--------------------------------------------------------------------------

This plugin will connect barlines with the staff below. You must specify if the current staff is Upper, Middle or Lower staff in order to draw connections correctly.

--]]--------------------------------------------------------------------------


local userObjTypeName = ...
local nextBar = nwc.drawpos.new()
local prevBoundary = nwc.drawpos.new()
local drawpos = nwcdraw.user


local drawidx1 = nwc.drawpos
local objidx = nwc.ntnidx
local searchidx = objidx.new()
local c = nwcdraw


local object_spec = {
{ id='System', label='Staff Location', type='enum', default='Top Staff', list={'Top Staff', 'Middle Staff', 'Bottom Staff'}},
}

local function do_create(t)
    t.Class = 'StaffSig'
end

local function do_draw(t)
  local w = nwc.toolbox.drawStaffSigLabel('BarLines3')
  if not nwcdraw.isDrawing() then return w end
  -- if nwcdraw.getTarget() ~= 'print' then return end
  if drawpos:isHidden() then return end

  local yPosTop
  local yPosBottom

  local setTopIfNil = function(value)
    if not yPosTop then
      yPosTop = value
    end
  end

  local setBottomIfNil = function(value)
    if not yPosBottom then
      yPosBottom = value
    end
  end

  local drawSegment = function(x,y,bType)
    if t.System == 'Top Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(bType,y-4,y-yPosBottom)
    elseif t.System == 'Middle Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(bType,y+yPosTop,y+4)
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(bType,y-4,y-yPosBottom)
    elseif t.System == 'Bottom Staff' then
      nwcdraw.moveTo(x,y)
      nwcdraw.barSegment(bType,y+yPosTop,y+4)
    end
  end
--- I do not understand the following (copied from BarCounter)
  local me = c.user
  local me_autoins = me:isAutoInsert()

  drawidx1:reset()

    -- don't do anything when hidden
    if me:isHidden() then return end

    if me_autoins then
      drawidx1:find('first')
    else
      drawidx1:find('prior','bar')
    end

  if me_autoins and drawidx1:find('first','noteOrRest') then
    if drawidx1:isAutoInsert() and (drawidx1:objType() == 'RestMultiBar') then
      pendingBar = drawidx1:barCounter()
    end
  else
    drawidx1:reset()
  end

  -- start from the first note and count bars backwards
  objidx:reset()
  searchidx:find(drawidx1)
  while searchidx:find('prior') and (searchidx > objidx) do
--- end "I do not understand"
   
    if searchidx:objType() == 'Boundary' and searchidx:objProp('Style') == 'NewSize' then
      setTopIfNil(searchidx:objProp('Upper'))
      setBottomIfNil(searchidx:objProp('Lower'))
      nwc.debug("c2", yPosTop, yPosBottom)
    elseif searchidx:objType() == 'Boundary' and searchidx:objProp('Style') == 'Reset' then
      setTopIfNil(nwcdraw.getStaffProp('BoundaryTop'))
      setBottomIfNil(nwcdraw.getStaffProp('BoundaryBottom'))
      nwc.debug("c3", yPosTop, yPosBottom)
    end
  end

  setTopIfNil(nwcdraw.getStaffProp('BoundaryTop'))
  setBottomIfNil(nwcdraw.getStaffProp('BoundaryBottom'))
  nwc.debug("c5", yPosTop, yPosBottom)

  nextBar:reset()
  local found = nextBar:find('last', 'bar')
  if found then
    found = nextBar:find('next', 'bar')
  end
 
  if found then   
    local x,y = nextBar:xyAnchor()
    local barType = nextBar:objProp('Style')

    drawSegment(x, y, barType)
  end

  nextBar:reset()
  while nextBar:find('next', 'bar') do
    local x,y = nextBar:xyAnchor()
    drawSegment(x, y, 'BrokenDouble')
  end
end

return {
  spec  = object_spec,
  create  = do_create,
  width  = do_draw,
  draw  = do_draw,
}


Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #14
A few quick notes (dotted 64th):

First of all, BarCounter.nw is not my object; it was written by @NoteWorthy Online, who can hopefully answer questions about it.

One important thing to remember is that there are two kinds of pointers in the plugin system. There are drawpos pointers, and ntnidx pointers. Each of these can use a "find" function to locate items, but they have a different scope of operation: a drawpos pointer will only reference items in the currently rendered staff (i.e. in the current system), while a ntnidx pointer can see the entire staff, from first to last measure. There are a number of other methods that will work with both pointer types, while there are others that only work on drawpos pointers (most notably the drawing functions).

I hope this information is helpful in debugging your changes.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #15
Oh - sorry for the wrong attribution --> I corrected it (and should have seen from the "nw" instead of "ms" where the code came from ...).
Many thanks for the explanation of the two pointer types - that clears up quite a few clouds; with this knowledge, I'll try again to tinker with the bar line code ...

H.M.

Re: Connected bar only at end of score (and staffs) - is this possible?

Reply #16
There is now a plugin "ConnectBarlines.hmm" for connecting correctly and easily, also in the presence of boundary changes and collapsed staffs - see the "Object Plugins" subforum.

H.M.