Skip to content

Commit 9c5b59b

Browse files
committed
Create expression_playback.lua
Not sure this is worthy of REPO inclusion. It's the sort of thing that you only need occasionally but then you really need it.
1 parent fd60e91 commit 9c5b59b

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

src/expression_playback.lua

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
function plugindef()
2+
finaleplugin.RequireSelection = false
3+
finaleplugin.Author = "Carl Vine"
4+
finaleplugin.AuthorURL = "http://carlvine.com/lua/"
5+
finaleplugin.Copyright = "https://creativecommons.org/licenses/by/4.0/"
6+
finaleplugin.Version = "0.07"
7+
finaleplugin.Date = "2024/07/27"
8+
finaleplugin.Notes = [[
9+
Change the assigned playback layer and position for all expressions
10+
in the current selection.
11+
Layers __1-4__ are the _standard_ playback layers.
12+
Layer numbers __0__, __5__ and __6__ are interpreted respectively
13+
as __Current__, __Chord__ and __Expression__ Layers for playback.
14+
15+
Hold down _Shift_ when starting the script to repeat the same action
16+
as last time without a confirmation dialog.
17+
]]
18+
return "Expression Playback...",
19+
"Expression Playback",
20+
"Change the assigned playback layer for all expressions in the current selection"
21+
end
22+
23+
local start_options = { -- "Begin Playback At:" (ordered)
24+
{ "Alignment Point",
25+
"Beginning of Measure",
26+
"Position in Measure"
27+
}, -- + corresponding index of EXPRESSION_PLAYBACK_STARTPOINTS:
28+
{ finale.EXPRPLAYSTART_ALIGNMENTPOINT,
29+
finale.EXPRPLAYSTART_BEGINNINGOFMEASURE,
30+
finale.EXPRPLAYSTART_POSINMEASURE
31+
}
32+
}
33+
local c = { -- user config values
34+
layer = 0,
35+
start_at = 1, -- {start_options} chosen index (1-based)
36+
window_pos_x = false,
37+
window_pos_y = false,
38+
}
39+
local hotkey = { -- customise hotkeys (lowercase only)
40+
start_at = "z",
41+
show_info = "q",
42+
}
43+
local configuration = require("library.configuration")
44+
local mixin = require("library.mixin")
45+
local utils = require("library.utils")
46+
local library = require("library.general_library")
47+
local script_name = library.calc_script_name()
48+
local name = plugindef():gsub("%.%.%.", "")
49+
local refocus_document = false -- set to true if utils.show_notes_dialog is used
50+
51+
local function dialog_set_position(dialog)
52+
if c.window_pos_x and c.window_pos_y then
53+
dialog:StorePosition()
54+
dialog:SetRestorePositionOnlyData(c.window_pos_x, c.window_pos_y)
55+
dialog:RestorePosition()
56+
end
57+
end
58+
59+
local function dialog_save_position(dialog)
60+
dialog:StorePosition()
61+
c.window_pos_x = dialog.StoredX
62+
c.window_pos_y = dialog.StoredY
63+
configuration.save_user_settings(script_name, c)
64+
end
65+
66+
local function user_dialog()
67+
local y = 0
68+
local y_off = finenv.UI():IsOnMac() and 3 or 0
69+
local x_off = 54 -- horiz offset for Layer Number and Radio Group
70+
local save = c.layer
71+
local dialog = mixin.FCXCustomLuaWindow():SetTitle(name)
72+
73+
local function flip_radio()
74+
local radio = dialog:GetControl("start_at")
75+
radio:SetSelectedItem((radio:GetSelectedItem() + 1) % 3)
76+
end
77+
local function show_info()
78+
utils.show_notes_dialog(dialog, "About " .. name, 300, 155)
79+
refocus_document = true
80+
end
81+
local function cstat(x, wide, str)
82+
dialog:CreateStatic(x, y):SetWidth(wide):SetText(str)
83+
end
84+
cstat(0, 190, "Assign Playback of All Expressions")
85+
y = y + 22
86+
cstat(0, x_off, "to Layer:")
87+
dialog:CreateEdit(x_off, y - y_off, "layer"):SetInteger(save):SetWidth(20)
88+
:AddHandleCommand(function(self)
89+
local s = self:GetText():lower()
90+
if s:find("[^0-6]") then
91+
if s:find(hotkey.start_at) then flip_radio()
92+
elseif s:find(hotkey.show_info) then show_info()
93+
end
94+
else
95+
save = tonumber(s:sub(-1)) or 0
96+
end
97+
self:SetInteger(save):SetKeyboardFocus()
98+
end)
99+
y = y + 22
100+
cstat(0, 160, "Begin Playback At:")
101+
dialog:CreateButton(165, y, "q"):SetText("?"):SetWidth(20)
102+
:AddHandleCommand(function() show_info() end)
103+
y = y + 16
104+
local labels = finale.FCStrings()
105+
labels:CopyFromStringTable(start_options[1])
106+
dialog:CreateRadioButtonGroup(x_off, y, 3, "start_at")
107+
:SetText(labels):SetWidth(130)
108+
:SetSelectedItem(c.start_at - 1)
109+
y = y + 14
110+
cstat(x_off / 2, 50, "[" .. hotkey.start_at .. "]")
111+
dialog:CreateOkButton()
112+
dialog:CreateCancelButton()
113+
dialog_set_position(dialog)
114+
dialog:RegisterInitWindow(function()
115+
local q = dialog:GetControl("q")
116+
q:SetFont(q:CreateFontInfo():SetBold(true)) end)
117+
dialog:RegisterHandleOkButtonPressed(function()
118+
c.layer = dialog:GetControl("layer"):GetInteger()
119+
c.start_at = dialog:GetControl("start_at"):GetSelectedItem() + 1
120+
end)
121+
dialog:RegisterCloseWindow(function(self) dialog_save_position(self) end)
122+
return (dialog:ExecuteModal() == finale.EXECMODAL_OK)
123+
end
124+
125+
local function playback_layer()
126+
if finenv.Region():IsEmpty() then
127+
finenv.UI():AlertError(
128+
"Please select some music\nbefore running this script",
129+
name .. " Error")
130+
return
131+
end
132+
configuration.get_user_settings(script_name, c, true)
133+
local qim = finenv.QueryInvokedModifierKeys
134+
local mod_key = qim and (qim(finale.CMDMODKEY_ALT) or qim(finale.CMDMODKEY_SHIFT))
135+
136+
if mod_key or user_dialog() then
137+
local start_option = start_options[2][c.start_at] -- user choice -> actual index
138+
local expressions = finale.FCExpressions()
139+
expressions:LoadAllForRegion(finenv.Region())
140+
for exp in each(expressions) do
141+
if exp.StaffGroupID == 0 then -- exclude "Staff List" expressions
142+
exp.PlaybackLayerAssignment = c.layer
143+
exp.PlaybackStart = start_option
144+
exp:Save()
145+
end
146+
end
147+
end
148+
if refocus_document then finenv.UI():ActivateDocumentWindow() end
149+
end
150+
151+
playback_layer()

0 commit comments

Comments
 (0)