Thank you all, esp. John, for an excellent set of responses to my question.
I had assumed that we would need to write a handler that walked through our
objects and did rectangle hit-testing, and you all confirmed that to be the
case.  

I'm thinking that we want to write a "better FrmDispatch" that tests for
our own gadgets as well as the built in ones (by calling FrmDispatch), and
hides the whole thing from the rest of our program. As I recall, we used to
do something like this under MS Windows when we had to deal with
monstrosities like modeless dialogs.

This group is an amazing resource! Thanks!

Glenn


At 10:05 AM 11/18/99 -0800, you wrote:
>Glenn asks how we hide (or abstract, if you want to be more computer-science
>like) the behavior of gadgets the way Fields and other built-in interface
>elements do it. It's not magic, that's for sure ;)
>
>The answer is, use the same technique that Palm does. If that's enough for
>you, stop here. Long and detailed explanation below:
>
>When you use forms, you register a form event handler by calling 
>
>FrmSetEventHandler(frmP, MyFormHandleEvent);
>
>Then you open the form...
>
>Looking at a typical event loop, we see:
>
>do {   
>       EvtGetEvent(&event, evtWaitForever); 
>       if (! SysHandleEvent(&event))
>               if (! MenuHandleEvent(0, &event, &error))
>                       if (! ApplicationHandleEvent(&event))
>                               FrmDispatchEvent(&event);
>} while (event.eType != appStopEvent);
>
>So for each event, lots of functions may take a look and see if they are
>interested. The FrmDispatchEvent() function is where low-level pen taps
>within interface elements are handled or translated into higher-level
>events. Here's what's happening (in general based on my understanding of How
>Computers Work, not from Palm OS source code -- you'll need to get the Palm
>OS source to see *exactly* what's happening!)
>
>Boolean FrmDispatchEvent(EventTypePtr eventP) {
>       // based on event x & y location, figure out which, if any,
>interface element the event belongs to
>
>       Word numObjs = FrmGetNumberOfObjects (frm);
>       for (i = 0; i < numObjs; i++) {
>               // check each object until one is found where event x/y is
>inside bounds
>               if (CheckBounds(frm, i, eventP)) { // OK, I made this
>function up, but you get the idea 
>                       // call the object event handler, based on its type
>                       switch (FrmGetObjectType (frm, i) {
>                       case frmFieldObj:
>                               return FldHandleEvent(FrmGetObjectPtr
>(frm,i), eventP)
>                       case frmControlObj:
>                               return CtlHandleEvent(FrmGetObjectPtr
>(frm,i), eventP)
>                       case // you get the idea!
>                       }
>               }
>       }
>       // no match? call the registered form handler fn
>       return frm->handler(event);
>}
>
>All the "dispatch" fn does is check every object in the form to see if it is
>interested in the event. If it is, then the event is handled and processing
>of that event stops. Check the docs, and you'll see for every interface
>object there is a xxxHandleEvent() function. That's what they're for.
>Sometimes these handlers will handle one or more low-level event (pen
>down/pen up) and create a new event (CtlSelectEvent) which is inserted into
>the event queue. This is from the PalmOS docs:
>
>"ctlSelectEvent
>The control routine CtlHandleEvent sends this event. When
>CtlHandleEvent receives a ctlEnterEvent, it tracks the pen
>until the pen is lifted. If the pen is lifted within the bounds of the
>same control it went down in, a cltSelectEvent is added to the
>event queue; if not, a ctlExitEvent is added to the event queue."
>
>Reading the ctlEnterEvent description, we see that the CtlHandleEvent sends
>this one when it handles a penDownEvent in its bounds. So, the user puts the
>pen down in a control, and this happens:
>
>penDownEvent is received in the event loop, and eventually passed to
>FrmDispatchEvent(), where it is sent to the correct control's
>CtlHandleEvent(). That handler creates a new event named ctlEnterEvent and
>adds it to the event queue. 
>
>ctlEnterEvent is received in the event loop, and eventually passed to
>FrmDispatchEvent(), where it is sent to the correct control's
>CtlHandleEvent(). That handler tracks events until a penUpEvent is received,
>and then it either adds a ctlSelectEvent or ctlExitEvent to the event queue.
>let's say it adds a ctlSelectEvent.
>
>ctlSelectEvent is received in the event loop, and eventually passed to
>FrmDispatchEvent(), where it is not handled by any of the object handlers...
>so your registered form event handler is finally called with it!
>
>That's not exactly magic... but it sure does hide a lot of complexity from
>you when you're writing apps.
>
>
>If you want to mimic this behavior in your form handler, you'll need to
>write a myGadgetHandleEvent() fn. That function would do whatever processing
>you want, including possibly generating new user-defined events for you.
>Your form event handler would then look something like this:
>
>Boolean myFormEventHandler(EventPtr eventp) {
>Boolean handled;
>
>       handled = myGadgetDispatchEvent(eventp);
>
>       if (handled) return handled;
>
>       switch (eventP->eType) {
>       case MyGadgetSelect:    // or some other user-defined event type...
>               // handle high-level event here
>       case // etc.
>       }
>       return false;
>}
>
>Your myGadgetDispatchEvent() fn would look in the current form for gadgets,
>and for each gadget found would check to see if the event is in its bounds.
>If it is, then you'd process the event (possibly adding new events to the
>event queue), and return true/false as appropriate. You could do that in the
>myGadgetHandleEvent() function, if you really want to mimic the PalmOS
>design.
>
>As they say, it's all in the book ;)
>
>NOTE: In PalmOS 3.5, you can register a callback for a gadget. That callback
>is called during the FrmDispatchEvent() processing if an event falls inside
>the bounds of a gadget, so you no longer have to figure out *which* gadget
>got tapped. In essence, you just need to write a myGadgetHandleEvent() for
>your gadget, and you get rid of the myGadgetDispatchEvent() function I
>describe above.
>
> ==-
>John Schettino author of
>Palm OS Programming For Dummies, http://schettino.tripod.com
>
>
>-----Original Message-----
>Subject: Gadgets and events - followup question
>From: Glenn Bachmann
>A followup to Pete Angiuoli's question on gadgets:
>
>I think I understand that if I put an input field on a form, that the form
>handler does not "see" low-level events such as pen up/down. Through some
>magic, they get routed directly to the input field, and handled by code in
>the Palm OS handler for input fields. There is no special routing that the
>form handler has to do to say to the input field that a pen was tapped.
>
>I think I also understand that if I write a gadget, that it does not
>magically receive events that happen within its client area rectangle, it
>is the responsibility of the parent form to figure out that a pen down that
>happened at coordinates 100,50 should be handled by the gadget at that
>location. So I wind up with code in my form handler that looks like this:
>
>-Get a pen event
>-Determine the location of the pen tap
>-Figure out if there is a custom gadget that is "underneath" that x/y
>location
>-Hand the event to some piece of code that is responsible for handling a
>pendown in the context of the gadget (ex. change the cursor position).
>
>You can see where this becomes unwieldy if, say, I've written a "super
>input field" gadget, and I've got 16 of them on my form. 
>
>So my question is, how is it that pen events and such are automatically
>routed to the "built-in" UI elements? Is there a way for my own "custom
>gadgets" to participate in this mechanism, such that my parent form handler
>logic does not have to manually route these events? Under windows, because
>of the parent-child relationship of windows, this is automatically handled
>by the UI element that "has the focus". 
>
>Assuming I'm not just hopelessly confused, any insight on this would be
>helpful to us.
>
>Thanks!
>
>
>Glenn Bachmann
>Bachmann Software and Services, LLC
>http://www.bachmannsoftware.com
>Software for Handheld & Wireless Computing, Windows and the Internet
>Authors of "Palm Programming", published by Macmillan/Sams, and home of
>Bachmann Print Manager, the only graphical printing solution for the Palm
>Computing Platform
> 
Glenn Bachmann
Bachmann Software and Services, LLC
http://www.bachmannsoftware.com
Software for Handheld & Wireless Computing, Windows and the Internet
Authors of "Palm Programming", published by Macmillan/Sams, and home of
Bachmann Print Manager, the only graphical printing solution for the Palm
Computing Platform

Reply via email to