User Tools

Site Tools


weblogo:ideas

Event Handling

This is tricky, hard-to-understand stuff. The Web version currently has three different ways to implement event handlers. Especially with the upcoming InO-Bot, event handling becomes more important because of the multitude of sensors that InO-Bot offers.

I'll try to show how they work with three examples:

  • Menu command handler for a menuitem called TEST
  • Mouse movement handler
  • InO-Bot handler to detect a clap with your hands

The intention is to remove two of the three ways to handle events, leaving the simplest approach.

Both the Web and the Desktop versions beginning with 5.0.17236 contain all three of these handlers; please test them all if you like.

EVENTS properties

This is the oldest implementation, and Phil got used to it. You add runlists as properties of the EVENTS object, and the event data is available in the global variable :EVENTDATA.

; menu command, prints HELLO
PPROP "EVENTS "MENU.TEST [PR "HELLO]
; mouse movement, prints the position and the buttons
PPROP "EVENTS "MOUSE.MOVED [PR :EVENTDATA]
; InO-Bot noise level detection, prints "CLAP
PPROP "EVENTS "INOBOT.NOISELEVEL [IF :EVENTDATA > 30 THEN PR "CLAP]

; remove an event handler
REPMPROP "EVENTS "INOBOT.NOISELEVEL

WHEN

The WHEN command is very sophisticated, maybe too sophisticated for the casual programmer. It accepts a propertylist name, a property name, an optional condition, and a runlist. It works with several properties that I have defined with GRAPHICS and LISTENER. The :EVENTDATA variable contains the object name, the property name, the old and the new value.

This way provides most information, but it is too convoluted IMHO.

; menu command, prints HELLO
WHEN "LISTENER "MENU [IF (LAST :EVENTDATA) = "TEST THEN PR "HELLO]
; mouse movement, prints the position and the buttons
WHEN "GRAPHICS "MOUSE [(PR (LAST :EVENTDATA) GPROP "GRAPHICS "BUTTON)]
; InO-Bot noise level detection, prints "CLAP
WHEN "INOBOT [NOISELEVEL > 30] [PR "CLAP]

; remove an event handler
WHEN "INOBOT "NOISELEVEL []

Procedures

For every event, you define a procedure with a special name that receives the event data as inputs.

; menu command, prints HELLO
TO HANDLE.MENU :which
    IF :which = "TEST THEN PR "HELLO
END

; mouse movement, prints the position and the buttons
TO HANDLE.MOUSE.MOVED :pos :btns
    (PR :POS :BTNS)
END

; InO-Bot noise level detection, prints "CLAP
TO HANDLE.INOBOT.NOISELEVEL :value
    IF :value > 30 THEN PR "CLAP
END

; remove an event handler
ER "HANDLE.INOBOT.NOISELEVEL

Own opinion

I like the last approach best, because it forces procedural thinking, and makes handling the event values easy. I am not sure about the naming of these procedures, however. The event names are the same as the EVENTS object's property names, but the prefix (or suffix) could be changed.

Given the event name MOUSE.MOVED, how could the name of an event handler be:

  1. HANDLE.MOUSE.MOVED
  2. ON.MOUSE.MOVED
  3. MOUSE.MOVED.HANDLER
  4. MOUSE.MOVED.EVENT
  5. others?

List of all Events

Here is the list of possible events for the EVENTS object and event procedures that you can define along with the format of the :EVENTDATA.

Event Name EVENTDATA Description
KEY.PRESSED Key code Sent when the user presses any key. The data is the character that the user pressed. For keys that are not associated with characters, the data is a word describing the key, like ENTER, HOME, or LEFT. Note that when you tell the browser to ignore the event, the Listener will not accept any keys anymore.
MOUSE.MOVED [[x y] buttons] Sent when the mouse moves over the Graphics panel. The data is a two-element list. The first element is again a two-element list of the X and Y coordinates of the mouse position. The second element is a combination of bits that indicate which mouse buttons are pressed. A bit is set for each button. Use the LOGAND command to check these bits. The bit 1 stands for the left button, bit 2 for the middle button, bit 4 for the right button etc. For example, the command LOGAND LAST :EVENTDATA 2 <> 0 checks if the middle button is clicked.
BUTTON.CLICKED [[x y] buttons] Sent when a mouse button is clicked in the Graphics panel. The data is the same as for the MOUSE.MOVED event.
TOUCHED Array of finger data Sent on touch-enabled devices when one or more fingers touch the surface of the Graphics panel. The data is a list of lists, where each list element stands for a finger. Each “finger list” has three elements. The first element is a two-element list of the X and Y coordinates. The next element is again a two-element list of the touch area's width and height; a finger is never so small that it touches only a single pixel like a mouse does. Finally, the third element indicates the amount of pressure that the finger applied; this is a value between 0 and 1. For touch screens without pressure sensitivity (most are not touch sensitive), the value is 1.
TOUCH.MOVED Array of finger data Sent on touch-enabled devices when one or more fingers that are currently touching the Graphics panel move. The event data is the same as for the TOUCHED event.
GRAPHICS.RESIZED [width height] Sent when the size of the Graphics panel changes. The data is a two-element list with the new width and height.
MENU.XXXXX Sent when the user clicks a user-defined menu item (see APPENDMENIITEM). The “XXXXX” is the name of the menu item. For example, if you define a menu item “TEST”, give it the name “TESTITEM” and append it to the Window menu, the command would be APPENDMENUITEM “WINDOW “TEST “TESTITEM, and the corresponding event name would be “MENU.TESTITEM”. Note that if you define an event procedure to handle menu selections, its name is “HANDLE.MENU”, and its input is the name of the selected menu item.
weblogo/ideas.txt · Last modified: 2019/01/22 06:09 (external edit)