awd@dbase.UUCP (Alastair Dallas) (06/27/89)
It occurred to me that the following simple function might be interesting to the net. The first version was considerably longer and it got polished down to this, so I thought I'd invite the net to critique it and help _really_ polish it. I have a fondness for "lapidary code." Boolean TrackButton(button) Rect *button; { Boolean wasIN = FALSE; Point mouse; while (StillDown()) { GetMouse(&mouse); if (PtInRect(mouse, button) != wasIN) { InvertRect(button); wasIN = !wasIN; } } if (wasIN) InvertRect(button); return (wasIN); } /* TrackButton */ This does the job using THINK C v3.0. I'd be interested to hear of any language incompatibilities, etc. that would make it non-portable. Also, the various toolbox routines that Track.. things usually take an initial point as an argument--why is this? Finally, any thoughts about how to make the button flash before returning TRUE? My current solution (not shown) is pretty crude and I'd like to be more Mac-family-clean (isn't there a parameter RAM setting or something?) By the way, I'm not missing something obvious, am I? I mean, the Control Manager seems like a lot of overkill to handle a simple (and custom) button or two. Should I write a CDEF for this? Anyway. Comments are welcome... /alastair/
awd@dbase.UUCP (Alastair Dallas) (06/27/89)
I posted the TrackButton() function without a disclaimer. This was a really stupid thing to do, because not everyone knows that I write IBM PC code for Ashton-Tate and that Mac programming is a sideline/hobby for me. Therefore, the code and discussion in the previous posting were mine: my code, my opinions, my discussion. I'm not publishing Ashton-Tate code on the net (just call me the nuProtagonist :-), and in fact Ashton-Tate is not involved with the previous posting whatsoever. Thank you. /alastair/
jmunkki@kampi.hut.fi (Juri Munkki) (06/27/89)
In article <128@dbase.UUCP> awd@dbase.UUCP (Alastair Dallas) writes: <Boolean TrackButton(button) <Rect *button; <{ < Boolean wasIN = FALSE; < Point mouse; < while (StillDown()) < { GetMouse(&mouse); < if (PtInRect(mouse, button) != wasIN) < { InvertRect(button); < wasIN = !wasIN; < } < } < if (wasIN) InvertRect(button); < return (wasIN); <} /* TrackButton */ <By the way, I'm not missing something obvious, am I? I mean, the Control <Manager seems like a lot of overkill to handle a simple (and custom) <button or two. Should I write a CDEF for this? Comments are welcome... What if the user quickly presses and releases the mouse button on the control and then moves the mouse away from the button area. Your routine does not detect this. You should use GetNextEvent to find when the button comes up and where it comes up. Since GetNextEvent returns the mouse location, you can remove the GetMouse too. Your code is not compatible with Quickeys. I used to program this way (take a look at my Mandelbrot DA source), but discovered that since it does not depend on mouseUp events, it doesn't work with QuicKeys. _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
lsr@Apple.COM (Larry Rosenstein) (06/28/89)
In article <23239@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes: > What if the user quickly presses and releases the mouse button on the > control and then moves the mouse away from the button area. Your routine > does not detect this. You should use GetNextEvent to find when the button The example code called StillDown which seems to be the right thing to do. StillDown returns FALSE if the event queue contains a mouseUp event, which would handle the case you describe. (You can also call WaitMouseUp, which does the same thing and removes the mouseUp from the event queue.) Perhaps you can elaborate on why this does not work with QuicKeys; the code does take into account mouseUp events. > comes up and where it comes up. Since GetNextEvent returns the mouse > location, you can remove the GetMouse too. But you would have to add a call to GlobalToLocal because GetNextEvent returns global coordinates and GetMouse returns local coordinates. Larry Rosenstein, Apple Computer, Inc. Object Specialist Internet: lsr@Apple.com UUCP: {nsc, sun}!apple!lsr AppleLink: Rosenstein1
jmunkki@kampi.hut.fi (Juri Munkki) (06/28/89)
In article <2509@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes: >In article <23239@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes: >> What if the user quickly presses and releases the mouse button on the >> control and then moves the mouse away from the button area. Your routine >> does not detect this. You should use GetNextEvent to find when the button > >The example code called StillDown which seems to be the right thing to do. > StillDown returns FALSE if the event queue contains a mouseUp event, >which would handle the case you describe. (You can also call WaitMouseUp, >which does the same thing and removes the mouseUp from the event queue.) You still get the wrong mouse coordinates if you use stilldown/getmouse. With GetNextEvent you get the coordinate where the mouseup happened. GetMouse just tells you the current mouse locations. These are not the same thing. >Perhaps you can elaborate on why this does not work with QuicKeys; the >code does take into account mouseUp events. Ok. Here's the code I used in my Mandelbrot DA. /* A general purpose pseudo-button ** handler. Give it a rect and it ** handles the rectangle as a button ** and returns true if the button was ** hit. */ int ClickRect(box) Rect *box; { register int hilited=0,where; Point spot; while(StillDown()) { GetMouse(&spot); where=PtInRect(spot,box); if(where!=hilited) { hilited=where; InvertRect(box); } } if(hilited) InvertRect(box); return hilited; } Now take a look at the code that was posted. There are some very minor differences, but basically it's the same program. I don't know how QuicKeys is supposed to work, but defining a click in the box does not produce the expected results. _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
jmunkki@kampi.hut.fi (Juri Munkki) (06/28/89)
In article <2509@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes: >Perhaps you can elaborate on why this does not work with QuicKeys; the >code does take into account mouseUp events. It took some writing to find this out and even then I can only guess at what happens. The assumptions I make here are based on the following code fragment and quickeys behavior with it: int ClickRect(box) Rect *box; { EventRecord myEvent; register int hilited=0,where; do { GetNextEvent(mUpMask,&myEvent); GlobalToLocal(&myEvent.where); where=PtInRect(myEvent.where,box); if(where!=hilited) { hilited=where; InvertRect(box); } } while(myEvent.what!=mouseUp); if(hilited) InvertRect(box); return hilited; } What happens is that the mouseup is never detected. You have to click somewhere outside the "button" to release the control. If you define the click so that the mouse moves even a single pixel, both versions will work. Neither works if the mouse doesn't move. I assume that quickeys doesn't bother to post a mouseup if the mouse position doesn't change. (I'd call that a bug.) The above code is still preferable because it handles event buffering correctly. You can click on buttons while a program is calculating and the program will behave correctly. IM-I-36: >The system provides a "mouse-ahead"; that is, any mouse actions the user >performs when the application isn't ready to process them are saved in a >buffer and can be processed at the apllication's convenience. Alternatively, >the application can choose to ignore saved-up mouse actions, but should do >so only to protect the user from possibly damaging consequences. _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
isle@eleazar.dartmouth.edu (Ken Hancock) (07/03/89)
In article <23257@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
:>
:>Ok. Here's the code I used in my Mandelbrot DA.
:>
:>/* A general purpose pseudo-button
:>** handler. Give it a rect and it
:>** handles the rectangle as a button
:>** and returns true if the button was
:>** hit.
:>*/
:>int ClickRect(box)
:>Rect *box;
:>{
:>register int hilited=0,where;
:> Point spot;
:>
:> while(StillDown())
:> { GetMouse(&spot);
:> where=PtInRect(spot,box);
:> if(where!=hilited)
:> { hilited=where;
:> InvertRect(box);
:> }
:> }
:> if(hilited) InvertRect(box);
:>
:> return hilited;
:>}
Technically, you should force an invert first since the mouse may
be up by the time you arrive at your tracking routine...
Ken
Ken Hancock '90 | BITNET/UUCP/
Personal Computing Ctr Consultant | INTERNET: isle@eleazar.dartmouth.edu
-----------------------------------+----------------------------------------
DISCLAIMER? I don't get paid enough to worry about disclaimers.