User:Raul Miller/J Event Handlers

From J Wiki
Jump to navigation Jump to search

The information presented below is outdated.

Guides/Window Driver/Window Driver Overview covers much of what was presented here, in a more up-to-date fashion.

If you notice significant omissions there, please let me know.

Also possibly relevant, for working with J's Qt based implementation of its wd subsystem is Guides/Window Driver/Websocket as well as more general background:

(Also, you might consider donating time, money and/or informed and pertinent questions to the site.)

Outdated (J6) content follows:

J602's .ijs editor has a form editor which can add event handlers to a form or one of its controls (the "Code" menu option).

I am going to use FORM and CONTROL to represent my form name and control name, here.

FORM_handler, if present, would prevent any other event handler from running (unless your implementation of this event handler delegated properly). If you are trying to close your form's window, and you have a buggy implementation of this handler, you can temporarly redefine FORM_handler to do wd'pclose'. Or you could just erase FORM_handler if you have defined a good FORM_close.

FORM_default and FORM_CONTROL_char, if present, would prevent any "fkey" event handler from running and will also intercept character events which represent normal text entry. FORM_CONTROL_char takes precedence over FORM_default.

The real top-level event handler seems to be wdhandler which has a default implementation in J's z locale. This standard implementation basically works like this:

   wdq=: wd'q'
   ({."1 wdq)=: wd_val=. {:"1 wdq
   wd_fn=. >{.(#~ 3 = 4!:0) 3{.wd_val
   if. 0<#wd_fn do.
   i.0 0

In other words, it defines wdq and the "sys" value and optionally runs an event handler. The actual implementation has some additional code for debugging (especially for when suspension is disabled), and for WINCE, but this is the essence of it.

The first three rows in wdq are syshandler (always FORM_handler), sysevent (varies) and sysdefault (always FORM_default).

wdq is a two column table of boxed character lists (so numeric values are represented textually -- use ". to parse them):

syshandler FORM_handler
sysevent see above
sysdefault FORM_default
sysparent FORM (name of form)
syschild CONTROL (name of control issuing event, or blank if none)
systype name of event
syslocalep FORM's locale
syslocalec CONTROL's locale? usually blank
syshwndp FORM's numeric handle
syshwndc CONTROL's numeric handle
sysfocus CONTROL (name of control with focus, or blank if none)
syslastfocus name of previous control

Usually, syschild and sysfocus are the same, but not for synthetic events (fkey events name the "fkey" in syschild, and the close event names "close" in syschild).

Mouse and keyboard events tend to also have sysdata and sysmodifiers.

sysmodifiers is (the decimal representation of) a small integer which represents which modifier keys were pressed. You can get their status using

   'ALT XX CONTROL SHIFT'=:2 2 2 2#:".sysmodifiers

In other words: 1 for the shift key, 2 for control and 8 for alt. I don't know what 4 would mean.

sysdata is the text represented by a key, a sequence of numbers for a mouse event, and missing (whatever the previous value was, if we are looking at the variable instead of using wdq directly) for fkey events.

For mouse events, you can use

   'mx my cw ch bl br kc ks bm b4 b5 mw'=. 0".sysdata
}}}in the form's locale.  The notation I am using here is
mx mouse x location (left side of control is 0)
my mouse y location (top of control is 0)
cw control width (maximum x value)
ch control height (maximum y value)
bl left mouse button is down
br right mouse button is down
kc control key is down
ks shift key is down
bm middle mouse button is down
b4 does nothing for me
b5 does nothing for me
mw mouse wheel (1: up, _1: down)

Note that the above only documents form and control event handlers, and that J also supports some other kinds of event handlers.