Skip to content

Commit 6ed481b

Browse files
authored
Merge pull request #756 from cv-on-hub/cv-exp-playback
Create expression_playback.lua
2 parents 6b123af + ee890e4 commit 6ed481b

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

src/expression_playback.lua

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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.08"
7+
finaleplugin.Date = "2024/07/28"
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 special_layer = {
34+
[0] = "(\"Current\" Layer)",
35+
[5] = "(Chord Layer)",
36+
[6] = "(Expression Layer)",
37+
}
38+
local c = { -- user config values
39+
layer = 0,
40+
start_at = 0, -- {start_options} chosen index (0-based)
41+
window_pos_x = false,
42+
window_pos_y = false,
43+
}
44+
local hotkey = { -- customise hotkeys (lowercase only)
45+
start_at = "z",
46+
show_info = "q",
47+
}
48+
local configuration = require("library.configuration")
49+
local mixin = require("library.mixin")
50+
local utils = require("library.utils")
51+
local library = require("library.general_library")
52+
local script_name = library.calc_script_name()
53+
local name = plugindef():gsub("%.%.%.", "")
54+
local refocus_document = false -- set to true if utils.show_notes_dialog is used
55+
56+
local function dialog_set_position(dialog)
57+
if c.window_pos_x and c.window_pos_y then
58+
dialog:StorePosition()
59+
dialog:SetRestorePositionOnlyData(c.window_pos_x, c.window_pos_y)
60+
dialog:RestorePosition()
61+
end
62+
end
63+
64+
local function dialog_save_position(dialog)
65+
dialog:StorePosition()
66+
c.window_pos_x = dialog.StoredX
67+
c.window_pos_y = dialog.StoredY
68+
configuration.save_user_settings(script_name, c)
69+
end
70+
71+
local function user_dialog()
72+
local y = 0
73+
local y_off = finenv.UI():IsOnMac() and 3 or 0
74+
local x_off = 54 -- horiz offset for Layer Number and Radio Group
75+
local save = c.layer
76+
local dialog = mixin.FCXCustomLuaWindow():SetTitle(name)
77+
78+
local function flip_radio()
79+
local radio = dialog:GetControl("start_at")
80+
radio:SetSelectedItem((radio:GetSelectedItem() + 1) % 3)
81+
end
82+
local function show_info()
83+
utils.show_notes_dialog(dialog, "About " .. name, 300, 155)
84+
refocus_document = true
85+
end
86+
local function cstat(x, wide, str, id)
87+
dialog:CreateStatic(x, y, id):SetWidth(wide):SetText(str)
88+
end
89+
cstat(0, 190, "Assign Playback of All Expressions")
90+
y = y + 22
91+
cstat(0, x_off, "to Layer:")
92+
dialog:CreateEdit(x_off, y - y_off, "layer"):SetInteger(save):SetWidth(20)
93+
:AddHandleCommand(function(self)
94+
local s = self:GetText():lower()
95+
if s:find("[^0-6]") then
96+
if s:find(hotkey.start_at) then flip_radio()
97+
elseif s:find(hotkey.show_info) then show_info()
98+
end
99+
else
100+
save = tonumber(s:sub(-1)) or 0
101+
dialog:GetControl("data"):SetText(special_layer[save] or "")
102+
end
103+
self:SetInteger(save):SetKeyboardFocus()
104+
end)
105+
cstat(x_off + 28, 110, (special_layer[save] or ""), "data")
106+
y = y + 22
107+
cstat(0, 160, "Begin Playback At:")
108+
dialog:CreateButton(165, y, "q"):SetText("?"):SetWidth(20)
109+
:AddHandleCommand(function() show_info() end)
110+
y = y + 16
111+
local labels = finale.FCStrings()
112+
labels:CopyFromStringTable(start_options[1])
113+
dialog:CreateRadioButtonGroup(x_off, y, 3, "start_at")
114+
:SetText(labels):SetWidth(130)
115+
:SetSelectedItem(c.start_at)
116+
y = y + 14
117+
cstat(x_off / 2, 50, "[" .. hotkey.start_at .. "]")
118+
dialog:CreateOkButton()
119+
dialog:CreateCancelButton()
120+
dialog_set_position(dialog)
121+
dialog:RegisterInitWindow(function()
122+
local q = dialog:GetControl("q")
123+
q:SetFont(q:CreateFontInfo():SetBold(true)) end)
124+
dialog:RegisterHandleOkButtonPressed(function()
125+
c.layer = dialog:GetControl("layer"):GetInteger()
126+
c.start_at = dialog:GetControl("start_at"):GetSelectedItem() -- 0-based
127+
end)
128+
dialog:RegisterCloseWindow(function(self) dialog_save_position(self) end)
129+
return (dialog:ExecuteModal() == finale.EXECMODAL_OK)
130+
end
131+
132+
local function playback_layer()
133+
if finenv.Region():IsEmpty() then
134+
finenv.UI():AlertError(
135+
"Please select some music\nbefore running this script",
136+
name .. " Error")
137+
return
138+
end
139+
configuration.get_user_settings(script_name, c, true)
140+
local qim = finenv.QueryInvokedModifierKeys
141+
local mod_key = qim and (qim(finale.CMDMODKEY_ALT) or qim(finale.CMDMODKEY_SHIFT))
142+
143+
if mod_key or user_dialog() then
144+
local start_option = start_options[2][c.start_at + 1] -- user choice -> actual index
145+
local expressions = finale.FCExpressions()
146+
expressions:LoadAllForRegion(finenv.Region())
147+
for exp in each(expressions) do
148+
if exp.StaffGroupID == 0 then -- exclude "Staff List" expressions
149+
exp.PlaybackLayerAssignment = c.layer
150+
exp.PlaybackStart = start_option
151+
exp:Save()
152+
end
153+
end
154+
end
155+
if refocus_document then finenv.UI():ActivateDocumentWindow() end
156+
end
157+
158+
playback_layer()

0 commit comments

Comments
 (0)