Return-Path: <oster%ucblapis@BERKELEY.EDU>
Received: from ucbvax.berkeley.edu by SUMEX-AIM.ARPA with TCP; Mon 10 Mar 86 00:45:05-PST
Received: by ucbvax.berkeley.edu (5.45/1.9)
	id AA19777; Mon, 10 Mar 86 00:10:49 PST
Received: from ucblapis.Berkeley.Edu (ucblapis.ARPA)
	by ucbjade.Berkeley.Edu (4.19/4.41.3)
	id AA00206; Sun, 9 Mar 86 23:18:45 pst
Received: by ucblapis.Berkeley.Edu (4.19/4.41)
	id AA09220; Sun, 9 Mar 86 17:13:31 pst
Date: Sun, 9 Mar 86 17:13:31 pst
From: oster%ucblapis@BERKELEY.EDU (David Phillip Oster)
Message-Id: <8603100113.AA09220@ucblapis.Berkeley.Edu>
To: info-mac@sumex-aim.arpa
Subject: How to tell a double click.

Here is the T.M.L. Pascal procedure I've written to tell if a given
mouseDown eventrecord is actually the first click of a double click.
There are a couple of tricky points:

1.) The user gets to set the DoubleClick time threshold from the control
panel.  It is up to us to respect it.

2.) You must arrange to return as soon as you know that a given
eventRecord is NOT the first click of a double click - if you always
wait for the doubleClick time to expire, the application will seem sluggish.

3.) You have to allow for the mouse to move a little while the user is 
doubleClicking (but not too much.)

{ --- Cut Here --- }
{ ******************************************************************************* }
{+++ 
Wrap a toolbox procedure in a layer to make it
  a function returning a useful value: LocalToGlobal
Convert a point from the current window's coordinates to screen coordinates.
Author: David Phillip Oster
Date: 1/6/86
+++}
FUNCTION LocToGlob(p : Point) : Point;
BEGIN
  LocalToGlobal(p);
  LocToGlob := p;
END;
{ ******************************************************************************* }
{+++ 
Wrap a toolbox procedure in a layer to make it
  a function returning a useful value: GetMouse
return the mouse's position in local coordinates
Author: David Phillip Oster
Date: 1/6/86
+++}
FUNCTION MousePt : Point;
VAR p : Point;
BEGIN
  GetMouse(p);
  MousePt := p;
END;
{ ******************************************************************************* }
{+++ Calaculates on rectangles and points 
CenterRectPt takes a rectangle and a pt and centers the rect 
	with respect to the pt
Author: David Phillip Oster
Date: 1/6/86
+++}
FUNCTION CenterRectPt(theRect : Rect; thePt : Point ) : Rect;
VAR newCorn : Point;
  i : VHSelect;
BEGIN
  FOR i := v TO h DO 
    newCorn.vh[i] := thePt.vh[i] -
    	((theRect.botRight.vh[i] - theRect.topleft.vh[i]) div 2);
  OffsetRect(theRect, newCorn.h, newCorn.v);
  CenterRectPt := theRect;
END;
{ ******************************************************************************* }
{+++ WasDoubleClick - call with the event record from a mouseDown event.
check for a second mouse down within DblTime time, and within 
	8 pixels.  If such an event exists, remove it and 
	return true otherwise, return false 
Author: David Phillip Oster
Date: 1/6/86
+++}
FUNCTION WasDoubleClick(VAR myEvent : EventRecord) : Boolean;
TYPE
  LongPtr = ^ LongInt;
VAR
  DblTime : LongPtr;
  clickRect : Rect;
  dnTime : LongInt;
  dnEvent : EventRecord;
  dontCare : Boolean;
BEGIN
  WasDoubleClick := FALSE;
  DblTime := LongPtr(POINTER($2F0));	{ get the user's doubletime threshold }
  dnTime := myEvent.when + DblTime^;	{ only wait until dnTime for second event }	
  SetRect(clickRect, 0,0,12,12);
  clickRect := CenterRectPt(clickRect, myEvent.where);
  	{ +++ wait for the second event, leave loop as soon as we can +++ }
  WHILE (TickCount < dnTime) AND
  	PtInRect(LocToGlob(MousePt), clickRect) AND
  	NOT EventAvail(mDownMask,dnEvent) DO 
    { nothing } ;
  { +++ waited long enough, is there a second mouse down? +++ }
  IF EventAvail(mDownMask,dnEvent) THEN BEGIN
    IF PtInRect(dnEvent.where, clickRect) THEN BEGIN
		{ +++ we know GetNextEvent will return true +++ }
      WasDoubleClick := GetNextEvent(mDownMask,dnEvent);
    END;
  END;
END;
{ --- Cut Here --- }
This code would be much more elegant in C, because I could return 0; as
soon as I knew that this particular event wasn't a doubleCLick, but it is
okay in Pascal.

I hope this helps.  (I also do a much nicer double-click on title-bar of
window goes to full screen and back than the new Mac Roms do.)
---David Phillip Oster
---------------------  ``What do you look like when you aren't visualizing?''
Arpa: oster@lapis.berkeley.edu
Uucp: ucbvax!ucblapis!oster
