Skip to content

Commit 83b9392

Browse files
chore: autopublish 2024-01-31T19:13:14Z
1 parent 1f51b4d commit 83b9392

File tree

2 files changed

+127
-112
lines changed

2 files changed

+127
-112
lines changed

dist/selection_refiner.lua

+126-111
Original file line numberDiff line numberDiff line change
@@ -4843,8 +4843,8 @@ function plugindef()
48434843
finaleplugin.Author = "Carl Vine"
48444844
finaleplugin.AuthorURL = "https://carlvine.com/lua/"
48454845
finaleplugin.Copyright = "CC0 https://creativecommons.org/publicdomain/zero/1.0/"
4846-
finaleplugin.Version = "0.53"
4847-
finaleplugin.Date = "2023/12/11"
4846+
finaleplugin.Version = "0.57"
4847+
finaleplugin.Date = "2024/01/25"
48484848
finaleplugin.CategoryTags = "Measures, Region, Selection"
48494849
finaleplugin.MinJWLuaVersion = 0.67
48504850
finaleplugin.Notes = [[
@@ -4854,7 +4854,7 @@ function plugindef()
48544854
slider controls to change the beat and EDU position in each measure,
48554855
continuously updating the score highlighting as the selection changes.
48564856
Note that when one slider overlaps the other in the same
4857-
measure, it will be pushed out of the way to create a "null"
4857+
measure, it will push the other out of the way creating a "null"
48584858
selection (start = end). This doesn't break anything
48594859
but the selection contains no notes.
48604860
== Beat Boundaries ==
@@ -4866,10 +4866,18 @@ function plugindef()
48664866
relative to the beat, as happens when entering beat numbers
48674867
on the inbuilt "Select Region" option.
48684868
== Key Commands ==
4869-
- START point: [w][s][a][d] (up-down-left-right) increments [e][r]
4870-
- END point: [f][v][c][b] (up-down-left-right) increments [g][h]
4871-
- [z] toggle the "follow selection" checkbox.
4872-
- [q] show these script notes
4869+
- (w)(s) @tStart Staff up/down
4870+
- (d)(f) @tStart Measure left/right
4871+
- (g)(h) @tStart increments -/+
4872+
- (j)(k) / (-)(+) @tStart -/+ one EDU
4873+
- • •
4874+
- (a)(z) @tEnd Staff up/down
4875+
- (x)(c) @tEnd Measure left/right
4876+
- (v)(b) @tEnd increments -/+
4877+
- (n)(m) / ([)(]) @tEnd -/+ one EDU
4878+
- • •
4879+
- (e) toggle the "follow selection" checkbox
4880+
- (q) show these script notes
48734881
]]
48744882
finaleplugin.HashURL = "https://raw.githubusercontent.com/finale-lua/lua-scripts/master/hash/selection_refiner.hash"
48754883
return "Selection Refiner...", "Selection Refiner", "Refine the selected music area with visual feedback"
@@ -4882,7 +4890,7 @@ slider controls to change the beat and EDU position in each measure,
48824890
continuously updating the score highlighting as the selection changes.
48834891
**
48844892
Note that when one slider overlaps the other in the same
4885-
measure, it will be pushed out of the way to create a "null"
4893+
measure, it will push the other out of the way creating a "null"
48864894
selection (start = end). This doesn't break anything
48874895
but the selection contains no notes.
48884896
**
@@ -4897,21 +4905,30 @@ relative to the beat, as happens when entering beat numbers
48974905
on the inbuilt "Select Region" option.
48984906
**
48994907
== Key Commands ==
4900-
*• (w)(s)(a)(d) @tSTART (up-down-left-right)
4901-
*• (e/r) @t@tSTART increments
4902-
*• (+/-) (t/y) @tSTART +/- one EDU
4903-
*• (f)(v)(c)(b) @tEND (up-down-left-right)
4904-
*• (g/h) @t@tEND increments
4905-
*• ( [/] ) (j/k) @tEND +/- one EDU
4906-
*• (z) toggle the "follow selection" checkbox
4908+
*• (w)(s) @tStart Staff up/down
4909+
*• (d)(f) @tStart Measure left/right
4910+
*• (g)(h) @tStart increments -/+
4911+
*• (j)(k) / (-)(+) @tStart -/+ one EDU
4912+
*• • •
4913+
*• (a)(z) @tEnd Staff up/down
4914+
*• (x)(c) @tEnd Measure left/right
4915+
*• (v)(b) @tEnd increments -/+
4916+
*• (m)(n) / ([)(]) @tEnd -/+ one EDU
4917+
*• • •
4918+
*• (e) toggle the "follow selection" checkbox
49074919
*• (q) show these script notes
49084920
]]
49094921
info_notes = info_notes:gsub("\n%s*", " "):gsub("*", "\n"):gsub("@t", "\t")
4910-
local config = { window_pos_x = false, window_pos_y = false, follow_measure = 1 }
4922+
.. "\n(v" .. finaleplugin.Version .. ")"
4923+
local config = {
4924+
follow_measure = 0,
4925+
window_pos_x = false,
4926+
window_pos_y = false
4927+
}
49114928
local mixin = require("library.mixin")
49124929
local library = require("library.general_library")
49134930
local configuration = require("library.configuration")
4914-
local script_name = "selection_refiner"
4931+
local script_name = library.calc_script_name()
49154932
local function dialog_set_position(dialog)
49164933
if config.window_pos_x and config.window_pos_y then
49174934
dialog:StorePosition()
@@ -4925,21 +4942,27 @@ local function dialog_save_position(dialog)
49254942
config.window_pos_y = dialog.StoredY
49264943
configuration.save_user_settings(script_name, config)
49274944
end
4928-
local function power_of_2(duration)
4929-
local test_rest = finale.NOTE_128TH / 2
4945+
local function power_of_two(duration)
4946+
local smallest = finale.NOTE_128TH / 2
49304947
local power = 1
4931-
while test_rest < duration and power < 10 do
4932-
test_rest = test_rest * 2
4948+
while smallest < duration and power < 10 do
4949+
smallest = smallest * 2
49334950
power = power + 1
49344951
end
49354952
return power
49364953
end
49374954
local function score_limits(rgn)
4955+
local staff = finale.FCStaff()
4956+
local staff_list = {}
49384957
local stack = mixin.FCMMusicRegion()
4939-
stack:SetRegion(rgn):SetFullMeasureStack()
4958+
stack:SetRegion(rgn):SetFullDocument()
4959+
for staff_number in eachstaff(stack) do
4960+
staff:Load(staff_number)
4961+
4962+
table.insert(staff_list, staff:CreateDisplayFullNameString())
4963+
end
49404964
local max_slot = stack.EndSlot
4941-
stack:SetFullDocument()
4942-
return stack.EndMeasure, max_slot
4965+
return stack.EndMeasure, max_slot, staff_list
49434966
end
49444967
local function compile_rest_strings(power)
49454968
power = math.min(math.max(power, 1), 10)
@@ -5000,7 +5023,7 @@ local function get_measure_details(region, is_start_sector)
50005023
md.mark = md.beatdur / 2
50015024
md.steps = 8
50025025
end
5003-
local power = power_of_2(md.mark * 2)
5026+
local power = power_of_two(md.mark * 2)
50045027
md.div_dur = md.beatdur / md.steps
50055028
md.divisions = md.beats * md.steps
50065029
if md.composite then
@@ -5017,12 +5040,6 @@ local function get_measure_details(region, is_start_sector)
50175040
md.rests = compile_rest_strings(power)
50185041
return md
50195042
end
5020-
local function get_staff_name(region, slot)
5021-
local staff_number = region:CalcStaffNumber(slot)
5022-
local staff = finale.FCStaff()
5023-
staff:Load(staff_number)
5024-
return staff:CreateDisplayFullNameString()
5025-
end
50265043
local function convert_edu_to_rest_string(index, md, backwards)
50275044
if backwards then index = md.divisions - index end
50285045
local beat = md.rests.beat
@@ -5054,17 +5071,18 @@ end
50545071
local function user_chooses(rgn)
50555072
local y, rest_wide, x_wide = 40, 130, 236
50565073
local x_offset = finenv.UI():IsOnMac() and 0 or 3
5074+
local name = plugindef():gsub("%.%.%.", "")
50575075
local function yd(diff)
50585076
y = diff and y + diff or y + 16
50595077
end
50605078
local function show_info()
5061-
finenv.UI():AlertInfo(info_notes, "About " .. plugindef())
5079+
finenv.UI():AlertInfo(info_notes, "About " .. name)
50625080
end
50635081

50645082
local measure, sliders, offset, save_off = {}, {}, {}, {}
5065-
local rest, buttons, index, staff, actions = {}, {}, {}, {}, {}
5083+
local rest, buttons, index, staff_sel, actions = {}, {}, {}, {}, {}
50665084
local follow
5067-
local max_measure, max_slot = score_limits(rgn)
5085+
local max_measure, max_slot, staff_list = score_limits(rgn)
50685086

50695087
local md = { get_measure_details(rgn, true), get_measure_details(rgn, false) }
50705088
local function pos_to_index(side)
@@ -5073,7 +5091,7 @@ local function user_chooses(rgn)
50735091
index[1] = pos_to_index(1)
50745092
index[2] = pos_to_index(2)
50755093

5076-
local dialog = mixin.FCXCustomLuaWindow():SetTitle(plugindef())
5094+
local dialog = mixin.FCXCustomLuaWindow():SetTitle(name)
50775095

50785096
local function set_measure_pos(side)
50795097
if side == 1 then rgn.StartMeasurePos = md[side].pos
@@ -5126,15 +5144,6 @@ local function user_chooses(rgn)
51265144
rgn:SetInDocument()
51275145
rgn:Redraw()
51285146
end
5129-
local function staff_button_visibility()
5130-
for side = 1, 2 do
5131-
buttons[side].up:SetEnable(md[side].slot > 1)
5132-
buttons[side].down:SetEnable(md[side].slot < max_slot)
5133-
staff[side]:SetText(get_staff_name(rgn, md[side].slot))
5134-
end
5135-
rgn:SetInDocument()
5136-
rgn:Redraw()
5137-
end
51385147
local function position_increment(side, add)
51395148
if (add > 0 and md[side].pos < md[side].dur)
51405149
or (add < 0 and md[side].pos > 0) then
@@ -5147,36 +5156,36 @@ local function user_chooses(rgn)
51475156
end
51485157

51495158
actions = {
5150-
up = function(a_side)
5151-
if md[a_side].slot > 1 then
5152-
md[a_side].slot = md[a_side].slot - 1
5153-
if a_side == 1 then
5154-
rgn.StartSlot = md[1].slot
5155-
else
5156-
rgn.EndSlot = md[2].slot
5157-
if md[1].slot > md[2].slot then
5158-
md[1].slot = md[2].slot
5159-
rgn.StartSlot = md[2].slot
5160-
end
5159+
staff = function(a_side)
5160+
local new_slot = staff_sel[a_side]:GetSelectedItem() + 1
5161+
if new_slot == md[a_side].slot then return end
5162+
if a_side == 1 then
5163+
rgn.StartSlot = new_slot
5164+
if new_slot > (staff_sel[2]:GetSelectedItem() + 1) then
5165+
staff_sel[2]:SetSelectedItem(new_slot - 1)
5166+
md[2].slot = new_slot
5167+
rgn.EndSlot = new_slot
5168+
end
5169+
else
5170+
rgn.EndSlot = new_slot
5171+
if new_slot < (staff_sel[1]:GetSelectedItem() + 1) then
5172+
staff_sel[1]:SetSelectedItem(new_slot - 1)
5173+
md[1].slot = new_slot
5174+
rgn.StartSlot = new_slot
51615175
end
5162-
staff_button_visibility()
51635176
end
5177+
staff_sel[a_side]:SetSelectedItem(new_slot - 1)
5178+
md[a_side].slot = new_slot
5179+
rgn:SetInDocument()
5180+
rgn:Redraw()
51645181
end,
51655182

5166-
down = function(a_side)
5167-
if md[a_side].slot < max_slot then
5168-
md[a_side].slot = md[a_side].slot + 1
5169-
if a_side == 1 then
5170-
rgn.StartSlot = md[1].slot
5171-
if md[2].slot < md[1].slot then
5172-
md[2].slot = md[1].slot
5173-
rgn.EndSlot = md[1].slot
5174-
end
5175-
else
5176-
rgn.EndSlot = md[2].slot
5177-
end
5178-
staff_button_visibility()
5183+
change_staff = function(a_side, diff)
5184+
local slot = staff_sel[a_side]:GetSelectedItem() + 1
5185+
if (slot > 1 and diff < 0) or (slot < max_slot and diff > 0) then
5186+
staff_sel[a_side]:SetSelectedItem(slot + diff - 1)
51795187
end
5188+
actions.staff(a_side)
51805189
end,
51815190

51825191
left = function(a_side)
@@ -5261,23 +5270,23 @@ local function user_chooses(rgn)
52615270
local s = offset[i]:GetText():lower()
52625271
if s:find("[^0-9]") then
52635272
if s:find("[?q]") then show_info()
5264-
elseif s:find("w") then actions.up(1)
5265-
elseif s:find("s") then actions.down(1)
5266-
elseif s:find("a") then actions.left(1)
5267-
elseif s:find("d") then actions.right(1)
5268-
elseif s:find("e") then actions.thumb(1, -1)
5269-
elseif s:find("r") then actions.thumb(1, 1)
5270-
elseif s:find("f") then actions.up(2)
5271-
elseif s:find("v") then actions.down(2)
5272-
elseif s:find("c") then actions.left(2)
5273-
elseif s:find("b") then actions.right(2)
5274-
elseif s:find("g") then actions.thumb(2, -1)
5275-
elseif s:find("h") then actions.thumb(2, 1)
5276-
elseif s:find("[-_t]") then position_increment(1, -1)
5277-
elseif s:find("[+=y]") then position_increment(1, 1)
5278-
elseif s:find("[%[j]") then position_increment(2, -1)
5279-
elseif s:find("[%]k]") then position_increment(2, 1)
5280-
elseif s:find("z") then
5273+
elseif s:find("w") then actions.change_staff(1, -1)
5274+
elseif s:find("s") then actions.change_staff(1, 1)
5275+
elseif s:find("d") then actions.left(1)
5276+
elseif s:find("f") then actions.right(1)
5277+
elseif s:find("g") then actions.thumb(1, -1)
5278+
elseif s:find("h") then actions.thumb(1, 1)
5279+
elseif s:find("a") then actions.change_staff(2, -1)
5280+
elseif s:find("z") then actions.change_staff(2, 1)
5281+
elseif s:find("x") then actions.left(2)
5282+
elseif s:find("c") then actions.right(2)
5283+
elseif s:find("b") then actions.thumb(2, 1)
5284+
elseif s:find("v") then actions.thumb(2, -1)
5285+
elseif s:find("[-_j]") then position_increment(1, -1)
5286+
elseif s:find("[+=k]") then position_increment(1, 1)
5287+
elseif s:find("[%[n]") then position_increment(2, -1)
5288+
elseif s:find("[%]m]") then position_increment(2, 1)
5289+
elseif s:find("e") then
52815290
follow:SetCheck((follow:GetCheck() + 1) % 2)
52825291
end
52835292
offset[i]:SetText(save_off[i])
@@ -5297,17 +5306,12 @@ local function user_chooses(rgn)
52975306
}
52985307
local default_font = finale.FCFontInfo()
52995308
default_font:LoadFontPrefs(finale.FONTPREF_MUSIC)
5300-
local button_x = (x_wide + rest_wide + 14) / 4
5301-
local bx12 = button_x + 12
5309+
local button_x = (x_wide + rest_wide + 14) / 5
53025310
local function make_rest_text(i, y_off)
53035311
rest[i] = dialog:CreateStatic(x_wide + 65, y_off + md[i].rests.vert)
53045312
:SetWidth(rest_wide):SetHeight(80):SetFont(default_font)
53055313
:SetText(convert_edu_to_rest_string(index[i], md[i], false))
53065314
end
5307-
local function make_staff_name(i)
5308-
staff[i] = dialog:CreateStatic(bx12 + 25, y):SetWidth(rest_wide)
5309-
:SetText(get_staff_name(rgn, md[i].slot))
5310-
end
53115315
local function make_slider_and_offset(i)
53125316
sliders[i] = dialog:CreateSlider(0, y):SetMinValue(0)
53135317
:SetWidth(x_wide):SetMaxValue(md[i].divisions)
@@ -5317,45 +5321,56 @@ local function user_chooses(rgn)
53175321
:AddHandleCommand(function() actions.offset(i) end):SetWidth(50)
53185322
end
53195323
local function make_buttons(i)
5324+
5325+
staff_sel[i] = dialog:CreatePopup(0, y)
5326+
:AddStrings(table.unpack(staff_list)):SetWidth(button_x * 2)
5327+
:SetSelectedItem(md[i].slot - 1)
5328+
:AddHandleCommand(function() actions.staff(i) end)
5329+
53205330
buttons[i] = {}
5321-
for k, v in pairs({
5322-
up = { bx12, y, "Staff ↑" }, down = { bx12, y + 20, "Staff ↓" },
5323-
left = { 0, y + 10, "← Measure" }, right = { bx12 * 2, y + 10, "Measure →" }
5324-
}) do
5325-
buttons[i][k] = dialog:CreateButton(v[1], v[2]):SetWidth(button_x)
5326-
:AddHandleCommand(function() actions[k](i) end):SetText(v[3])
5327-
end
5328-
measure[i] = dialog:CreateStatic(bx12 * 3, y + 10):SetWidth(60)
5331+
for k, v in pairs{
5332+
left = { button_x * 2 + 5, "← Measure" }, right = { button_x * 3 + 5, "Measure →" }
5333+
} do
5334+
buttons[i][k] = dialog:CreateButton(v[1], y):SetWidth(button_x - 5)
5335+
:AddHandleCommand(function() actions[k](i) end):SetText(v[2])
5336+
end
5337+
measure[i] = dialog:CreateStatic(button_x * 4 + 5, y):SetWidth(button_x - 5)
53295338
:SetText("m. " .. md[2].measure)
53305339
end
53315340

53325341
make_rest_text(1, 0)
5333-
make_rest_text(2, 83)
5334-
dialog:CreateStatic(0, y):SetText("START of Selection:"):SetWidth(x_wide)
5335-
make_staff_name(1)
5336-
dialog:CreateButton(x_wide + rest_wide + 30, y):SetText("?"):SetWidth(20)
5342+
make_rest_text(2, 78)
5343+
5344+
dialog:CreateStatic(0, y, "head_1"):SetText("START of Selection:"):SetWidth(x_wide)
5345+
dialog:CreateButton(x_wide + rest_wide + 30, y, "q"):SetText("?"):SetWidth(20)
53375346
:AddHandleCommand(function() show_info() end)
53385347
yd(14)
53395348
make_slider_and_offset(1)
5340-
yd(22)
5349+
yd(30)
53415350
make_buttons(1)
5342-
yd(42)
5343-
dialog:CreateHorizontalLine(0, y, button_x * 4)
5351+
yd(30)
5352+
dialog:CreateHorizontalLine(0, y, button_x * 5)
53445353
yd(5)
53455354

5346-
dialog:CreateStatic(0, y):SetText("END of Selection:"):SetWidth(x_wide)
5347-
make_staff_name(2)
5355+
dialog:CreateStatic(0, y, "head_2"):SetText("END of Selection:"):SetWidth(x_wide)
53485356
yd(14)
53495357
make_slider_and_offset(2)
5350-
yd(22)
5358+
yd(30)
53515359
make_buttons(2)
5352-
yd(42)
5360+
yd(30)
53535361
follow = dialog:CreateCheckbox(0, y, "follow_measure"):SetWidth(x_wide)
53545362
:SetText("Follow selection to off-screen measures"):SetCheck(config.follow_measure)
53555363
dialog:CreateOkButton()
53565364
dialog:CreateCancelButton()
53575365
dialog_set_position(dialog)
53585366
dialog:RegisterHandleOkButtonPressed(function() config.follow_measure = follow:GetCheck() end)
5367+
dialog:RegisterInitWindow(function(self)
5368+
local h = self:GetControl("head_1")
5369+
local bold = h:CreateFontInfo():SetBold(true)
5370+
h:SetFont(bold)
5371+
self:GetControl("head_2"):SetFont(bold)
5372+
self:GetControl("q"):SetFont(bold)
5373+
end)
53595374
dialog:RegisterCloseWindow(function(self) dialog_save_position(self) end)
53605375
return (dialog:ExecuteModal(nil) == finale.EXECMODAL_OK)
53615376
end

hash/selection_refiner.hash

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5da8ca2ca9af1b774a379f27eda767c5750439b77ee6a924e1ee46f505f7ce3574f02db2e7e6a772346f805e59ccdbbe26a0f7ac982699aa653e06af5873051f selection_refiner.lua
1+
4247d75a2852a6e3ad26adc47057c13ad68ef04bb8aeceb1e65e1ec9ab145c4314f31ba8c4312a3ef27297e9ce8ef42f725296ef9f7b27a2781f31b6629cab60 selection_refiner.lua

0 commit comments

Comments
 (0)