[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-openjfx-dev
Subject:    Re: [Request for Comments] Behavior / InputMap
From:       Martin Fox <martin () martinfox ! com>
Date:       2023-10-31 0:23:27
Message-ID: B02F9DBC-001B-498C-8EE5-29D6B5E87F67 () martinfox ! com
[Download RAW message or body]

I was looking over the InputMap proposal with an eye toward paring it down to the \
bare minimum.

From the perspective of a user who wants to manipulate a control without subclassing \
it I think there are only a few essential components.

1) Ensure the user gets events before the control does. That's a topic for a \
different thread.

2) Provide an API that asks a control to perform the operation identified by a \
FunctionTag. This is the only way to access operations like COPY and MOVE_RIGHT that \
are implemented behind the scenes.

3) Provide an API that asks a control to map an Event to a FunctionTag. This enables \
blocking existing mappings; if a user wants to block the default mappings for, say, \
COPY they can simply discard/consume any events that the control would map to COPY.

If a user wants to subclass an existing control they could also use these API's to do \
full customization but only if they can guarantee that their subclass will process \
events before the superclass. That, too, might be a separate discussion.

I would like to discuss these API's without getting too deep into implementation \
details. With that said, I do have one implementation suggestion: since most of the \
event => FunctionTag mappings are common (SELECT_ALL is always Shortcut+A) there \
should be an internal shared object containing the common mappings.

Martin

> On Oct 30, 2023, at 3:11 PM, Andy Goryachev <andy.goryachev@oracle.com> wrote:
> 
> Dear Kevin:
> 
> Thank you for providing a summary to our (lively) discussion.  Even though I think \
> I answered these concerns, I don't mind to have another go at it. 
> Please find the updated proposal here (same link):
> 
> https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09
> 
> Let me first define what I mean by "behavior" in the context of this proposal.  A \
> behavior is a translation layer between input events - coming either from the \
> control, or from some nodes contained in the skin, or from the platform itself - \
> into some actions.  These translation mappings are maintained by a new property in \
> Control - the InputMap.  The InputMap has two sides - one for the user application, \
> and another - for the skins/behaviors.  Both are "public APIs" but the latter is \
> represented as protected methods of BehaviorBase class which forms a foundation of \
> the behavior part of the skins that want to use the InputMap paradigm. 
> Back to individual concerns.
> 
> * We should not make anything related to Behaviors public without a full design of \
> how Behaviors should work, what their responsibilities are, how they interact with \
> Skins 
> And we don't.  We recommend to use BehaviorBase, but it's still possible to use \
> event handlers or any other home-grown mechanism to implement skins/behaviors and \
> suffer from the lack of functionality as a result.  If BehaviorBase is not the \
> right name, we can call it InputMapAccessorForSkinUse any other name. 
> * This proposal doesn't solve the coupling of Skins and behaviors
> 
> The skins and behaviors are tightly coupled in some cases.  It is possible that a \
> simple control such as Button does not require tight coupling, but a complex \
> control such as TextArea does (see TextAreaSkin:1214). 
> With the InputMap, we now can separate user mappings from skin mappings and \
> handlers.  Changing a skin will unregister all of the handlers added by the \
> associated behavior, leaving the user mappings intact. 
> * Function tags are defined in control class, but don't match the functionality of \
>                 control class
> NOTE: this begs the question of whether there should always be a method on control \
> for each such function (even if the implementation just delegates to the behavior 
> May be it was not described extensively, but it is being suggested to have one \
> public method for each function tag, which does invoke the said tag.  This enabled \
> indirection via InputMap which in turn allows the app- or skin- developer to \
> redefine the functionality (in effect, allowing for changing the behavior without \
> subclassing the behavior). 
> So, for example, SomeControl.copy() would invoke execute(TAG_COPY), which by \
> default would invoke SomeControlBehavior.copy(). 
> This proposal did not make this change for the subset of controls - intentionally - \
> because it can be done later in a separate PR. 
> * An input map should not refer to the node and be stateless and sharable among all \
> (or some) instances of the same class; this would mean mapping input events to \
>                 Control::method rather than to instance::method or to some \
>                 arbitrary lambda
> NOTE: this would depend on the previous being resolved
> 
> I think we are confusing two things.  The InputMap allows for per-control mapping, \
> so it cannot be shareable or static.  Period. 
> Now, the other thing is a possible requirement to allow for changing the mapping on \
> per-control-type basis, to overwrite the behavior for each instance of a particular \
> control.  This I did not address because it's an implementation detail for that \
> control type.  I did not want to add child maps, but perhaps we could add another \
> API to the skin/behavior side of InputMap to allow for such a static map. 
> Personally, I don't like the idea as it basically adds nothing: event handlers \
> still need to be added to each control and each Node in the skin (if any) and there \
> is an extra complexity added.  A better solution would be to subclass the control \
> class and add the mappings for each instance just like we do today. 
> * Arbitrary key mapping seems out of scope for the core of JavaFX; this sort of \
> mapping could be done by the application if the event order problem was solved, and \
> if we had public API on control for all functions that are called by the behavior. 
> Arbitrary (user) key bindings are enabled by the proposed InputMap.  Any \
> alternative proposal, in my opinion, should support this function out of the box. 
> * Should Input map be immutable?
> 
> The value of InputMap is ability to change the mapping, so I don't understand where \
> this requirement is coming from.  Perhaps an example or a use case could be \
> provided? 
> * Changes to the Behavior system should focus on replacing complete behaviors, and \
> being able to use these by default for a certain subset of controls (like -fx-skin \
> provide in CSS) 
> As I mentioned earlier, the skin and its behavior might be tightly coupled.  So if \
> a use case exists for changing the behavior, we already have a solution - a custom \
> skin.  May be a use case or an example of why we can't do that with the existing \
> architecture would help here. 
> And finally, I would like to emphasize that even though the InputMap proposal is \
> fairly well developed and validated using a number of non-trivial controls and some \
> new controls (RichTextArea https://github.com/andy-goryachev-oracle/jfx/pull/1 ), I \
> am not against modifying/enhancing it based on the community feedback.  I hope we \
> can get to a good solution in a reasonable time frame, or we all would have to \
> learn react and program in javascript. 
> Cheers,
> -andy
> 
> 
> 
> 
> 
> From: openjfx-dev <openjfx-dev-retn@openjdk.org> on behalf of Kevin Rushforth \
>                 <kevin.rushforth@oracle.com>
> Date: Friday, October 27, 2023 at 16:34
> To: openjfx-dev <openjfx-dev@openjdk.org>
> Subject: Re: [Request for Comments] Behavior / InputMap
> 
> I've mostly caught up on the (lively) discussion surrounding this feature request.
> 
> It is clear that we do not yet have general agreement on the direction this \
> proposal should take, so let's continue to discuss the proposal, its shortcomings, \
> and any alternative approaches. 
> We should start by making sure that the motivation for doing this -- what problem \
> is being solved -- is well understood. Andy will rework the initial sections of the \
> proposal to make it more clear. 
> If I can summarize what I see are the main concerns that have been raised:
> 
> * We should not make anything related to Behaviors public without a full design of \
> how Behaviors should work, what their responsibilities are, how they interact with \
> Skins 
> * This proposal doesn't solve the coupling of Skins and behaviors
> 
> * Function tags are defined in control class, but don't match the functionality of \
>                 control class
> NOTE: this begs the question of whether there should always be a method on control \
> for each such function (even if the implementation just delegates to the behavior 
> * An input map should not refer to the node and be stateless and sharable among all \
> (or some) instances of the same class; this would mean mapping input events to \
>                 Control::method rather than to instance::method or to some \
>                 arbitrary lambda
> NOTE: this would depend on the previous being resolved
> 
> * Arbitrary key mapping seems out of scope for the core of JavaFX; this sort of \
> mapping could be done by the application if the event order problem was solved, and \
> if we had public API on control for all functions that are called by the behavior. 
> * Should Input map be immutable?
> 
> * Changes to the Behavior system should focus on replacing complete behaviors, and \
> being able to use these by default for a certain subset of controls (like -fx-skin \
> provide in CSS) 
> There are probably other concerns as well.
> 
> Finally, one of the comments made, which I completely agree with, is that API \
> design needs to come first. It needs to be fully fleshed out, and needs to be \
> forward-looking. We should only expose as public API what is needed to solve the \
> problem and no more. 
> Let's continue the discussion with this in mind.
> 
> -- Kevin
> 
> 
> On 9/29/2023 3:44 PM, Andy Goryachev wrote:
> Dear fellow JavaFX developers:
> 
> For some time now, we've been working to identify missing features in JavaFX that \
> hinder application development.  We've been working on adding some of the missing \
> features (for which we'll have a separate announcement), but I feel that engaging \
> wider community is a rather important part of the process. 
> I would like to share with you one such missing feature - ability to extend \
> behavior of the existing components (and make the task of creating new components \
> easier) by adding a public InputMap and BehaviorBase.   
> Please find the actual proposal here
> https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09
> 
> We are very much interested in your feedback.  Thank you in advance.
> 
> -andy


[Attachment #3 (unknown)]

<html><head><meta http-equiv="content-type" content="text/html; \
charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: \
space; line-break: after-white-space;"><p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">I was looking over the InputMap proposal with an \
eye toward paring it down to the bare minimum.</p><p style="margin: 0px; font-style: \
normal; font-variant-caps: normal; font-stretch: normal; font-size: 12px; \
line-height: normal; font-family: Helvetica; font-size-adjust: none; font-kerning: \
auto; font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;"><br></p><p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">From the perspective of a user who wants to \
manipulate a control without subclassing it I think there are only a few essential \
components.</p> <p style="margin: 0px; font-style: normal; font-variant-caps: normal; \
font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; \
font-size-adjust: none; font-kerning: auto; font-variant-alternates: normal; \
font-variant-ligatures: normal; font-variant-numeric: normal; \
font-variant-east-asian: normal; font-variant-position: normal; \
font-feature-settings: normal; font-optical-sizing: auto; font-variation-settings: \
normal; min-height: 14px;"><br></p> <p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">1) Ensure the user gets events before the control \
does. That's a topic for a different thread.</p> <p style="margin: 0px; font-style: \
normal; font-variant-caps: normal; font-stretch: normal; font-size: 12px; \
line-height: normal; font-family: Helvetica; font-size-adjust: none; font-kerning: \
auto; font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal; min-height: 14px;"><br></p> <p style="margin: 0px; \
font-style: normal; font-variant-caps: normal; font-stretch: normal; font-size: 12px; \
line-height: normal; font-family: Helvetica; font-size-adjust: none; font-kerning: \
auto; font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">2) Provide an API that asks a control to perform \
the operation identified by a FunctionTag. This is the only way to access operations \
like COPY and MOVE_RIGHT that are implemented behind the scenes.</p> <p \
style="margin: 0px; font-style: normal; font-variant-caps: normal; font-stretch: \
normal; font-size: 12px; line-height: normal; font-family: Helvetica; \
font-size-adjust: none; font-kerning: auto; font-variant-alternates: normal; \
font-variant-ligatures: normal; font-variant-numeric: normal; \
font-variant-east-asian: normal; font-variant-position: normal; \
font-feature-settings: normal; font-optical-sizing: auto; font-variation-settings: \
normal; min-height: 14px;"><br></p> <p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">3) Provide an API that asks a control to map an \
Event to a FunctionTag. This enables blocking existing mappings; if a user wants to \
block the default mappings for, say, COPY they can simply discard/consume any events \
that the control would map to COPY.</p> <p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal; min-height: 14px;"><br></p> <p style="margin: 0px; \
font-style: normal; font-variant-caps: normal; font-stretch: normal; font-size: 12px; \
line-height: normal; font-family: Helvetica; font-size-adjust: none; font-kerning: \
auto; font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">If a user wants to subclass an existing control \
they could also use these API's to do full customization but only if they can \
guarantee that their subclass will process events before the superclass. That, too, \
might be a separate discussion.</p> <p style="margin: 0px; font-style: normal; \
font-variant-caps: normal; font-stretch: normal; font-size: 12px; line-height: \
normal; font-family: Helvetica; font-size-adjust: none; font-kerning: auto; \
font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal; min-height: 14px;"><br></p> <p style="margin: 0px; \
font-style: normal; font-variant-caps: normal; font-stretch: normal; font-size: 12px; \
line-height: normal; font-family: Helvetica; font-size-adjust: none; font-kerning: \
auto; font-variant-alternates: normal; font-variant-ligatures: normal; \
font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-position: \
normal; font-feature-settings: normal; font-optical-sizing: auto; \
font-variation-settings: normal;">I would like to discuss these API's without getting \
too deep into implementation details. With that said, I do have one implementation \
suggestion: since most of the event =&gt; FunctionTag mappings are common (SELECT_ALL \
is always Shortcut+A) there should be an internal shared object containing the common \
mappings.</p><p style="margin: 0px; font-style: normal; font-variant-caps: normal; \
font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; \
font-size-adjust: none; font-kerning: auto; font-variant-alternates: normal; \
font-variant-ligatures: normal; font-variant-numeric: normal; \
font-variant-east-asian: normal; font-variant-position: normal; \
font-feature-settings: normal; font-optical-sizing: auto; font-variation-settings: \
normal;"><br></p><p style="margin: 0px; font-style: normal; font-variant-caps: \
normal; font-stretch: normal; font-size: 12px; line-height: normal; font-family: \
Helvetica; font-size-adjust: none; font-kerning: auto; font-variant-alternates: \
normal; font-variant-ligatures: normal; font-variant-numeric: normal; \
font-variant-east-asian: normal; font-variant-position: normal; \
font-feature-settings: normal; font-optical-sizing: auto; font-variation-settings: \
normal;">Martin</p><div><br><blockquote type="cite"><div>On Oct 30, 2023, at 3:11 PM, \
Andy Goryachev &lt;andy.goryachev@oracle.com&gt; wrote:</div><br \
class="Apple-interchange-newline"><div><meta charset="UTF-8"><div \
class="WordSection1" style="page: WordSection1; caret-color: rgb(0, 0, 0); \
font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: \
normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: \
0px; text-transform: none; white-space: normal; word-spacing: 0px; \
-webkit-text-stroke-width: 0px; text-decoration: none;"><div style="margin: 0in; \
font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: \
&quot;Iosevka Fixed SS16&quot;;">Dear Kevin:<o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">Thank you for providing a summary to our (lively) discussion.&nbsp; Even \
though I think I answered these concerns, I don't mind to have another go at \
it.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; font-family: \
Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">Please find the updated proposal here (same \
link):<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; font-family: \
Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><a href="https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09" \
style="color: rgb(5, 99, 193); text-decoration: \
underline;">https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09</a><o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">Let me first define what I mean by "behavior" in the context of this \
proposal.&nbsp; A behavior is a translation layer between input events - coming \
either from the control, or from some nodes contained in the skin, or from the \
platform itself - into some actions.&nbsp; These translation mappings are maintained \
by a new property in Control - the InputMap.&nbsp; The InputMap has two sides - one \
for the user application, and another - for the skins/behaviors.&nbsp; Both are \
"public APIs" but the latter is represented as protected methods of BehaviorBase \
class which forms a foundation of the behavior part of the skins that want to use the \
InputMap paradigm.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">Back to individual concerns.<o:p></o:p></span></div><div style="margin: \
0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: \
&quot;Iosevka Fixed SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: \
0in 0in 0in 0.5in; font-size: 11pt; font-family: Calibri, sans-serif;">* We should \
not make anything related to Behaviors public without a full design of how Behaviors \
should work, what their responsibilities are, how they interact with \
Skins<br><br><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">And we don't.&nbsp; We recommend to use BehaviorBase, but it's still \
possible to use event handlers or any other home-grown mechanism to implement \
skins/behaviors and suffer from the lack of functionality as a result.&nbsp; If \
BehaviorBase is not the right name, we can call it InputMapAccessorForSkinUse any \
other name.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in 0in 0in 0.5in; \
font-size: 11pt; font-family: Calibri, sans-serif;">* This proposal doesn't solve the \
coupling of Skins and behaviors<span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">The skins and behaviors are tightly coupled in some cases.&nbsp; It is \
possible that a simple control such as Button does not require tight coupling, but a \
complex control such as TextArea does (see \
TextAreaSkin:1214).<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;">With the InputMap, we now can separate user mappings from skin mappings \
and handlers.&nbsp; Changing a skin will unregister all of the handlers added by the \
associated behavior, leaving the user mappings intact.<o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in 0in 0in 0.5in; \
font-size: 11pt; font-family: Calibri, sans-serif;">* Function tags are defined in \
control class, but don't match the functionality of control class<br>NOTE: this begs \
the question of whether there should always be a method on control for each such \
function (even if the implementation just delegates to the behavior<br><br><span \
style="font-family: &quot;Iosevka Fixed SS16&quot;;"><o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: &quot;Iosevka Fixed SS16&quot;;">May be it was not described \
extensively, but it is being suggested to have one public method for each function \
tag, which does invoke the said tag.&nbsp; This enabled indirection via InputMap \
which in turn allows the app- or skin- developer to redefine the functionality (in \
effect, allowing for changing the behavior without subclassing the \
behavior).<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: &quot;Iosevka Fixed \
SS16&quot;;"><o:p>&nbsp;</o:p></span></div><div style="margin: 0in; font-size: 11pt; \



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic