zoo@aps1.spa.umn.edu (david d [zoo] zuhn) (11/27/90)
Howdy. I'm trying to write an application that needs to be able to distinguish between single clicks and double clicks of a mouse button. I am using XView 2, and this processing will be in the event procedure of a canvas. Does anyone have sample code for this? Thanks. david d [zoo] zuhn Univ. of Minnesota Dept. of Astronomy zoo@aps1.spa.umn.edu Automated Plate Scanner Project
kasso@aha.Eng.Sun.COM (Chris Kasso) (12/06/90)
In article <ZOO.90Nov26201641@grumpy.spa.umn.edu> zoo@aps1.spa.umn.edu writes: >Howdy. I'm trying to write an application that needs to be able to >distinguish between single clicks and double clicks of a mouse button. >I am using XView 2, and this processing will be in the event procedure >of a canvas. > >Does anyone have sample code for this? Thanks. > >david d [zoo] zuhn Univ. of Minnesota Dept. of Astronomy >zoo@aps1.spa.umn.edu Automated Plate Scanner Project You probably want to use an interval timer to distinguish between double and single clicks of the mouse. Here's some code that should do what you want: #include <stdio.h> #include <xview/xview.h> #include <xview/canvas.h> #include <xview/notify.h> short buttonState; main(argc,argv) int argc; char *argv[]; { void EventProc(); Xv_server server; Frame frame; Canvas canvas; server = xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL); frame = xv_create(NULL, FRAME, XV_LABEL, "XView Example", XV_X, 200, XV_Y, 200, XV_WIDTH, 200, XV_HEIGHT, 200, NULL); canvas = xv_create(frame, CANVAS, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, WIN_EXTEND_TO_EDGE, NULL); xv_set(canvas_paint_window(canvas), WIN_EVENT_PROC, EventProc, WIN_CONSUME_EVENTS, WIN_MOUSE_BUTTONS, WIN_RESIZE, WIN_REPAINT, NULL, NULL); buttonState = 0; window_fit(frame); xv_main_loop(frame); } void EventProc(window, event) Xv_Window window; Event *event; { switch (event_action(event)) { case ACTION_SELECT: if (event_is_down(event)) { struct itimerval timer; void ButtonTimer(); if (!buttonState) { timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 200000; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; notify_set_itimer_func(window, ButtonTimer, ITIMER_REAL, &timer, NULL); buttonState = 1; } else { /* * Second button press happened before the timeout, this must * be a double click. */ notify_set_itimer_func(window, NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL); fprintf (stderr, "Double-Click on ACTION_SELECT\n"); buttonState = 0; } } break; case ACTION_ADJUST: if (event_is_down(event)) fprintf (stderr, "ACTION_ADJUST (down)\n"); else fprintf (stderr, "ACTION_ADJUST (up)\n"); break; case ACTION_MENU: if (event_is_down(event)) fprintf (stderr, "ACTION_MENU (down)\n"); else fprintf (stderr, "ACTION_MENU (up)\n"); break; case WIN_REPAINT: fprintf (stderr, "WIN_REPAINT\n"); break; case WIN_RESIZE: fprintf (stderr, "WIN_RESIZE\n"); break; } } void ButtonTimer(client, which) Notify_client client; int which; { /* * Timeout happened before the second button press. This is a * single click. */ notify_set_itimer_func(client, NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL); fprintf (stderr, "Single-Click on ACTION_SELECT\n"); buttonState = 0; } -- Chris Kasso Internet: kasso@Eng.Sun.COM Windows and Graphics Software uucp: {...}!sun!kasso Sun Microsystems, Inc.
jcb@frisbee.Eng.Sun.COM (Jim Becker) (12/07/90)
In comp.windows.open-look Chris Kasso writes: In article <ZOO.90Nov26201641@grumpy.spa.umn.edu> zoo@aps1.spa.umn.edu writes: >Howdy. I'm trying to write an application that needs to be able to >distinguish between single clicks and double clicks of a mouse button. >I am using XView 2, and this processing will be in the event procedure >of a canvas. > >Does anyone have sample code for this? Thanks. > >david d [zoo] zuhn Univ. of Minnesota Dept. of Astronomy >zoo@aps1.spa.umn.edu Automated Plate Scanner Project You probably want to use an interval timer to distinguish between double and single clicks of the mouse. Here's some code that should do what you want: An easier method is simply to retain the `time' field in the XButtonEvent associated with the last ACTION_SELECT event. Then the `time' field associated with the next XButtonEvent in the following ACTION_SELECT can be tested in terms of the double click timing threshhold. Here's some snippets of code: /* * this does the check for multiclick and returns boolean */ static int txt_is_multiclick( textsw, tline, tindex ) Textob *textsw; int tline, tindex; { XButtonEvent *bevent = &textsw->xevent->xbutton; Time curtime = bevent->time; short is_multiclick = FALSE; if( tline == textsw->last_tline && tindex == textsw->last_tindex ) if( (curtime - textsw->last_time) <= textsw->click_timeout ) is_multiclick = TRUE; return is_multiclick; } static int text_notify_dispatch( textsw_pub, event, arg, type) Textsw textsw_pub; Event *event; Notify_arg arg; Notify_event_type type; { ... XEvent *aevent = event->ie_xevent; XButtonEvent *bevent = aevent->xbutton; ... textsw->click_timeout = HARDCODED_MILLISECONDS; /* init once */ textsw->xevent = aevent; ... if( txt_is_multiclick( textsw, line, index ) ) { /* inside the threshhold */ } else { /* outside the threshold */ } textsw->last_time = bevent->time; } -Jim -- -- Jim Becker / jcb%frisbee@sun.com / Sun Microsystems