Behaviors, Event Handlers and builtin HTML Controls
General principles
Behaviors and event handlers are the way to make html page dynamic. Main purpose of the behavior is to handle various user interface events: mouse and keyboard, timer and drawing events, etc. Event is the representation of some asynchronous occurrence (e.g. mouse click or loss of focus) that gets associated with an html element (targeted at it.)
Physically behaviors are implemented by host application as a function:
BOOL ElementEventProc(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms);
ElementEventProc is a functional equivalent of WindowProc. SDK contains C++ class event_handler - OO wrapper splitting calls of various event groups (evtg) into separate virtual calls: on_mouse , on_key, on_focus, etc.
Behaviors can be attached by CSS and programmatically in runtime. Any element can have multiple behaviors/event_handlers.
Style definition (CSS) in HTMLayout may contain behavior attribute:
.myclass { behavior:my-button; }
When HTMLayout loads html document it resolves styles of all elements. If some element is getting behavior value then HTMLayout window sends notification HLN_ATTACH_BEHAVIOR to host application with the name of behavior ("my-button" in this case). And host application may provide its own implementation of the behavior.
SDK also contains implementation of the behavior:event_handler C++ class. behavior class has additionally name field and implements list of instances - list of behaviors. Therefore behavior is a named event_handler in HTMLayout.
Propagation of Events.
When an event occurs it is being dispatched. HTMLayout uses standard for HTML sinking/bubbling dispatch mechanism which is quite different from the one Windows uses.
Lets imagine that we have following document:
<html> <body> <p><input type="button"></p> </body>
</html>
and user will press mouse button on the input element.
The dispatch is done in two phases: The first phase is called sinking ( or capture ). At this phase event is passed down from root element to the target element.
If user click on the input the event would be first processed by event handler of <html> element, then by <body>, and then by <p> element and <input>.
The second phase is called bubbling. At this phase the event is passed back up the tree to the root element. For the example above, elements would be processed in the following order: first <input> element, then <p>, then <body> and last <html> element.
If element has multiple event handlers assigned then their ElementEventProcs will be called in the order of handler assignment.
Sinking phase is marked by PHASE_MASK:SINKING bit of cmd field in event parameters structure. See file sdk/include/htmlayout_behaviors.h. Thus if you need to handle mouse down event in sinking phase (before it will be dispatched to children) you will use:
case MOUSE_DOWN | SINKING : ... break;
and if you want to handle MOUSE_DOWN if it was not processed by any child you will do following:
case MOUSE_DOWN : ... break;
Therefore event_handler associated with some element will receive:
- all events targeted at it or contained elements in sinking phase (with SINKING flag);
- all events targeted at this element and all non-consumed by its children events in the bubbling phase.
Event is considered as consumed if correspondent ElementEventProc in the chain will return TRUE while handling it. In this case HTMLayout stops dispatching it further. Thus if for example event_handler of the root element will always return TRUE for some event in sinking phase then no one descendant of the root will not even know about this event occurrence.
Builtin HTML Controls.
Built-in input controls in HTMLayout are plain DOM elements. Period.
Different input elements have different behaviors implemented guess by what? - by set of the behaviors of course. Take a look on master style sheet of HTMLayout. This CSS (Cascading Style Sheet) table is used by HTMLayout for assigning behaviors to particular DOM elements and for definition of their rendering styles.
Having behaviors declared and assigned by CSS practically means following:
- You can design your own behavior which will replace builtin behavior. It is enough to say e.g. :
button { behavior:my-button; } and all <button>s will automagically get your own application specific behavior.
- You can assign standard behaviors to any DOM element of your choice. For example CSS declaration:
td.button { behavior:button; } will assign button behavior for all cells <td class="button"> in some table.
- CSS and its cascading rules allows now to define not only rendering style of the element but also "behavioral style" of element.
Standard Behaviors.
Here is a list of currently supported behaviors (some of them are not documented but work):
| button, radio, checkbox |
| |
TBD... |
| text, number, password - TBD... |
| |
TBD... |
| behavior:decimal - decimal number input element. |
| Attributes: |
- format - string defining format of number representation:
"grouping:3; fdigits:4; leading-zero:false; decimal-sep:','; thousand-sep:'_'; negative-sign:false" where:
- grouping - number, number of digits in "thousand" groups.
- fdigits - number, fractional digits to show.
- leading-zero - true/false, show leading zero.
- decimal-sep - string, separator between integer and fractional parts.
- grouping-sep - string, separator between groups.
- negative-sign - true/false, true - show '-', false - wrap digits by '(' ')' characters.
If the format attribute ommited then the behavior will use current user settings for decimal numbers.
|
| Automatic attributes: |
(set by behavior and can be used for styling purposes)
- invalid - behavior will set this attribute if user provide wrong content (e.g. alpha characters)
- negative - behavior will set this attribute if number is negative.
|
| Element |
<input type="decimal" /> |
| Events: |
This behavior generates BEHAVIOR_EVENT with codes EDIT_VALUE_CHANGING and EDIT_VALUE_CHANGED events when user will change its value. |
| behavior:currency - decimal number input element. |
| Attributes: |
- format - string defining format of number representation:
"grouping:3; fdigits:4; leading-zero:false; decimal-sep:','; thousand-sep:'_'; negative-sign:false" where:
- grouping - number, number of digits in "thousand" groups.
- fdigits - number, fractional digits to show.
- leading-zero - true/false, show leading zero.
- decimal-sep - string, separator between integer and fractional parts.
- grouping-sep - string, separator between groups.
- negative-sign - true/false, true - show '-', false - wrap digits by '(' ')' characters.
- currency - string, currency sign to show.
- currency-after - true - currency sign after , false - sign is before numbers.
If the format attribute ommited then the behavior will use current user settings for decimal numbers.
|
| Automatic attributes: |
(set by behavior and can be used for styling purposes)
- invalid - behavior will set this attribute if user provide wrong content (e.g. alpha characters)
- negative - behavior will set this attribute if number is negative.
|
| Element |
<input type="currency" /> |
| Events: |
This behavior generates BEHAVIOR_EVENT with codes EDIT_VALUE_CHANGING and EDIT_VALUE_CHANGED events when user will change its value. |
| behavior:select - selectable list element. Also supports hierarchical items (<options> elements) - a.k.a. TreeView. |
| Attributes: |
- multiple - allows multiselection
- multiple="checks" - multiselection with checkmarks.
|
| Elements: |
Elements <select type="select"> and <widget type="select"> have this behavior applied by default. This element and is seen to CSS processor so you may use it for styling.
Select can contain arbitrary markup (not only <option>s). See samples in SDK. |
| Events: |
This behavior generates BEHAVIOR_EVENT with codes SELECT_SELECTION_CHANGED when user will change selection. |
| Value: |
See get/set_value() function implementations in the SDK. |
| behavior:dropdown-select - select with dropdown list element |
| Attributes: |
- editable - if this attribute defined then caption portion of the select will have behavior:edit applied - will be editable.
|
| Elements: |
Elements <select size=1>, <select type="dropdown-select"> and <widget type="dropdown-select"> have this behavior applied by default. This element and is seen to CSS processor so you may use it for styling. Dropdown select consists of:
select element
- caption element
- button element
- select element (this is a popup select element)
- option element 1,
- option element 2,
- .....
|
| Events: |
This behavior generates BEHAVIOR_EVENT with codes SELECT_SELECTION_CHANGED when user will change its value. |
| Value: |
See get/set_value() function implementations in the SDK. |
| behavior:textarea - mutiline edit box. |
| Attributes: |
- cols and rows - integers, number of columns and rows (characters in line and lines). These parameters determine min-intinsinc values of width and height.
- maxlength - integer, maximum number of characters this element can hold.
- wrap="off" resolves to white-space:pre CSS attribute, other values of the wrap attribute resolve to white-space:prewrap - preserve white spaces and carrige returns but allow line wrapping.
|
| Elements: |
Elements <textarea> and <widget type="textarea"> have this behavior applied by default. This element and is seen to CSS processor so you may use it for styling. Each paragraph inside the textarea is a also seen to CSS processor so it can be styled. See html_samples/forms/textarea.htm for examples of textarea styling. |
| Events: |
This behavior generates BEHAVIOR_EVENT with codes EDIT_VALUE_CHANGING and EDIT_VALUE_CHANGED events when user will change its value. |
| Value: |
Use dom::element::get_text/dom::element::set_text finctions. |
| behavior:htmlarea - WYSIWYG HTML editor. |
| |
TBD... |
| behavior:progress - progress bar. |
| |
TBD... |
| behavior:hslider and behavior:vslider - slider bars. |
| Attributes: |
- min and max - integer, minimum and maximum values of slider range.
- value - integer, current value of the slider.
- buddy - string, id of "buddy" DOM element. Text of the buddy element will be updated if value of the slider will change.
|
| Elements: |
Elements <input type="hslider">, <input type="vslider">, <widget type="hslider" /> and <widget type="vslider" /> have this behavior applied by default. These elements have single child element of type img.slider (img of class "slider"). This element is seen to CSS processor so you may use it for styling. |
| Events: |
this behavior generates BEHAVIOR_EVENT/BUTTON_STATE_CHANGED event when user will change its value. |
| Value: |
Position of the slider reflects value element attribute. |
| behavior:hscrollbar and behavior:vscrollbar - standalone scrollbars. |
| Attributes: |
TBD... |
| Elements: |
Elements <input type="hscrollbar">, <input type="vscrollbar">, <widget type="hscrollbar" /> and <widget type="vscrollbar" /> have this behavior applied by default. |
| Events: |
this behavior generates SCROLLBAR_EVENTs when user will change its value. |
| Value: |
Position of the slider reflects value element attribute. |
To be continued soon...
Design of Custom Behaviors.
To be continued soon...
|