finale-lua / lua-scripts

A central repository for all Lua scripts for Finale.
https://finalelua.com
Creative Commons Zero v1.0 Universal
14 stars 14 forks source link

Update pitch_entry_keep_delete.lua #704

Closed cv-on-hub closed 4 months ago

cv-on-hub commented 4 months ago

Changed Popups to RadioButtonGroups for operational clarity, improved Markdown for website listing, and added Script Info dialog through show_notes_dialog(). This PR is subject to @jwink75’s approval since he generously allowed me to subvert his original script submission. (Some of the other alterations flagged here are just a change in the indent method).

But the real reason for this PR is to dig deeper into Robert’s assertion that my Key Commands are “hacks”. This is an ideal exemplar because there’s only one CtrlEdit ("number") with a tightly prescribed format.

We read CtrlEdit contents at will, provide initial values, are told by the Handler when they change, and may need subsequently to change their contents for any number of reasons. That’s all that my Key Commands do. In this case the number control must only be numeric, and if the User accidentally types “z” we must either immediately message an error or cancel the activity (which could be confusing). So why not inhibit alphabet entry in the first place? When any new key is typed in the control just ignore it unless it’s numeric. Is that a hack? It’s certainly handy to the user.

Similarly it should only be one digit (unless you deal regularly with 19-note chords). If the user types a second digit just use that one instead so they don’t need to hit the delete key first. This is exactly the same behaviour as when the control is highlighted. Which it probably is anyway. That feels a tad hack-ish, but is it really? Ctrl handle alert -> read value -> write revised value. Standard CtrlEdit handling.

So now we have all these left-over alphabetics … why not do something useful with them? Scripts can make all types of internal decisions about contents, enabling controls, re-drawing dialog contents etc, for any set of reasons. (Just like Robert’s incredibly clever class browser does). If a key press is unwanted as value input then surely it’s free to trigger anything else within the dialog. Is that a hack?

Robert suggested that some unexpected consequence might arise in the future, but I can't really see what. (Even though that's the whole point of "unexpected"!) It's only doing what Edit controls already do in any script that calls dialogs.

asherber commented 4 months ago

I think these key commands are very clever; I also think implementing them on an edit control is a hack. It's fine for code attached to an edit box to restrict input to that control or manipulate that control, but it's unexpected for code on a control to manipulate other items in the window. It would be more usual for code like that to be attached to the window.

(As Robert has also pointed out, it may also be one of the other controls on the window that has focus, in which case key commands attached to a single control won't work.)

Is there a way for a keypress handled by a control to propagate up to the window if the control doesn't want it?

As a side note, I wish the key commands in this dialog acted more like mnemonics -- k for keep, d for delete, etc. That's the standard practice in Windows, where controls often have "accelerator keys". These show up as an underscored letter in the control's text and are triggered with Alt plus the key.

rpatters1 commented 4 months ago

On Windows, it might be possible to simply add the underscored mnemonics with the & character. They might just work then. But I haven't tried it.

rpatters1 commented 4 months ago

Unfortunately, there is no generalized keystroke monitoring available in RGP Lua (or JW Lua). The hack of using an edit control is probably the only option, at least on a Mac. (I think there's at least a chance mnemonic characters would work on Win if they were added to the text of the control.)

rpatters1 commented 4 months ago

The FCCtrlTextEditor and latest iteration of FCCtrlDataList each provide command keys to the control. That is, if the user presses cmd (mac) or ctrl (win) in combination with any letter on either of those controls, you can get a notification that you can either handle or propagate.

cv-on-hub commented 4 months ago
  1. it's unexpected for code on a control to manipulate other items in the window. Maybe unexpected philosophically, but I see the "window" as a single united system and whether or not a command originates at the "top" of the window or anywhere "inside" it is moot. I have several scripts where a checkbox setting must enable or disable other controls. Is that also a hack? Surely it's just part of that window's total ecosystem.
  2. I wish the key commands acted more like mnemonics Well sure - if that's what you want. You will notice that all my key commands (in all scripts) keep to the left-hand side of the QWERTY, and often trigger a string of adjacent checkboxes with something like W-E-R-T-Y. Or else use nearby keys (A-Z, S-X) for "toggling" type actions. It's trivial to set, in your copy of the script, any key you like for each action. Following "first letter" commands all over the keyboard takes as much getting used to as having all commands fall neatly under the left hand. Whichever system you use frequently will become easily brain-wired.
  3. one of the other controls on the window may have focus And I've made it very clear in all Script_Infos that the Key Commands only work when numeric fields are selected. Once one is selected, in either OS, that control should stay selected and the key commands will continue to work. None of this precludes mouse control or prevents the user changing from one to the other.
  4. FCCtrlTextEditor and FCCtrlDataList each provide command keys to the control But if this is all hacking then one shouldn't use such commands anywhere except "within" that control. Which makes that power hardly worth having. Surely to do anything actually useful you should be able to control everything inside the window?
rpatters1 commented 4 months ago

To be clear, my comment is merely to state what's available now. I'm not suggesting any of them are very useful for the intended purpose.

Intercepting keystrokes on dialog boxes at the window level is harder than you might think on both platforms, but especially on Mac. Dialog boxes are designed to let the in-focus control have the character, and many of those controls simply eat them even if they don't do anything with them. Both OSs have built-in ways of providing keyboard-only navigation. I understand that @cv-on-hub is not satisfied with them, but trying to defeat or improve them will be a losing battle in the general case. This is not to say I see any reason to object to this script being added to the repo.

rpatters1 commented 4 months ago

I should add that, my philosophy has always been to provide as close to bog-standard behavior as possible. This actually makes it easier for a user to customize whatever keystrokes they like with a keyboard macro to fit the exact contour of their fingers, because the program is behaving the way the macro program expects it to. By designing the program itself to provide this level of customized behavior, you are limiting your user base. Maybe this is not a big concern for some programmers. ymmv

asherber commented 4 months ago

A checkbox which enables or disables other controls makes sense to me, because the checkbox is saying, "If my state changes, then these other things must happen as well". I think this is different from an edit control taking action on other controls without its own state being changed.

ThistleSifter commented 4 months ago

Intercepting keystrokes on dialog boxes at the window level is harder than you might think on both platforms, but especially on Mac. Dialog boxes are designed to let the in-focus control have the character, and many of those controls simply eat them even if they don't do anything with them.

How did FinaleScript handle adding custom keyboard shortcuts? Was there some other mechanism that it used?

rpatters1 commented 4 months ago

I don't know much about FinaleScript so I can't comment about how it works.