Author Topic: double click  (Read 5372 times)

0 Members and 1 Guest are viewing this topic.

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
double click
« on: February 16, 2020, 05:47:01 pm »
Hi all,

I have to give up... can you help me understand, please, where is the error in this example?
Can you enter the missing code?

Code: QB64: [Select]
  1.  DO
  2.         j$ = INKEY$          'other controls
  3.         xxw& = _KEYHIT   'other controls
  4.  
  5.         num_click=0    
  6.         the_end=0            'other controls
  7.  
  8.  
  9.  
  10. ' here one o double click control missing code
  11. '--------------------------------------------------
  12.  
  13.  
  14.  
  15.  
  16.  
  17. LOOP UNTIL j$ <> "" OR the_end > 0
  18.  
  19.  
  20. ? num_click
  21.  
  22.  

I can't insert the wiki example.
I had solved the single click but now I need to monotorate the second click.




« Last Edit: February 16, 2020, 05:52:50 pm by krovit »
Nothing is easy, especially when it appears simple (and nothing could be as dangerous as trying to do good to others)

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Re: double click
« Reply #1 on: February 16, 2020, 06:03:41 pm »
Code: QB64: [Select]
  1.  DO
  2.         j$ = INKEY$
  3.         xxw& = _KEYHIT
  4.  
  5.         num_click=0    
  6.         the_end=0  
  7.  
  8.    
  9.         DO WHILE _MOUSEINPUT                'check mouse status
  10.                 mb% = _MOUSEBUTTON(1)
  11.         LOOP
  12.         DO WHILE mb%                 'check for button release
  13.                 i = _MOUSEINPUT
  14.                 mb% = _MOUSEBUTTON(1)
  15.                 num_click=1
  16.         LOOP
  17.  
  18.         IF num_click = 1 THEN                   'if button was pressed and released
  19.                 t = TIMER + .3
  20.                 DO WHILE TIMER < t      'check for a second press within .3 seconds
  21.                         i = _MOUSEINPUT
  22.                         IF _MOUSEBUTTON(1) THEN num_click = 2': EXIT DO
  23.                 LOOP
  24.                 'IF num_click>0 then exit do
  25.         END IF
  26.  
  27.  
  28. LOOP UNTIL j$ <> "" OR the_end > 0 or num_click>0
  29.  
  30.  
  31. ? num_click
  32.  
  33.  


So it works but then, inserting it into the real program, no. Maybe it's some variable that disturbs...

In any case is this the cleanest code to monitor the double click or do you think and be another more efficient?

Thank you
Nothing is easy, especially when it appears simple (and nothing could be as dangerous as trying to do good to others)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: double click
« Reply #2 on: February 16, 2020, 06:44:23 pm »
OK same menu demo I gave you last time now with modification for Double Click detection:
Code: QB64: [Select]
  1. _TITLE "press menu number key or Double Click Menu Item" 'b+ 2020-02-16
  2.     CLS
  3.     PRINT "Press menu # key or double click menu item:"
  4.     FOR m = 1 TO 8
  5.         ms$ = _TRIM$(STR$(m))
  6.         PRINT ms$; ") Menu item "; ms$
  7.     NEXT
  8.     PRINT "9) Quit this demo"
  9.  
  10.  
  11.     k$ = INKEY$ '<<<<<<<<<<<<<<<<<<< update k$
  12.     WHILE _MOUSEINPUT: WEND ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< update mouse status
  13.  
  14.     ' ++++++++++++++++++++++++++++++++++++ Report Stuff +++++++++++++++++++++++++++++++++++++++++++++++
  15.     mb = _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) OR _MOUSEBUTTON(3) ' >>>>>>>>>>>>> report mouse status
  16.     mx = _MOUSEX: my = _MOUSEY
  17.     PRINT
  18.     PRINT "INKEY$:"; k$; "   _MOUSEBUTTON(X) pressed "; mb; "  Current _MOUSEX"; mx; "  Current _MOUSEY"; my
  19.     PRINT
  20.     '-------------------------------------------------------------------------------------------------------
  21.  
  22.     IF mb AND oldMouse = 0 OR LEN(k$) THEN '>>>>> wait for oldMouse to clear to 0  so you know mb is new one!
  23.         IF TIMER(.001) - lastTime < 0 THEN curTime = TIMER(.001) + 24 * 60 * 60 ELSE curTime = TIMER(.001)
  24.         IF curTime - lastTime < .3 THEN 'double = two clicks in less than .3 sec
  25.             mb2 = 1
  26.         ELSE
  27.             lastTime = curTime 'save last click time
  28.             mb2 = 0 'clear last double click report
  29.         END IF
  30.         FOR m = 1 TO 9
  31.             IF mb2 AND my = m + 1 OR k$ = _TRIM$(STR$(m)) THEN 'for screen 0 or default my = line number
  32.                 PRINT "You selected menu"; m: _DELAY 2
  33.                 IF m = 9 THEN SYSTEM
  34.             END IF
  35.         NEXT
  36.     END IF
  37.  
  38.     'save last mouse status
  39.     oldMouse = mb ' <<<  comment on and off to see difference when hold mouse button down and go up and down menu
  40.     '          oldMouse will wait until you release mousebutton before accepting another menu selection
  41.  
  42.  
  43.     _LIMIT 60
  44.  
  45.  
  46.  
  47.  

EDIT add comments

EDIT 2: before Steve reminds us of Midnight problem here is the fix.
« Last Edit: February 16, 2020, 07:37:07 pm by bplus »

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Re: double click
« Reply #3 on: February 17, 2020, 03:36:40 am »
Thank you, it actually seems like the best, clean and efficient routine.

I can't import it into my program but maybe it depends on the complexity of the function in which I want to insert it.
And the flow of execution is probably not as efficient.
It's going to take me some time...
Nothing is easy, especially when it appears simple (and nothing could be as dangerous as trying to do good to others)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: double click
« Reply #4 on: February 17, 2020, 10:51:06 am »
Does not port?

Aha! I see a problem trying to get INKEY$ when mouse polling is done outside main loop where INKEY$ polling is.

So do INKEY$ (and/or _KEYHIT) with mouse polling in a portable FUNCTION:
Code: QB64: [Select]
  1. _TITLE "press menu number key or Double Click Menu Item" 'b+ 2020-02-18
  2.     CLS
  3.     PRINT "Press menu # key or double click menu item:"
  4.     FOR m = 1 TO 8
  5.         ms$ = _TRIM$(STR$(m))
  6.         PRINT ms$; ") Menu item "; ms$
  7.     NEXT
  8.     PRINT "9) Quit this demo"
  9.  
  10.     '====================================  evaluate for double click ======================================
  11.     IF singleClick%(mx, my, k$) THEN
  12.         IF TIMER(.001) - lastTime < 0 THEN curTime = TIMER(.001) + 24 * 60 * 60 ELSE curTime = TIMER(.001)
  13.         IF curTime - lastTime < .3 THEN 'double = two clicks in less than .3 sec
  14.             mb2 = 1
  15.         ELSE
  16.             lastTime = curTime 'save last click time
  17.             mb2 = 0 'clear last double click report
  18.         END IF
  19.     END IF
  20.     ' ================================== use mb2, mx, my for double click existence and location ==========
  21.  
  22.     ' mF = 0 ' Demo using keypress or double click info
  23.     FOR m = 1 TO 9
  24.         IF mb2 AND my = m + 1 OR k$ = _TRIM$(STR$(m)) THEN 'for screen 0 or default my = line number
  25.             PRINT "You selected menu"; m: _DELAY 2
  26.             IF m = 9 THEN SYSTEM
  27.             'mF = 1
  28.         END IF
  29.     NEXT
  30.  
  31.     ' Demo use single click info when doesn't interfere with dbl click evaluation, ie doesn't delay 2nd click detection
  32.     IF my > 10 THEN PRINT " You clicked outside then menu area: col"; mx; ", row"; my: _DELAY 2
  33.     IF LEN(k$) THEN PRINT "You pressed "; k$: _DELAY 2
  34.  
  35. FUNCTION singleClick% (atX, atY, K$) 'this function waits until mousebutton is pressed and released or a key is pressed
  36.     _KEYCLEAR: atX = -1: atY = -1
  37.     DO
  38.         K$ = INKEY$ '<<<<<<<<<<<<<<<<<<< update k$
  39.         WHILE _MOUSEINPUT: WEND ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< update mouse status
  40.         mb = _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) OR _MOUSEBUTTON(3) ' >>>>>>>>>>>>> report mouse status
  41.         mx = _MOUSEX: my = _MOUSEY
  42.  
  43.         '___________________________________ Comment this block out in app _______________________________________________
  44.         LOCATE 15
  45.         PRINT
  46.         PRINT "INKEY$:"; K$; "   _MOUSEBUTTON(X) pressed "; mb; "  Current _MOUSEX"; mx; "  Current _MOUSEY"; my
  47.         PRINT
  48.  
  49.  
  50.         IF mb AND oldMouse = 0 THEN '>>>>> wait for oldMouse to clear to 0  so you know mb is new one!
  51.             singleClick% = -1: atX = mx: atY = my
  52.         END IF
  53.         oldMouse = mb
  54.         _LIMIT 200 '<<<<<<<<<<<<<<<<<<<<<<<<<< reduce if you want to see a keypress flash
  55.     LOOP UNTIL singleClick% AND oldMouse = 0 OR LEN(K$) 'hang until mouse button is released
  56.  
  57.  
  58.  

Edit again: I keep finding improvements
« Last Edit: February 17, 2020, 11:33:07 am by bplus »

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Re: double click
« Reply #5 on: February 17, 2020, 01:50:30 pm »
Maybe it's like you say.

I'm going crazy trying to understand why when it enters the routine at the first click it already thinks it has double clicked and then exits...

The version you posted is improved and even more effective than the previous one. But I'm going crazy trying...




My programs has tens of thousands of lines ... posting it is impossible. If I say it again to explain the problem, it simplifies too much.

The application are all parametric and modular.
A series of fields can be selected with the keyboard and with the mouse.
With a first click jump to the position of the field.
With the second click ... nothing happens. And that's okay!
In fact the second click, only in certain fields, activates a drop-down menu. Alternatively, on that field, I press CTRL+Enter and I get the same result.

Everything worked fine until I realized how useful it is to activate the drop-down menu with a double click.
I can't insert double click! when I'm on the field (because I pressed a click or because I got there by scrolling through the fields with the keyboard) I can't manage the double click: it doesn't notice and during the attempts I get to the maximum that the first click is already mistaken for the second and activate - or try to activate even where it doesn't exist - the drop-down menu.

I understand that it is difficult to understand in words... but in fact I seem to move your routines to the right position of mine but it no longer works! It's really frustrating.

I am one who does not give up but I know that I could spend months looking for the solution.
And I'm not that young anymore.


I will try your second version again.
In the meantime if something else comes to mind... write it! Thank you!










« Last Edit: February 17, 2020, 01:54:01 pm by krovit »
Nothing is easy, especially when it appears simple (and nothing could be as dangerous as trying to do good to others)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: double click
« Reply #6 on: February 17, 2020, 03:03:19 pm »
Oh man, drop down menus!

I don't know if we could detect both a single click AND a double click for the same spot (in the same screen state), the single click would always win I would think, though I think Windows does it.

We could mouse down on a spot and release mouse at another spot far enough away to call that a double click or  otherwise mouse release at very near the same spot and call that a single click as would be expected. That way we don't have to count clicks we just distinguish how far away the mouse is when released.

Another consideration, use a right click instead of a double left click?

Ah trying to distinguish double click AND single from same spot might be possible, I have an experiment in mind... ;-)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: double click
« Reply #7 on: February 17, 2020, 04:51:53 pm »
Oh man, drop down menus!

I don't know if we could detect both a single click AND a double click for the same spot (in the same screen state), the single click would always win I would think, though I think Windows does it.

We could mouse down on a spot and release mouse at another spot far enough away to call that a double click or  otherwise mouse release at very near the same spot and call that a single click as would be expected. That way we don't have to count clicks we just distinguish how far away the mouse is when released.

Another consideration, use a right click instead of a double left click?

Ah trying to distinguish double click AND single from same spot might be possible, I have an experiment in mind... ;-)

I’ve got a few mouse demos which cover single/double clicks, hover events, drag events, and all, on one of these various forums.  If I can find some free time here later, I’ll try and drag one up for you guys.

The trick is in using a timer and counter with the mouse.  Basically:

FUNCTION mouseclick
    STATIC lastclicktime AS _FLOAT, oldmouse AS INTEGER
    WHILE _MOUSEINPUT: WEND
     IF lastclicktime = 0 THEN ‘there was no previous click event to deal with
         IF oldmouse = UP AND _MOUSEINPUT(1) = DOWN THEN lastclicktime = TIMER ‘start the timer
     ELSE ‘we had a previous click event
          IF lastclicktime + 0.2 > TIMER THEN
               lastclicktime = 0 ‘reset timer
               mouseclick = 1 ‘single click if there’s no double click in 0.2 seconds
         ELSE
              IF oldmouse = UP AND _MOUSEINPUT(1) = DOWN THEN
                  mouseclick = 2 ‘doubleclick
                  lastclicktimer = 0
         END IF
     END IF

    oldmouse = _MOUSEINPUT(1)
EXIT FUNCTION
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: double click
« Reply #8 on: February 17, 2020, 05:02:09 pm »
If you’re worried about the mouse moving, just store the old x/y positions and compare them before you decide what the result is.

STATIC mx, my

If ABS(_MOUSEX - mx) > 5 OR ABS(_MOUSEY - my) THEN mousemoved = TRUE


^ With something like the above, you store the mouse x/y position when the first click event starts and then compare to see if the mouse has moved before the time is up to determine your double click vs click resolution.  I like the idea of ABS(firstposition - currentposition) < 5 instead of firstposition = currentposition type comparison as I’ve had some old mice over the years which “jiggle” +/- a few pixels almost constantly.  Give it an acceptable threshold for minor variance, before you just declare it “moved” from a single pixel’s change.   ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: double click
« Reply #9 on: February 17, 2020, 05:17:36 pm »
Here is how I usually detect single and double mouse clicks within a looping structure. Perhaps this can help you.

Code: QB64: [Select]
  1. TYPE MOUSE
  2.     x AS INTEGER '           actual Y location of mouse cursor
  3.     y AS INTEGER '           actual X location of mouse cursor
  4.     Click AS INTEGER '       TRUE if single click occurred
  5.     DoubleClick AS INTEGER ' TRUE if double click occurred
  6.     DCTimer AS INTEGER '     double click timer
  7.     LeftDown AS INTEGER '    TRUE if left button is down
  8.     ClickX AS INTEGER
  9.     ClickY AS INTEGER
  10.  
  11. CONST FALSE = 0, TRUE = NOT FALSE
  12. CONST FPS = 60
  13.  
  14. DIM Mouse AS MOUSE
  15.  
  16. SCREEN _NEWIMAGE(640, 480, 32)
  17.  
  18.     _LIMIT FPS
  19.     CLS
  20.     UpdateMouse
  21.     IF Mouse.DoubleClick THEN SOUND 880, 1
  22.     IF Mouse.Click THEN SOUND 440, 1
  23.     _DISPLAY
  24.  
  25.  
  26. SUB UpdateMouse ()
  27.  
  28.     SHARED Mouse AS MOUSE
  29.  
  30.     Mouse.x = _MOUSEX '                     actual X coordinate
  31.     Mouse.y = _MOUSEY '                     actual Y coordinate
  32.     Mouse.DoubleClick = FALSE
  33.     Mouse.Click = FALSE
  34.     SELECT CASE _MOUSEBUTTON(1) '                   current state of left button?
  35.         CASE TRUE '                                 button is down
  36.             IF NOT Mouse.LeftDown THEN '            already held down?
  37.                 Mouse.LeftDown = TRUE '             no, remember that it is now
  38.                 IF Mouse.DCTimer THEN '             was last click less than double click timer value?
  39.                     IF ABS(Mouse.ClickX - Mouse.x) < 3 AND ABS(Mouse.ClickY - Mouse.y) < 3 THEN
  40.                         Mouse.DoubleClick = TRUE '  yes, report a double click happened
  41.                     END IF
  42.                     Mouse.DCTimer = 0 '             reset the double click timer
  43.                 ELSE '                              no, double click timer has run out
  44.                     Mouse.DCTimer = FPS \ 3 '       reset double click timer to 1/3 second
  45.                     Mouse.ClickX = Mouse.x '        remember X location of click
  46.                     Mouse.ClickY = Mouse.y '        remember Y location of click
  47.                     Mouse.Click = TRUE '            report that a single click occurred
  48.                 END IF
  49.             END IF
  50.         CASE FALSE '                                button is up
  51.             IF Mouse.LeftDown THEN '                was the left button previously down?
  52.                 Mouse.LeftDown = FALSE '            yes, report that it's now up
  53.             END IF
  54.             IF Mouse.DCTimer THEN '                 time left in double click timer?
  55.                 Mouse.DCTimer = Mouse.DCTimer - 1 ' yes, decrement value
  56.             END IF
  57.     END SELECT
  58.  
« Last Edit: February 17, 2020, 05:19:05 pm by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: double click
« Reply #10 on: February 17, 2020, 05:29:24 pm »
You all are missing a point, we need to get keypress also and  krovit is looking for both INKEY$ and _KEYHIT.

Test and prove in working app / demo.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: double click
« Reply #11 on: February 17, 2020, 05:36:51 pm »
You all are missing a point, we need to get keypress also and  krovit is looking for both INKEY$ and _KEYHIT.

Test and prove in working app / demo.

Mouse in one function, keyhit in a second one, and check desired resolution results in your main loop.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: double click
« Reply #12 on: February 17, 2020, 05:49:36 pm »
You all are missing a point, we need to get keypress also and  krovit is looking for both INKEY$ and _KEYHIT.

Test and prove in working app / demo.

I'm not seeing the issue here. Here is the previous code I wrote modified a bit to detect _KEYHIT and INKEY$.

Code: QB64: [Select]
  1. TYPE MOUSE
  2.     x AS INTEGER '           actual Y location of mouse cursor
  3.     y AS INTEGER '           actual X location of mouse cursor
  4.     Click AS INTEGER '       TRUE if single click occurred
  5.     DoubleClick AS INTEGER ' TRUE if double click occurred
  6.     DCTimer AS INTEGER '     double click timer
  7.     LeftDown AS INTEGER '    TRUE if left button is down
  8.     ClickX AS INTEGER
  9.     ClickY AS INTEGER
  10.  
  11. CONST FALSE = 0, TRUE = NOT FALSE
  12. CONST FPS = 60
  13.  
  14. DIM Mouse AS MOUSE
  15.  
  16. SCREEN _NEWIMAGE(640, 480, 32)
  17.  
  18.     _LIMIT FPS
  19.     CLS
  20.     UpdateMouse
  21.     IF Mouse.DoubleClick THEN SOUND 880, 1
  22.     IF Mouse.Click THEN SOUND 440, 1
  23.     PRINT "Mouse X     : "; Mouse.x
  24.     PRINT "Mouse Y     : "; Mouse.y
  25.     PRINT "Last click X: "; Mouse.ClickX
  26.     PRINT "Last click Y: "; Mouse.ClickY
  27.     PRINT "Left button is ";
  28.     IF Mouse.LeftDown THEN PRINT "DOWN" ELSE PRINT "UP"
  29.     keyhit = _KEYHIT
  30.     IF keyhit > 0 THEN oldkeyhit = keyhit
  31.     ink$ = INKEY$
  32.     IF ink$ <> "" THEN oldink$ = ink$
  33.     PRINT "Last KeyHit = "; oldkeyhit
  34.     PRINT "Last Inkey$ = "; oldink$
  35.     _DISPLAY
  36.  
  37.  
  38. SUB UpdateMouse ()
  39.  
  40.     SHARED Mouse AS MOUSE
  41.  
  42.     Mouse.x = _MOUSEX '                     actual X coordinate
  43.     Mouse.y = _MOUSEY '                     actual Y coordinate
  44.     Mouse.DoubleClick = FALSE
  45.     Mouse.Click = FALSE
  46.     SELECT CASE _MOUSEBUTTON(1) '                   current state of left button?
  47.         CASE TRUE '                                 button is down
  48.             IF NOT Mouse.LeftDown THEN '            already held down?
  49.                 Mouse.LeftDown = TRUE '             no, remember that it is now
  50.                 IF Mouse.DCTimer THEN '             was last click less than double click timer value?
  51.                     IF ABS(Mouse.ClickX - Mouse.x) < 3 AND ABS(Mouse.ClickY - Mouse.y) < 3 THEN
  52.                         Mouse.DoubleClick = TRUE '  yes, report a double click happened
  53.                     END IF
  54.                     Mouse.DCTimer = 0 '             reset the double click timer
  55.                 ELSE '                              no, double click timer has run out
  56.                     Mouse.DCTimer = FPS \ 3 '       reset double click timer to 1/3 second
  57.                     Mouse.ClickX = Mouse.x '        remember X location of click
  58.                     Mouse.ClickY = Mouse.y '        remember Y location of click
  59.                     Mouse.Click = TRUE '            report that a single click occurred
  60.                 END IF
  61.             END IF
  62.         CASE FALSE '                                button is up
  63.             IF Mouse.LeftDown THEN '                was the left button previously down?
  64.                 Mouse.LeftDown = FALSE '            yes, report that it's now up
  65.             END IF
  66.             IF Mouse.DCTimer THEN '                 time left in double click timer?
  67.                 Mouse.DCTimer = Mouse.DCTimer - 1 ' yes, decrement value
  68.             END IF
  69.     END SELECT
  70.  
  71.  
In order to understand recursion, one must first understand recursion.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: double click
« Reply #13 on: February 17, 2020, 06:00:29 pm »
Here it is modified a bit more. Now you can drag a selection box around while holding down the left mouse button. It still detects keystrokes as well while dragging the box.

Code: QB64: [Select]
  1. TYPE MOUSE
  2.     x AS INTEGER '           actual Y location of mouse cursor
  3.     y AS INTEGER '           actual X location of mouse cursor
  4.     Click AS INTEGER '       TRUE if single click occurred
  5.     DoubleClick AS INTEGER ' TRUE if double click occurred
  6.     DCTimer AS INTEGER '     double click timer
  7.     LeftDown AS INTEGER '    TRUE if left button is down
  8.     ClickX AS INTEGER
  9.     ClickY AS INTEGER
  10.  
  11. CONST FALSE = 0, TRUE = NOT FALSE
  12. CONST FPS = 60
  13.  
  14. DIM Mouse AS MOUSE
  15.  
  16. SCREEN _NEWIMAGE(640, 480, 32)
  17.  
  18.     _LIMIT FPS
  19.     CLS
  20.     UpdateMouse
  21.     IF Mouse.DoubleClick THEN SOUND 880, 1
  22.     IF Mouse.Click THEN SOUND 440, 1
  23.     PRINT "Mouse X     : "; Mouse.x
  24.     PRINT "Mouse Y     : "; Mouse.y
  25.     PRINT "Last click X: "; Mouse.ClickX
  26.     PRINT "Last click Y: "; Mouse.ClickY
  27.     PRINT "Left button is ";
  28.     IF Mouse.LeftDown THEN PRINT "DOWN" ELSE PRINT "UP"
  29.     keyhit = _KEYHIT
  30.     IF keyhit > 0 THEN oldkeyhit = keyhit
  31.     ink$ = INKEY$
  32.     IF ink$ <> "" THEN oldink$ = ink$
  33.     PRINT "Last KeyHit = "; oldkeyhit
  34.     PRINT "Last Inkey$ = "; oldink$
  35.     IF Mouse.LeftDown THEN
  36.         LINE (Mouse.ClickX, Mouse.ClickY)-(Mouse.x, Mouse.y), _RGB32(0, 0, 255), BF
  37.     END IF
  38.     _DISPLAY
  39.  
  40.  
  41. SUB UpdateMouse ()
  42.  
  43.     SHARED Mouse AS MOUSE
  44.  
  45.     Mouse.x = _MOUSEX '                     actual X coordinate
  46.     Mouse.y = _MOUSEY '                     actual Y coordinate
  47.     Mouse.DoubleClick = FALSE
  48.     Mouse.Click = FALSE
  49.     SELECT CASE _MOUSEBUTTON(1) '                   current state of left button?
  50.         CASE TRUE '                                 button is down
  51.             IF NOT Mouse.LeftDown THEN '            already held down?
  52.                 Mouse.LeftDown = TRUE '             no, remember that it is now
  53.                 IF Mouse.DCTimer THEN '             was last click less than double click timer value?
  54.                     IF ABS(Mouse.ClickX - Mouse.x) < 3 AND ABS(Mouse.ClickY - Mouse.y) < 3 THEN
  55.                         Mouse.DoubleClick = TRUE '  yes, report a double click happened
  56.                     END IF
  57.                     Mouse.DCTimer = 0 '             reset the double click timer
  58.                 ELSE '                              no, double click timer has run out
  59.                     Mouse.DCTimer = FPS \ 3 '       reset double click timer to 1/3 second
  60.                     Mouse.ClickX = Mouse.x '        remember X location of click
  61.                     Mouse.ClickY = Mouse.y '        remember Y location of click
  62.                     Mouse.Click = TRUE '            report that a single click occurred
  63.                 END IF
  64.             END IF
  65.         CASE FALSE '                                button is up
  66.             IF Mouse.LeftDown THEN '                was the left button previously down?
  67.                 Mouse.LeftDown = FALSE '            yes, report that it's now up
  68.             END IF
  69.             IF Mouse.DCTimer THEN '                 time left in double click timer?
  70.                 Mouse.DCTimer = Mouse.DCTimer - 1 ' yes, decrement value
  71.             END IF
  72.     END SELECT
  73.  
  74.  
In order to understand recursion, one must first understand recursion.

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Re: double click
« Reply #14 on: February 17, 2020, 06:21:54 pm »
Wow, thank you for your interest!

In fact, the issue is crucial. it's also crucial because an application can't ignore the intensive use of the mouse.


Checking the timer behavior in the various examples entered in my code I see some oddities.
This is the differential within which to count the number of clicks.

Well, it seems that whatever the frequency and speed of clicks the time between one and the other is always the same (and it happens always out of the imposed range - in the examples usually 0.3 seconds). Change, when there is, you see after the ninth, tenth and over digit after the comma.

Another question:
the results are very different when treated in double precision or in a single.

In single precision the results seem completely unreliable (even have the appearance of a random value and the differential between one measurement and the other is absolutely far from the 0.3-second limit).
It seems to be for this reason - or at least that this is one of the reasons why the second click is not intercepted.

That there is a problem in the TIMER command that in some particular case may arise?
Or maybe the command is used incorrectly or improperly?

Anyway I'll try your contributions in my code to continue to check their behavior.

I need to monitor that second click! And I can't give up after so much effort and to the point where I've come.


« Last Edit: February 18, 2020, 02:07:13 am by krovit »
Nothing is easy, especially when it appears simple (and nothing could be as dangerous as trying to do good to others)