[comp.sys.mac.programmer] Double Clicking

lippin@wheatena.berkeley.edu (The Apathist) (08/16/88)

A double click occurs when a mouseDown event follows a mouseUp event
and they are sufficiently close in both space and time.  "Sufficiently
close" in space is application dependent; IM recommends five pixels
for graphics, and on the same character boundary for text.
"Sufficiently close" in time is returned by the call GetDblTime.

Thus, to handle double clicks, you should do something like this:

On mouseUp events, record the time and place that they occur.

On mouseDown events, compare the time and place to the last mouseUp.
If they are close enough, do your double click thing, otherwise, treat
it as a single click.  If your single click routine handles dragging,
it should use StillDown, not WaitMouseUp.

Note that with this algorithm, a double click is treated as an add-on
to a single click.  This is usually appropriate, as a double click
should be a semantic extension of a single click.  If you don't want
this, you'll have to either wait around after clicks to make sure they
aren't double (which can be sluggish), or undo the single click when
the second click comes in (which may be more difficult to program).

					--Tom Lippincott
					..ucbvax!math!lippin

	"Thank you for observing all saftey precautions."
					--Dark Star

mikeoro@hubcap.UUCP (Michael K O'Rourke) (02/17/89)

A couple months ago, someone posted some example code to detect a double click.
Does anyone have that code? I saved it but seem to have "misplaced" it. What
I want to do is detect a double click in the title bar of a window.

Michael O'Rourke

beard@ux1.lbl.gov (Patrick C Beard) (02/24/89)

In article <4452@hubcap.UUCP> mikeoro@hubcap.UUCP (Michael K O'Rourke) writes:
>A couple months ago, someone posted some example code to detect a double click.
>I want to detect a double click in the title bar of a window.

The easiest way to detect a double click is to save the time of each mouse
down event in some variable, say lastClickTime.  To detect if the next click
should be interpreted as a double click, subtract this time from the time
of the next click and compare it to the result of  the GetDblTime() trap.

i.e.:

	long lastClickTime=0;
	.
	.
	.
	/* assume we've been keeping track of lastClickTime... */
	if(event.what==mouseDown) {
		if(event.when-lastClickTime<=GetDblTime()) {
			ProcessDoubleClicks();
			lastClickTime=0;	/* reset it */
		} else
			lastClickTime=event.when;
	}

Hope that helps.

+----------------------------------------------------------------+
 \   Patrick Beard                 "Badges?                       \
  \    Berkeley Systems              I ain't got to show you...    \
   \      PCBeard@lbl.gov                 ...NO STINKING BADGES!"   \
    + ---------------------------------------------------------------+

wiechman@athos.rutgers.edu (NightMeower) (02/24/89)

In article <1967@helios.ee.lbl.gov> beard@ux1.lbl.gov (Patrick C Beard) writes:

> In article <4452@hubcap.UUCP> mikeoro@hubcap.UUCP (Michael K O'Rourke) writes:
> >A couple months ago, someone posted some example code to detect a double click.
> The easiest way to detect a double click is to save the time of each mouse
> down event in some variable, say lastClickTime.  To detect if the next click
> should be interpreted as a double click, subtract this time from the time
> of the next click and compare it to the result of  the GetDblTime() trap.


You should be using the information stored from the Mouse CDEV in some
way because it allows the double click speed to be user defined.

Also, you'll want to compare the mouse locations to see if they are
sufficiently close together.  Consider a user doing fast but detailed
work.  Two clicks very close together in time, but far apart in
location could be misinterpretted as a double click.



Kevin
-- 
===========================================================================
Kevin S. Wiechmann			arpa:  wiechman@rutgers.rutgers.edu

	 This is only a test... for the next sixty seconds...

lippin@purina.berkeley.edu (The Apathist) (02/25/89)

Recently beard@ux1.lbl.gov (Patrick C Beard) wrote:
>The easiest way to detect a double click is to save the time of each mouse
>down event in some variable, say lastClickTime.  To detect if the next click
>should be interpreted as a double click, subtract this time from the time
>of the next click and compare it to the result of  the GetDblTime() trap.

Close, but no cigar -- the "standard double click" is a
mouseDown-Up-Down sequence with less than GetDblTime() ticks between
the mouseUp and the final mouseDown, and with the two mouseDowns
close, in some semantically defined sense.  In other words, save the
time of the mouseUp event, not the mouseDown event.

In the example that started this, double clicking in the title bar of
a window (yucko!), I suspect a difficulty in that DragWindow will
swallow the mouseUp.  In that case, you might want to use the
difference between the mouseDown times, but comparing that to
2*GetDblTime() to give a more standard feel.  The definition of
"close" in this context is likely "still in the title bar."

					--Tom Lippincott
					  lippin@math.berkeley.edu

	"You have no power here.  Now begone, before someone
		drops a house on you, too!"	--Glinda

tom@iconsys.UUCP (Tom Kimpton) (02/25/89)

In article <1967@helios.ee.lbl.gov> beard@ux1.lbl.gov (Patrick C Beard) writes:
>In article <4452@hubcap.UUCP> mikeoro@hubcap.UUCP (Michael K O'Rourke) writes:
>>A couple months ago, someone posted some example code to detect a double click.
>>I want to detect a double click in the title bar of a window.
>
>The easiest way to detect a double click is to save the time of each mouse
>down event in some variable, say lastClickTime.  To detect if the next click
>should be interpreted as a double click, subtract this time from the time
>of the next click and compare it to the result of  the GetDblTime() trap.
>
>i.e.:
>
>	long lastClickTime=0;
>	.
>	.
>	.
>	/* assume we've been keeping track of lastClickTime... */
>	if(event.what==mouseDown) {
>		if(event.when-lastClickTime<=GetDblTime()) {
>			ProcessDoubleClicks();
>			lastClickTime=0;	/* reset it */
>		} else
>			lastClickTime=event.when;
>	}
>
>Hope that helps.
>
	As well you would want to keep the location of the last click and
check to see if both it and the current location are in an appropriate
selection rectangle.

F
o
d
d
e
r



F
o
d
d
e
r



F
o
d
d
e
r


-- 
Tom Kimpton                    UUCP: {uunet,caeco,nrc-ut}!iconsys!tom
Software Development Engineer  ARPANET: icon%byuadam.bitnet@cunyvm.cuny.edu
Icon International, Inc.       BITNET: icon%byuadam.bitnet (multi-user acct)
Orem, Utah 84058               PHONE: (801) 225-6888

trebor@biar.UUCP (Robert J Woodhead) (02/25/89)

In article <Feb.24.08.37.59.1989.6111@athos.rutgers.edu> wiechman@athos.rutgers.edu (NightMeower) writes:
>Also, you'll want to compare the mouse locations to see if they are
>sufficiently close together.  Consider a user doing fast but detailed
>work.  Two clicks very close together in time, but far apart in
>location could be misinterpretted as a double click.

Very true.  In general, the double click "heuristic" is:

if (curTime-lastClickTime)<maxDoubleClickTime then
  if object_clicked_on = last_object_clicked_on then
     double_click(object_clicked_on);

As mentioned, it's VERY important that you ensure that the two clicks are
not only temporally close but SEMANTICALLY close; an example of an app that
does not do this in the current release is Compuserve Navigator when you are
selecting threads to retrieve -- if you click on an item and then click on
another item quickly, it thinks you double clicked on the second item; this
is disconcerting.

+---------------------------------------------------------------------------+
| Robert J Woodhead      !uunet!cornell!biar!trebor     CompuServe 72447,37 |
| Biar Games, Inc., 10 Spruce Lane, Ithaca NY 14850  607-257-1708,3864(fax) |
+---------------------------------------------------------------------------+
| Games written, Viruses killed   "I'm the head honcho of this here spread; |
| While U Wait.  Take a number.    I don't need no stinking disclaimers!!!" |
+---------------------------------------------------------------------------+

ech@pegasus.ATT.COM (Edward C Horvath) (02/26/89)

From article <1967@helios.ee.lbl.gov>, by beard@ux1.lbl.gov (Patrick C Beard):

> The easiest way to detect a double click is to save the time of each mouse
> down event...compare [the difference] to the result of the GetDblTime() trap.

A subtlety: ordinarily you would start the doubleTime clock on a mouse UP,
and stop it on a mouse DOWN.

=Ned Horvath=

osborn@ux1.lbl.gov (James R Osborn) (03/03/89)

In article <20846@agate.BERKELEY.EDU> lippin@math.berkeley.edu writes:
>Recently beard@ux1.lbl.gov (Patrick C Beard) wrote:
>>The easiest way to detect a double click is to save the time of each mouse
>>down event in some variable, say lastClickTime.  To detect if the next click
>>should be interpreted as a double click, subtract this time from the time
>>of the next click and compare it to the result of  the GetDblTime() trap.
>
>Close, but no cigar -- the "standard double click" is a
>mouseDown-Up-Down sequence with less than GetDblTime() ticks between
>the mouseUp and the final mouseDown, and with the two mouseDowns
>close, in some semantically defined sense.  In other words, save the
>time of the mouseUp event, not the mouseDown event.
>
>In the example that started this, double clicking in the title bar of
>a window (yucko!), I suspect a difficulty in that DragWindow will
>swallow the mouseUp.  In that case, you might want to use the
>difference between the mouseDown times, but comparing that to
>2*GetDblTime() to give a more standard feel.  The definition of
>"close" in this context is likely "still in the title bar."
>
>					--Tom Lippincott
>					  lippin@math.berkeley.edu


I just performed a small experiment regarding Mr. Lippincott's theory as to
what a double-click is composed of.  Try this:

Make sure the Title Click attribute is set in the 'LAYO' resource of your
finder.  This allows you to double-click in the title bar of an open window
in the finder to open its parent.  In other words if you have a folder open
whose parent (a folder or a disk) is closed (or just not the active window),
then double-clicking will open the parent or bring it to the front.

O.K. Now do this...down click in a window's title bar and hold it for a few
seconds and then quickly up click down click and then release.  You will find
that nothing happens.  If you instead quickly down click up click down click
and then hold it (ie - don't release the mouse on the final click), you will
find that the parent is opened while you are still holding the mouse down.

These observations give evidence to Patrick Beard's theory that a double-click
is timed between mouse downs and NOT between the intervening mouse up and the
final mouse down as Mr. Lippincott suggests.  However, dutiful reading about
the GetDblTime() trap (I.M. Vol. I page 260) enlightens one with knowledge
in agreement with Mr. Lippencott's beliefs.  This suggest that he is correct
as to the way in which title bar double-clicks ought to be implemented.  Since
this feature works quite well in the finder, it must me possible.  I think
Mr. Lippencott is correct as to how it should be done.


James R. Osborn
Lawrence Berkeley Laboratory
osborn@ux1.lbl.gov