Skip to content

Commit 2378ed4

Browse files
committed
Update transpose_diatonic.lua
Sundry minor code improvements
1 parent fd60e91 commit 2378ed4

File tree

1 file changed

+52
-50
lines changed

1 file changed

+52
-50
lines changed

src/transpose_diatonic.lua

Lines changed: 52 additions & 50 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 = "CC0 https://creativecommons.org/publicdomain/zero/1.0/"
7-
finaleplugin.Version = "0.16"
8-
finaleplugin.Date = "2024/05/03"
7+
finaleplugin.Version = "0.18"
8+
finaleplugin.Date = "2024/07/29"
99
finaleplugin.MinJWLuaVersion = 0.72
1010
finaleplugin.CategoryTags = "Pitch, Transposition"
1111
finaleplugin.ScriptGroupName = "Transpose Diatonic"
@@ -16,15 +16,13 @@ function plugindef()
1616
To repeat the last action without a confirmation dialog
1717
hold down [Shift] when starting the script.
1818
19-
Select __Modeless__ if you prefer the dialog window to
20-
"float" above your score and you can change the score selection
21-
while the script remains active. In this mode click __Apply__
22-
[Return] to transpose and __Cancel__ [Escape] to close the window.
19+
Select __Modeless Dialog__ if you want the dialog window to persist
20+
on-screen for repeated use until you click __Close__ [_Escape_].
2321
Cancelling __Modeless__ will apply the _next_
2422
time you use the script.
2523
2624
> These key commands are available
27-
> if a "numeric" field is highlighted:
25+
> if a _numeric_ field is highlighted:
2826
2927
> - __1-8__: interval (unison, 2nd, 3rd, .. 8ve)
3028
> - __0-8__: extra octave
@@ -33,7 +31,7 @@ function plugindef()
3331
> - __q__: show this script information
3432
> - __z__: toggle _Up/Down_
3533
> - __x__: toggle _Preserve Existing Notes_
36-
> - __c__: toggle _Modeless_
34+
> - __m__: toggle _Modeless_
3735
]]
3836
return "Transpose Diatonic...", "Transpose Diatonic",
3937
"Transpose notes and chords up or down by the chosen diatonic interval"
@@ -49,10 +47,7 @@ local refocus_document = false
4947
local selection
5048
local interval_names = { "unis.", "2nd", "3rd", "4th", "5th", "6th", "7th", "8ve"}
5149
local saved_bounds = {}
52-
local bounds = { -- selection boundaries
53-
"StartStaff", "StartMeasure", "StartMeasurePos",
54-
"EndStaff", "EndMeasure", "EndMeasurePos",
55-
}
50+
5651
local config = { -- over-written by saved user data
5752
interval = 1, -- 1 = unison; 2 = second etc.
5853
octave = 0,
@@ -71,13 +66,13 @@ local numerics = { -- edit boxes: key / text
7166
}
7267
local checks = { -- checkboxes: key / text
7368
{ "do_preserve", "Preserve Existing Notes" },
74-
{ "modeless", "\"Modeless\" Dialog" }
69+
{ "modeless", "Modeless Dialog" }
7570
}
7671
local hotkey = { -- customise hotkeys
7772
show_info = "q",
7873
direction = "z",
7974
do_preserve = "x",
80-
modeless = "c",
75+
modeless = "m",
8176
}
8277

8378
local function dialog_set_position(dialog)
@@ -107,10 +102,12 @@ end
107102

108103
local function update_selection()
109104
local rgn = finenv.Region()
110-
if rgn:IsEmpty() then
111-
saved_bounds = {0, 0, 0, 0, 0, 0}
112-
selection = "no staff, no selection" -- default
113-
else
105+
selection = "no staff, no selection" -- empty default
106+
if not rgn:IsEmpty() then
107+
local bounds = { -- selection boundaries
108+
"StartStaff", "StartMeasure", "StartMeasurePos",
109+
"EndStaff", "EndMeasure", "EndMeasurePos",
110+
}
114111
for _, prop in ipairs(bounds) do
115112
saved_bounds[prop] = rgn[prop]
116113
end
@@ -125,14 +122,26 @@ local function update_selection()
125122
end
126123
end
127124

128-
local function transpose_diatonic()
125+
local function nil_region_error(dialog)
126+
if finenv.Region():IsEmpty() then
127+
local ui = dialog and dialog:CreateChildUI() or finenv.UI()
128+
ui:AlertError(
129+
"Please select some music\nbefore running this script.",
130+
finaleplugin.ScriptGroupName
131+
)
132+
return true
133+
end
134+
return false
135+
end
136+
137+
local function transpose_diatonic(dialog)
138+
if nil_region_error(dialog) then return end -- empty -> do nothing
129139
local direction = (config.direction * -2) + 1
130140
local shift = ((config.octave * 7) + config.interval - 1) * direction
131141
if shift ~= 0 then
132142
finenv.StartNewUndoBlock(
133-
string.format("Transp. Diat. %s %s %s oct%d",
134-
selection, (config.direction == 1 and "Dn" or "Up"),
135-
interval_names[config.interval], config.octave),
143+
string.format("Transp. Diat. %s %s",
144+
(config.direction == 0 and "Up" or "Dn"), selection),
136145
false
137146
)
138147
for entry in eachentrysaved(finenv.Region(), config.layer) do
@@ -153,10 +162,10 @@ local function run_the_dialog()
153162
local dialog = mixin.FCXCustomLuaWindow():SetTitle("Transpose")
154163
-- local functions
155164
local function show_info()
156-
utils.show_notes_dialog(dialog, "About " .. finaleplugin.ScriptGroupName, 400, 345)
165+
utils.show_notes_dialog(dialog, "About " .. finaleplugin.ScriptGroupName, 400, 320)
157166
refocus_document = true
158167
end
159-
local function dy(diff) y = diff and (y + diff) or (y + y_inc) end
168+
local function dy(diff) y = y + (diff or y_inc) end
160169
local function cs(cx, cy, ctext, cwide)
161170
local stat = dialog:CreateStatic(cx, cy):SetText(ctext)
162171
local _ = cwide and stat:SetWidth(cwide) or stat:DoAutoResizeWidth()
@@ -166,27 +175,27 @@ local function run_the_dialog()
166175
answer[id]:SetCheck((answer[id]:GetCheck() + 1) % 2)
167176
end
168177
local function key_command(id) -- key command replacements
169-
local ctl = answer[id]
170-
local val = ctl:GetText():lower()
171-
if val:find("[^0-8]")
172-
or (id == "layer" and val:find("[^0-" .. max .. "]"))
173-
or (id == "interval" and val:find("0"))
178+
local s = answer[id]:GetText():lower()
179+
if s:find("[^0-8]")
180+
or (id == "layer" and s:find("[^0-" .. max .. "]"))
181+
or (id == "interval" and s:find("0"))
174182
then
175-
if val:find(hotkey.direction) then -- flip direction
183+
if s:find(hotkey.direction) then -- flip direction
176184
local n = answer.direction:GetSelectedItem()
177185
answer.direction:SetSelectedItem((n + 1) % 2)
178-
elseif val:find(hotkey.modeless) then toggle_check("modeless")
179-
elseif val:find(hotkey.do_preserve) then toggle_check("do_preserve")
180-
elseif val:find(hotkey.show_info) then show_info()
186+
elseif s:find(hotkey.modeless) then toggle_check("modeless")
187+
elseif s:find(hotkey.do_preserve) then toggle_check("do_preserve")
188+
elseif s:find(hotkey.show_info) then show_info()
181189
end
182-
elseif val ~= "" then
183-
save[id] = val:sub(-1)
190+
else
191+
save[id] = s:sub(-1)
192+
if save[id] == "" then save[id] = "0" end
184193
if id == "interval" then
185-
local n = tonumber(save[id]) or 1
186-
answer.msg:SetText(interval_names[n])
194+
if save[id] == "0" then save[id] = "1" end
195+
answer.msg:SetText(interval_names[tonumber(save[id])])
187196
end
188197
end
189-
ctl:SetText(save[id]):SetKeyboardFocus()
198+
answer[id]:SetText(save[id]):SetKeyboardFocus()
190199
end
191200
local function on_timer() -- look for changes in selected region
192201
for k, v in pairs(saved_bounds) do
@@ -220,13 +229,11 @@ local function run_the_dialog()
220229
answer.q = dialog:CreateButton(x_step + 43, y - y_inc - 1):SetText("?"):SetWidth(20)
221230
:AddHandleCommand(function() show_info() end)
222231
answer.info = cs(0, y, selection, x_step + 40)
223-
224-
dialog:CreateOkButton():SetText(config.modeless and "Apply" or "OK")
225-
dialog:CreateCancelButton()
232+
dialog:CreateOkButton() :SetText(config.modeless and "Apply" or "OK")
233+
dialog:CreateCancelButton():SetText(config.modeless and "Close" or "Cancel")
226234
dialog_set_position(dialog)
227235
if config.modeless then dialog:RegisterHandleTimer(on_timer) end
228236
dialog:RegisterInitWindow(function(self)
229-
dialog:SetOkButtonCanClose(not config.modeless)
230237
if config.modeless then self:SetTimer(config.timer_id, 125) end
231238
local bold = answer.a:CreateFontInfo():SetBold(true)
232239
for _, v in ipairs{"a", "q", "msg"} do
@@ -241,7 +248,7 @@ local function run_the_dialog()
241248
end
242249
config.direction = answer.direction:GetSelectedItem()
243250
config.do_preserve = (answer.do_preserve:GetCheck() == 1)
244-
transpose_diatonic()
251+
transpose_diatonic(dialog)
245252
end)
246253
dialog:RegisterCloseWindow(function(self)
247254
if config.modeless then self:StopTimer(config.timer_id) end
@@ -261,13 +268,8 @@ end
261268

262269
function do_diatonic()
263270
configuration.get_user_settings(script_name, config, true)
264-
if not config.modeless and finenv.Region():IsEmpty() then
265-
finenv.UI():AlertError(
266-
"Please select some music\nbefore running this script.",
267-
finaleplugin.ScriptGroupName
268-
)
269-
return
270-
end
271+
if not config.modeless and nil_region_error() then return end
272+
271273
local qim = finenv.QueryInvokedModifierKeys
272274
local mod_key = qim and (qim(finale.CMDMODKEY_ALT) or qim(finale.CMDMODKEY_SHIFT))
273275

0 commit comments

Comments
 (0)