Skip to content

Commit 9ec35e5

Browse files
committed
Update notes_cross_staff.lua
Improved clarity of Configuration window.
1 parent c3dbdb0 commit 9ec35e5

File tree

1 file changed

+65
-52
lines changed

1 file changed

+65
-52
lines changed

src/notes_cross_staff.lua

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ function plugindef()
44
finaleplugin.Author = "Carl Vine"
55
finaleplugin.AuthorURL = "https://carlvine.com/lua/"
66
finaleplugin.Copyright = "https://creativecommons.org/licenses/by/4.0/"
7-
finaleplugin.Version = "0.95i"
8-
finaleplugin.Date = "2024/05/22"
7+
finaleplugin.Version = "0.95k"
8+
finaleplugin.Date = "2024/07/23"
99
finaleplugin.MinJWLuaVersion = 0.74
1010
finaleplugin.ScriptGroupDescription = "Selected notes are cross-staffed to the next staff above or below"
1111
finaleplugin.Notes = [[
@@ -16,10 +16,10 @@ function plugindef()
1616
stem reversal, horizontal note shift (to counteract stem reversal),
1717
note pattern matching and beam height adjustment.
1818
19-
Hold [Shift] when starting the script to quickly cross staves
19+
Hold [_Shift_] when starting the script to quickly cross staves
2020
without a confirmation dialog, with the settings last used.
2121
Select __Modeless Dialog__ if you want the dialog window to persist
22-
on-screen for repeated use until you click _Cancel_ [Escape].
22+
on-screen for repeated use until you click __Close__ [_Escape_].
2323
2424
__Reverse Stems For Mid-Staff Beams__
2525
To centre beams _between_ the staves, the stems of __Crossed__
@@ -64,7 +64,7 @@ local units = { -- map keystrokes onto Measurement Unit ENUMs
6464
c = finale.MEASUREMENTUNIT_CENTIMETERS, o = finale.MEASUREMENTUNIT_POINTS,
6565
a = finale.MEASUREMENTUNIT_PICAS, s = finale.MEASUREMENTUNIT_SPACES,
6666
}
67-
local hotkey = { -- customise Key Commands (lower case only)
67+
local hotkey = { -- customise Key Commands (lowercase only)
6868
rest_fill = "d",
6969
not_unbeamed = "f",
7070
reversing = "g",
@@ -75,26 +75,26 @@ local hotkey = { -- customise Key Commands (lower case only)
7575
modeless = "m",
7676
script_info = "q",
7777
-- optionally re-map MEASUREMENTUNIT hotkeys:
78-
e = "e",
79-
i = "i",
80-
c = "c",
81-
o = "o",
82-
a = "a",
83-
s = "s",
78+
e = "e",
79+
i = "i",
80+
c = "c",
81+
o = "o",
82+
a = "a",
83+
s = "s",
8484
}
8585
local config = {
8686
rest_fill = true, -- fill destination with invisible rest
8787
not_unbeamed = true, -- true to prevent unbeamed notes
8888
reversing = true, -- true to allow reversing cross-note stems
8989
whole_measure = false, -- horizontal shift across whole measure
90-
measurement_unit = finale.MEASUREMENTUNIT_DEFAULT,
91-
layer_num = 0,
92-
direction = "Up", -- (or "Down")
90+
direction = "Up", -- (or "Down")
9391
modeless = false,
92+
layer_num = 0,
9493
count_notes = 1, -- "Cross" x notes
9594
count_out_of = 1, -- "out of" y notes
9695
window_pos_x = false,
9796
window_pos_y = false,
97+
measurement_unit = finale.MEASUREMENTUNIT_DEFAULT,
9898
}
9999

100100
local offsets = { -- (ordered) name; default value; text description; h_offset
@@ -144,7 +144,8 @@ local function get_staff_name(staff_num)
144144
return str
145145
end
146146

147-
local function next_staff_or_error(rgn, dialog)
147+
local function next_staff_or_error(dialog)
148+
local rgn = finenv.Region()
148149
local msg = ""
149150
local stack = mixin.FCMMusicRegion()
150151
stack:SetRegion(rgn):SetFullMeasureStack()
@@ -168,11 +169,8 @@ local function next_staff_or_error(rgn, dialog)
168169
end
169170
end
170171
if msg ~= "" then -- **ERROR**
171-
if dialog then
172-
dialog:CreateChildUI():AlertError(msg, name .. ": Error")
173-
else
174-
finenv.UI():AlertError(msg, name .. ": Error")
175-
end
172+
local ui = dialog and dialog:CreateChildUI() or finenv.UI()
173+
ui:AlertError(msg, name .. ": Error")
176174
return -1 -- flag error
177175
end
178176
return stack:CalcStaffNumber(next_slot)
@@ -197,8 +195,8 @@ end
197195

198196
local function clean_entry(entry) -- erase pre-exisiting conditions
199197
if entry:IsNote() then
200-
for i = 1, entry.Count do
201-
finale.FCCrossStaffMod():EraseAt(entry:GetItemAt(i - 1))
198+
for note in each(entry) do
199+
finale.FCCrossStaffMod():EraseAt(note)
202200
end
203201
local mods = finale.FCCrossStaffMods(entry)
204202
mods:LoadAll()
@@ -224,12 +222,12 @@ local function destination_rests(rgn, dest_staff_num)
224222
note_cell:Load()
225223
if note_cell.Count == 0 then -- destination empty so proceed
226224
local m = finale.FCMeasure()
227-
local m_duration = m:Load(measure_num) and m:GetDuration() or finale.WHOLE_NOTE
225+
local duration = m:Load(measure_num) and m:GetDuration() or finale.WHOLE_NOTE
228226
local new_rest = note_cell:AppendEntriesInLayer(layer_num, 1)
229227
if new_rest then
230-
new_rest:MakeRest():SetDuration(m_duration):SetLegality(true):SetVisible(false)
228+
new_rest:MakeRest():SetDuration(duration):SetLegality(true):SetVisible(false)
231229
note_cell:Save()
232-
end
230+
end
233231
end
234232
end
235233
end
@@ -304,7 +302,7 @@ local function cross_staff(dialog)
304302
local rgn = mixin.FCMMusicRegion()
305303
rgn:SetRegion(finenv.Region())
306304

307-
local next_staff = next_staff_or_error(rgn, dialog)
305+
local next_staff = next_staff_or_error(dialog)
308306
if next_staff < 0 then return false end -- error finding "next staff"
309307
-- ready to cross staves
310308
finenv.StartNewUndoBlock(string.format("Cross-Staff %s -> %s m.%d",
@@ -363,7 +361,6 @@ local function cross_staff(dialog)
363361
end
364362
finale.FCNoteEntry.MarkEntryMetricsForUpdate()
365363
end
366-
367364
-- pass 4 (measure) stem reversal & crossing
368365
bsen = nil
369366
for entry in eachentrysaved(whole_measure, config.layer_num) do
@@ -382,8 +379,8 @@ local function cross_staff(dialog)
382379
end
383380
end
384381
end
385-
bsen = nil
386382
-- pass 5 (measure) shift beam if "mixed" crossed-and-uncrossed
383+
bsen = nil
387384
for entry in eachentrysaved(whole_measure, config.layer_num) do
388385
if entry:IsNote() then
389386
local enum = entry.EntryNumber
@@ -447,7 +444,7 @@ end
447444

448445
local function run_the_dialog()
449446
local max = layer.max_layers()
450-
local x = { 140, 210, 245}
447+
local x = { 140, 210, 245 }
451448
local y = 0
452449
local answer, save_value = {}, {} -- "Edit" controls / saved "text" values
453450
local dialog = mixin.FCXCustomLuaWindow():SetTitle(name)
@@ -458,19 +455,31 @@ local function run_the_dialog()
458455
refocus_document = true
459456
end
460457
local function dy(diff)
461-
y = diff and (y + diff) or (y + 25)
458+
y = y + (diff or 25)
462459
end
463460
local function cstat(cx, cy, ctext, cwide)
464-
local stat = dialog:CreateStatic(cx, cy):SetText(ctext)
465-
if cwide then stat:SetWidth(cwide) end
466-
return stat
461+
local s = dialog:CreateStatic(cx, cy):SetText(ctext)
462+
if cwide then s:SetWidth(cwide) end
463+
return s
464+
end
465+
local function offset_enable_status()
466+
local up = answer.direction:GetSelectedItem() -- 0 = "Up", 1 = "Down"
467+
local status = (answer.reversing:GetCheck() == 1) -- "reversing" = true
468+
for i = 0, 1 do -- check "Up" then "Down" values
469+
local enable = status and (i == up)
470+
-- enable/disable matching "Offset" labels, "off1"/"off3"
471+
answer["off" .. i * 2 + 1]:SetEnable(enable)
472+
for j = 1, 2 do
473+
answer[offsets[i * 2 + j][1]]:SetEnable(enable)
474+
end
475+
end
467476
end
468477
local function set_offset_disable()
469-
local enable = answer.reversing:GetCheck() == 1
470-
for i = 1, 4 do answer[offsets[i][1]]:SetEnable(enable) end
471-
for _, v in ipairs{"whole_measure", "h1", "h2", "h3", "off1", "off3"} do
472-
answer[v]:SetEnable(enable)
478+
local status = (answer.reversing:GetCheck() == 1) -- "reversing" = true
479+
for _, v in ipairs{"whole_measure", "h0", "h1", "h2", "zero", "default"} do
480+
answer[v]:SetEnable(status)
473481
end
482+
offset_enable_status()
474483
answer[pattern[1][1]]:SetKeyboardFocus()
475484
end
476485
local function update_saved()
@@ -509,11 +518,14 @@ local function run_the_dialog()
509518
elseif s:find(hotkey.direction) then
510519
local n = answer.direction:GetSelectedItem()
511520
answer.direction:SetSelectedItem((n + 1) % 2)
521+
offset_enable_status()
512522
else -- remaining simple checkboxes
513523
for k, v in pairs(hotkey) do
514524
if s:find(v) then
515525
answer[k]:SetCheck((answer[k]:GetCheck() + 1) % 2)
516-
if k == "reversing" then set_offset_disable() end
526+
if k == "reversing" then set_offset_disable()
527+
else answer[k]:SetCheck((answer[k]:GetCheck() + 1) % 2)
528+
end
517529
break
518530
end
519531
end
@@ -538,8 +550,9 @@ local function run_the_dialog()
538550
answer.direction = dialog:CreatePopup(0, y - 1):SetWidth(90)
539551
:AddStrings("Cross Up", "Cross Down") -- item# == 0 or 1
540552
:SetSelectedItem(config.direction == "Up" and 0 or 1)
553+
:AddHandleCommand(function() offset_enable_status() end)
541554
answer.modeless = dialog:CreateCheckbox(131, y):SetWidth(120)
542-
:SetCheck(config.modeless and 1 or 0):SetText("\"Modeless\" Dialog")
555+
:SetCheck(config.modeless and 1 or 0):SetText("Modeless Dialog")
543556
answer.q = dialog:CreateButton(x[2] + 44, y):SetText("?"):SetWidth(20)
544557
:AddHandleCommand(function() show_info() end)
545558
dy()
@@ -569,16 +582,17 @@ local function run_the_dialog()
569582
dy(8)
570583
dialog:CreateHorizontalLine(0, y - 5, x[2] + 64)
571584
dialog:CreateHorizontalLine(0, y - 4, x[2] + 64)
572-
answer.h1 = cstat(x[1] + 4, y + 2, "HORIZONTAL OFFSETS", 130)
585+
answer.h0 = cstat(x[1] + 4, y + 2, "HORIZONTAL OFFSETS", 130)
573586
dy(12)
574587
cstat(0, y - 7, "Units:", 37)
575588
answer.popup = dialog:CreateMeasurementUnitPopup(37, y - 8):SetWidth(90)
576589
:AddHandleCommand(function() update_saved() end)
577-
answer.h2 = cstat(x[1], y + 2, "Crossed", 70)
578-
answer.h3 = cstat(x[2] - 4, y + 2, "Not Crossed", 70)
590+
answer.h1 = cstat(x[1], y + 2, "Crossed", 70)
591+
answer.h2 = cstat(x[2] - 4, y + 2, "Not Crossed", 70)
579592

580593
for i, v in ipairs(offsets) do -- OFFSET MEASUREMENTS
581594
if (i % 2 == 1) then dy(20) end
595+
if i == 5 then dy(25) end -- "beam vertical" sits BELOW the "Horiz" buttons
582596
answer[v[1]] = dialog:CreateMeasurementEdit((i % 2 == 1) and x[1] or x[2], y - y_off)
583597
:SetMeasurementInteger(config[v[1]]):SetWidth(63)
584598
:AddHandleCommand(function() key_check(v[1]) end)
@@ -588,21 +602,20 @@ local function run_the_dialog()
588602
end
589603
-- set "saved" edit values
590604
update_saved()
591-
dy(20)
592-
dialog:CreateButton(x[1], y):SetWidth(105)
593-
:SetText("Zero Horiz. (" .. hotkey.set_zero .. ")")
594-
:AddHandleCommand(function() set_default_values(0) end)
595-
dialog:CreateButton(20, y):SetWidth(105)
605+
dy(-23) -- move back ABOVE the "beam vertical" box
606+
answer.default = dialog:CreateButton(20, y):SetWidth(105)
596607
:SetText("Default Horiz. (" .. hotkey.set_default .. ")")
597608
:AddHandleCommand(function() set_default_values() end)
598-
599-
dialog:CreateOkButton():SetText(config.modeless and "Apply" or "OK")
600-
dialog:CreateCancelButton()
609+
answer.zero = dialog:CreateButton(x[1], y):SetWidth(105)
610+
:SetText("Zero Horiz. (" .. hotkey.set_zero .. ")")
611+
:AddHandleCommand(function() set_default_values(0) end)
612+
--
613+
dialog:CreateOkButton() :SetText(config.modeless and "Apply" or "OK")
614+
dialog:CreateCancelButton():SetText(config.modeless and "Close" or "Cancel")
601615
dialog_set_position(dialog)
602616
local change_mode, user_error = false, false
603-
dialog:RegisterInitWindow(function(self)
617+
dialog:RegisterInitWindow(function()
604618
set_offset_disable()
605-
self:SetOkButtonCanClose(not config.modeless)
606619
answer.q:SetFont(answer.q:CreateFontInfo():SetBold(true))
607620
end)
608621
dialog:RegisterHandleOkButtonPressed(function(self)

0 commit comments

Comments
 (0)