Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Riena/Custom Ridgets"

m (Ridget Design Principles)
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== Custom ridgets ==
+
{{#eclipseproject:rt.riena}}
  
There is a possibility for an application to provide and use its own ridgets (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=259937). This feature is meant for situations where a specific ridget (and corresponding widget) is not already present in riena. To support a new custom ridget the following has to be done:
+
{{RienaBox|
*For the widget create a ridget class implementing as minimum interface IRidget (there can be found many examples for ridgets in riena i.e. all subclasses of IRidget).
+
=== What are ridgets? ===
''-- Comments by Elias: The default starting point would be extending AbstractRidget. However it will be easier to extend AbstractSWTRidget or AbstractValueRidget - even though they are internal. I believe in the long run, we may have to make them API to make implementing new Ridgets easier. Please provide feedback on the mailing list or newsgroup.''
+
A ridget wraps an actual UI widget but offers a higher level of abstraction and it is independent from the UI toolkit (SWT). The idea is to separate the UI (view) from the logic behind it, which is moved to a view controller. The view controller interacts with the actual UI widgets through the ridgets. It should be possible to reuse a view controller with a view that is based on a different UI toolkit (e.g. Swing).
*Further a mapping from widget class to ridget class has to be provided to create the corresponding ridget of a widget from the view for the controller at runtime. This is done by adding the desired mapping to the existing mappings of singleton SwtControlRidgetMapper: SwtControlRidgetMapper.getInstance().addMapping(CustomWidget.class, CustomRidget.class) for example. For more details look at the JavaDoc of class SwtControlRidgetMapper.
+
  
=== Ridget Design Principles ===
+
In effect, a ridget can be considered a mini-controller for a single UI control.
  
To better understand the existing code and some challenges involved when writting a ridget, here are some design principles we follow (applies to all IValueRidget/AbstractValueRidget implementations):
+
A ridget offers the most commonly-used functionality (like <tt>setText(String)</tt> of a
 +
text field) along with some extra convenience functionality like markers. A textfield can be marked as error by adding an ErrorMarker. The marking itself (changing color, setting icons, etc.) is handled
 +
by the Riena framework. Another example is the <tt>bindToModel(...)</tt> method for a simple
 +
databinding with a JavaBean.
  
Values and Bindings:
+
The overall intention is to reduce the complexity for the application developer
* There are three values: value of the model, value in the ridget, value in the widget
+
and to ensure a common look & feel across the application. If the functionality
* When invoking bindToModel(...) the value of the model is bound to the value of the ridget. The value in the ridget is not changed when binding until ridget#updateFromModel is invoked (see below)
+
offered by the ridget's interface is not sufficient the developer can always
* Update from ridget to model is automatic. Update from model to ridget happens on request (ridget#updateFromModel())
+
access the actual UI widget. (Then of course he loses the independence from the
* When a control is bound to the ridget (ridget#setUIControl(...) invoked by the framework), the value of the ridget is copied into the control. From that point the value of the control is bound to the value in the ridget. Update in both directions (ridget to control, control to ridget) is automatic
+
UI toolkit). The set of ridgets is constantly getting bigger. If necessary it
 +
should be possible for applications to add its own ridgets.
  
Ridgets and Controls:
+
In the view you create SWT controls as always and register them with Riena (<tt>addUIControl(...)</tt>). The ridgets will be injected into the controller, where you then have access to the corresponding ridgets.
* Ridgets do not require a control (=widget) to work correctly
+
 
* Ridgets initially have no control (i.e. getUIControl() returns null)
+
(Adapted from a [http://markmail.org/message/tklyqqg7biym6uec discussion on riena-dev].) See also [[Riena_Custom_Ridgets#Ridget_Design_Principles|Ridget Design Principles]].
* When invoking ridget setters that may affect the control (example setVisibile(...)), the state must be stored in the ridget. The state is applied to the control immediately (if a control is available) or later (when a control is introduced via setUIControl(...))
+
}}
* A ridget can be unbound from a control (i.e. ridget#setUIControl(null)) or bound to a different control (i.e. ridget#setUIControl(otherControl)). In both cases listeners / bindings to the original control must be cleaned up. After this method returns the ridget should not modify the original control anymore.
+
 
 +
Riena application can provide and use its own ridgets (see [https://bugs.eclipse.org/bugs/show_bug.cgi?id=259937 issue #259937]). This feature is meant for situations where a specific ridget (and corresponding widget) is not already present in Riena. To support a new custom ridget the following has to be done:
 +
 
 +
# For the widget, create a ridget class implementing as minimum interface <tt>IRidget</tt> (many examples for ridgets can be found in Riena, i.e. all subclasses of IRidget).
 +
#: ''— Comments by Elias: The default starting point would be extending AbstractRidget. However it will be easier to extend AbstractSWTRidget or AbstractValueRidget - even though they are internal. I believe in the long run, we may have to make them API to make implementing new Ridgets easier. Please provide feedback on the mailing list or newsgroup.''
 +
# Furthermore, a mapping from the widget class to the ridget class must be provided to create the corresponding ridget of a widget from the view for the controller at runtime. This is done by adding the desired mapping to the existing mappings of singleton <tt>SwtControlRidgetMapper</tt> using the following API methods:
 +
#:<source lang="java">
 +
SwtControlRidgetMapper.getInstance()
 +
#:    .addMapping(CustomWidget.class, CustomRidget.class)
 +
#:SwtControlRidgetMapper.getInstance()
 +
#:    .addMapping(CustomWidget.class, CustomRidget.class, swtStyle)
 +
#:SwtControlRidgetMapper.getInstance()
 +
#:    .addMapping(CustomWidget.class, CustomRidget.class, new CustomMappingCondition())
 +
</source>
 +
#: For more details look at the JavaDoc of class <tt>SwtControlRidgetMapper</tt>. The mapping may be added in the custom application's activator for use in that application afterwards. Custom ridgets can be provided for all SWT widgets. For example, ridgets may be built for widgets from [http://www.eclipse.org/nebula Nebula]. Their usage is demonstrated in the [[Riena_Snippets| Snippets]].
 +
 
 +
== Ridget Design Principles ==
 +
 
 +
To better understand the existing code and some challenges involved when writing a ridget, here are some design principles we follow. This applies to all <tt>IValueRidget</tt>/<tt>AbstractValueRidget</tt> implementations.
 +
 
 +
=== Values and Bindings ===
 +
* There are three values: value of the model, value in the ridget, value in the widget.
 +
* When invoking <tt>bindToModel(...)</tt>, the value of the model is bound to the value of the ridget. The value in the ridget is not changed when binding until <tt>ridget#updateFromModel</tt> is invoked (see below).
 +
* Update from ridget to model is automatic. Update from model to ridget happens on request (<tt>ridget#updateFromModel()</tt>)
 +
* When a control is bound to the ridget (<tt>ridget#setUIControl(...)</tt> invoked by the framework), the value of the ridget is copied into the control. From that point the value of the control is bound to the value in the ridget. Update in both directions (ridget to control, control to ridget) is automatic.
 +
 
 +
=== Ridgets and Controls ===
 +
* Ridgets do not require a control (=widget) to work correctly.
 +
* Ridgets initially have no control (i.e. <tt>getUIControl()</tt> returns <tt>null</tt>).
 +
* When invoking ridget setters that may affect the control (example <tt>setVisibile(...)</tt>), the state must be stored in the ridget. The state is applied to the control immediately (if a control is available) or later (when a control is introduced via <tt>setUIControl(...)</tt>)
 +
* A ridget can be unbound from a control (i.e. <tt>ridget#setUIControl(null)</tt>) or bound to a different control (i.e. <tt>ridget#setUIControl(otherControl)</tt>). In both cases listeners / bindings to the original control must be cleaned up. After this method returns, the ridget should not modify the original control anymore.
 +
 
 +
A ridget should be provided as an interface. Then it is possible to access it through that interface in the controller.
  
 
[[Category:Riena]]
 
[[Category:Riena]]

Latest revision as of 09:19, 20 June 2011

{{#eclipseproject:rt.riena}}

What are ridgets?

A ridget wraps an actual UI widget but offers a higher level of abstraction and it is independent from the UI toolkit (SWT). The idea is to separate the UI (view) from the logic behind it, which is moved to a view controller. The view controller interacts with the actual UI widgets through the ridgets. It should be possible to reuse a view controller with a view that is based on a different UI toolkit (e.g. Swing).

In effect, a ridget can be considered a mini-controller for a single UI control.

A ridget offers the most commonly-used functionality (like setText(String) of a text field) along with some extra convenience functionality like markers. A textfield can be marked as error by adding an ErrorMarker. The marking itself (changing color, setting icons, etc.) is handled by the Riena framework. Another example is the bindToModel(...) method for a simple databinding with a JavaBean.

The overall intention is to reduce the complexity for the application developer and to ensure a common look & feel across the application. If the functionality offered by the ridget's interface is not sufficient the developer can always access the actual UI widget. (Then of course he loses the independence from the UI toolkit). The set of ridgets is constantly getting bigger. If necessary it should be possible for applications to add its own ridgets.

In the view you create SWT controls as always and register them with Riena (addUIControl(...)). The ridgets will be injected into the controller, where you then have access to the corresponding ridgets.

(Adapted from a discussion on riena-dev.) See also Ridget Design Principles.

Riena application can provide and use its own ridgets (see issue #259937). This feature is meant for situations where a specific ridget (and corresponding widget) is not already present in Riena. To support a new custom ridget the following has to be done:

  1. For the widget, create a ridget class implementing as minimum interface IRidget (many examples for ridgets can be found in Riena, i.e. all subclasses of IRidget).
    — Comments by Elias: The default starting point would be extending AbstractRidget. However it will be easier to extend AbstractSWTRidget or AbstractValueRidget - even though they are internal. I believe in the long run, we may have to make them API to make implementing new Ridgets easier. Please provide feedback on the mailing list or newsgroup.
  2. Furthermore, a mapping from the widget class to the ridget class must be provided to create the corresponding ridget of a widget from the view for the controller at runtime. This is done by adding the desired mapping to the existing mappings of singleton SwtControlRidgetMapper using the following API methods:
    SwtControlRidgetMapper.getInstance()
  3. : .addMapping(CustomWidget.class, CustomRidget.class)
  4. :SwtControlRidgetMapper.getInstance()
  5. : .addMapping(CustomWidget.class, CustomRidget.class, swtStyle)
  6. :SwtControlRidgetMapper.getInstance()
  7. : .addMapping(CustomWidget.class, CustomRidget.class, new CustomMappingCondition())
For more details look at the JavaDoc of class SwtControlRidgetMapper. The mapping may be added in the custom application's activator for use in that application afterwards. Custom ridgets can be provided for all SWT widgets. For example, ridgets may be built for widgets from Nebula. Their usage is demonstrated in the Snippets.

Ridget Design Principles

To better understand the existing code and some challenges involved when writing a ridget, here are some design principles we follow. This applies to all IValueRidget/AbstractValueRidget implementations.

Values and Bindings

  • There are three values: value of the model, value in the ridget, value in the widget.
  • When invoking bindToModel(...), the value of the model is bound to the value of the ridget. The value in the ridget is not changed when binding until ridget#updateFromModel is invoked (see below).
  • Update from ridget to model is automatic. Update from model to ridget happens on request (ridget#updateFromModel())
  • When a control is bound to the ridget (ridget#setUIControl(...) invoked by the framework), the value of the ridget is copied into the control. From that point the value of the control is bound to the value in the ridget. Update in both directions (ridget to control, control to ridget) is automatic.

Ridgets and Controls

  • Ridgets do not require a control (=widget) to work correctly.
  • Ridgets initially have no control (i.e. getUIControl() returns null).
  • When invoking ridget setters that may affect the control (example setVisibile(...)), the state must be stored in the ridget. The state is applied to the control immediately (if a control is available) or later (when a control is introduced via setUIControl(...))
  • A ridget can be unbound from a control (i.e. ridget#setUIControl(null)) or bound to a different control (i.e. ridget#setUIControl(otherControl)). In both cases listeners / bindings to the original control must be cleaned up. After this method returns, the ridget should not modify the original control anymore.

A ridget should be provided as an interface. Then it is possible to access it through that interface in the controller.

Retrieved from "https://wiki.eclipse.org/index.php?title=Riena/Custom_Ridgets&oldid=256692"

Back to the top