On 08/11/2023 21:18, Andy Goryachev wrote:
Dear Michael:
Thank you for specific questions!
> "switch between vim/emacs/etc. key mappings"? Maybe you can give a specific
example.
Vim/emacs might be a bad example, as they use key sequences. Key
sequences are not a part of this proposal (but it is possible to
implement with the help of the proposed API).
One example is a user preference for Go-To-Line function typical in
text editors. In jEdit on Mac it’s ⌘E, while in Eclipse it’s ⌘G. The
user might strongly prefer to have one or the other, so an application
requirement might include redefining one or more keys. Since it’s a
user preference, it has to be done at runtime.
That's not a function offered by text controls at all. That's a short
cut for a menu function that will pop-up a dialog asking for a line
number (Ctrl + L in Eclipse).
Standard behavior is everything that's standard about a control's
behavior that people come to expect when using their platform of
choice. Any text field will offer defaults like:
left: move cursor one character to the left
control+left: move cursor one word to the left
home: move cursor to start of line
ctrl+home: move cursor to start of text
ctrl+x/c/v: cut/copy/paste
etcetera.
What you are proposing here is about providing high level short-cuts
which IMHO is squarely in the domain of the application developer, or
some 3rd party. FX should only care about offering ways to change the
implicit standard key bindings that you use without even thinking about.
Basically, if it isn't a function offered directly by the control, and
handled directly by the control, then it's the application that should
be handling it. And they can handle this already by assigning such a
short cut to a menu, or by installing global/local event handlers.
What they CAN'T do right now is:
- Disabling one of those implicit key bindings because you want to use
it for something else (ie, application managed)
- Remapping an implicit key binding to a different key
Both of these are a rare occurence, as this would immediately cause
usability issue as you'd be deviating from standard control behavior,
but it may perhaps be useful in some very rare cases. This is why I
think it's fine to have to do a bit more work to achieve this (ie.
subclass a Behavior).
1. The way I understand it, the only thing a public InputMap API would
enable developers to do would be to change key mappings of existing
control functionality. For example, I could re-map the left arrow to
invoke the "moveRight" function, or I could re-map ctrl+A to "copy"
text, instead of "select all" text. But why would I want to do that?
These are default mappings for a reason. Is there any example in which
such a re-mapping would potentially be useful?
The public API should **enable** the possibility, even if the core set
of controls do not require it. I It is not the case of whether you
want to remap ctrl-A to COPY, but a case when an application developer
has a requirement to remap something (command-E to command-G). You
even hint at such a requirement when talking about navigating camel
case words.
How are you going to configure all the intricacies here? When should a
key trigger, on PRESSED, RELEASED, on both? What about when I hold it
down for more than 0.7 seconds? That's not something I made up, but in
use in actual code:
long heldTime = System.currentTimeMillis() - keyPressedStartTime;
if (keyPressedCode == event.getCode() && heldTime >= 700) {
handleLongPressKeyEvent(event);
}
...there are so many cases, and there is no way this can all be captured
with a simple "A to B" input map.
It also still ignores the fact that some of these standard keys react
differently already. Take SPACE for Button for example; it doesn't fire
on PRESSED, it fires on RELEASED. If I want it to fire immediately (so
I can do key repeat on Buttons, for some game or something), I already
need to write a custom function, but without the benefit of being able
to access ButtonBehavior's internal state, like the "keydown" flag
(which to be clear is not the same as Control.isArmed()).
2. We seem to be talking about text a lot. Is there any specific
example beyond TextInputControl that would benefit from this feature?
Maybe this should be an extension for TIC, and not for the control
architecture as a whole?
Some controls do not need an input map, some do. Some controls may
not benefit from key mapping, but others do. I focused on TIC because
that’s the area I am currently focused on, but perhaps Tree/Table view
could be another case where custom key mapping might be useful.
3. I have two examples that are not possible in JavaFX right now (at
last not out of the box):
...
The proposed API doesn't enable me to implement those features, does
it?
It does, it was specifically designed with these requirements in mind.
For example, for
Scroll through text on a word-by-word basis (look for: "Use CamelHump
words"
You’d define a custom function tags for
NEXT_CAMEL_HUMP_STOP/PREVIOS_CAMEL_HUMP_STOP and implement the
functions (get caret position or selection range from the control,
computing the next/previos stop by looking at the text, and setting
the caret to the new position), and remapping the RIGHT/LEFT keys to
the new function. If everything you need is provided to you by the
control’s public API, you don’t even have to touch the default skin or
its behavior.
I'm wondering if you tried doing this already: modify a Skin (directly
in FX repository), removing one of its more complicated bindings, and
reimplement it. I suspect that there is quite some internal state that
is unavailable on Control that you'd need to know in order to make it
feel again like it is part of the control (why else are Behaviors
stateful) and so it works exactly the same as it did before.
I suspect that without access to all the internals, such a custom
function will feel like a hotkey, that disregards anything else that's
going on in the control, and just does its thing whether that's a good
idea right now or not; it won't feel as an integrated part of the control.
--John