[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 => 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 <andy.goryachev@oracle.com> 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: \
"Iosevka Fixed SS16";">Dear Kevin:<o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; font-family: \
Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><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: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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: \
"Iosevka Fixed SS16";"><o:p> </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: "Iosevka Fixed \
SS16";"><o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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.<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </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: "Iosevka Fixed \
SS16";"><o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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).<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";">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.<o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: "Iosevka Fixed \
SS16";"><o:p> </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: "Iosevka Fixed SS16";"><o:p></o:p></span></div><div \
style="margin: 0in; font-size: 11pt; font-family: Calibri, sans-serif;"><span \
style="font-family: "Iosevka Fixed SS16";">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).<o:p></o:p></span></div><div style="margin: 0in; font-size: 11pt; \
font-family: Calibri, sans-serif;"><span style="font-family: "Iosevka Fixed \
SS16";"><o:p> </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