Author Topic: Is There a Mouse Equivalent of _KEYCLEAR?  (Read 7234 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Is There a Mouse Equivalent of _KEYCLEAR?
« on: January 03, 2019, 07:24:09 am »
Is There a Mouse Equivalent of _KEYCLEAR, where any stray mouse events are used up?  From my reading of the Wiki, there isn't and I could code and have coded a routine to use up any _MOUSEBUTTON events.  But an existing command would be easier.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #1 on: January 03, 2019, 07:41:07 am »
WHILE _MOUSEINPUT: WEND
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #2 on: January 03, 2019, 07:53:58 am »
Steve, I thought that it had to be slightly more complicated:

Code: QB64: [Select]
  1. DO 'make sure that mouse button is released
  2.     Dum` = _MOUSEINPUT
  3.  LOOP UNTIL NOT _MOUSEBUTTON(ButtonNo%%)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #3 on: January 03, 2019, 08:57:20 am »
Steve, I thought that it had to be slightly more complicated:

Code: QB64: [Select]
  1. DO 'make sure that mouse button is released
  2.     Dum` = _MOUSEINPUT
  3.  LOOP UNTIL NOT _MOUSEBUTTON(ButtonNo%%)

What you've got is a No-No code snippet, except under very controlled situations.   Here it is, in an actual program:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. LINE (100, 100)-(200, 200), &HFFFF0000, BF
  4. LINE (250, 100)-(350, 200), &HFF00FF00, BF
  5. LINE (400, 100)-(500, 200), &HFF0000FF, BF
  6.  
  7.  
  8. ButtonNo%% = 1 'left mouse
  9.     _LIMIT 60
  10.     DO 'make sure that mouse button is released
  11.         Dum` = _MOUSEINPUT
  12.     LOOP UNTIL NOT _MOUSEBUTTON(ButtonNo%%)
  13.     LOCATE 1, 1

Now, scroll your mouse around the screen a few times and watch the X/Y location print for you.  STOP moving the mouse, and watch the X/Y location... 

It's still updating from the mousebuffer, LOOOOOOOOOOONG after you quit moving the mouse!

Not the effect you're looking for at all, I'd imagine.  :)

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: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #4 on: January 03, 2019, 08:59:47 am »
For a simple mouseclick type event, to see if an user has clicked inside a proper boundry for you, try something like this:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3.     x AS INTEGER
  4.     y AS INTEGER
  5.     Click AS LONG
  6.  
  7. DIM Box(3) AS Point
  8. FOR i = 100 TO 400 STEP 150
  9.     count = count + 1
  10.     Box(count).x = i
  11.     Box(count).y = 100
  12. Box(1).Color = &HFFFF0000
  13. Box(2).Color = &HFF00FF00
  14. Box(3).Color = &HFF0000FF
  15.  
  16.  
  17.  
  18.     _LIMIT 60
  19.     CLS
  20.     FOR i = 1 TO 3
  21.         LINE (Box(i).x, Box(i).y)-STEP(100, 100), Box(i).Color, BF
  22.     NEXT
  23.  
  24.     IF OMB = 0 THEN 'The mouse button was up on a previous pass
  25.         IF _MOUSEBUTTON(1) THEN
  26.             FOR i = 1 TO 3
  27.                 IF _MOUSEX >= Box(i).x AND _MOUSEX <= Box(i).x + 100 AND _MOUSEY >= Box(i).y AND _MOUSEY <= Box(i).y + 100 THEN 'we clicked a box
  28.                     Box(i).Click = Box(i).Click + 1
  29.                 END IF
  30.             NEXT
  31.         END IF
  32.     END IF
  33.     LOCATE 1, 1
  34.     FOR i = 1 TO 3: PRINT "Box"; i; "Clicked:", Box(i).Click: NEXT
  35.     OMB = _MOUSEBUTTON(1) 'Old Mouse Button
  36.     _DISPLAY
  37.  

Notice how I update the mouseinput buffer?

Code: QB64: [Select]

It's as simple as it gets.  Clear the buffer, deal with what's going on with the mouse as your program makes each current loop.  ;)
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: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #5 on: January 03, 2019, 09:38:45 am »
And here's a more elaborate mouse routine:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3.     x AS INTEGER
  4.     y AS INTEGER
  5.     Click AS LONG
  6.  
  7. DIM Box(3) AS Point
  8. FOR i = 100 TO 400 STEP 150
  9.     count = count + 1
  10.     Box(count).x = i
  11.     Box(count).y = 100
  12. Box(1).Color = &HFFFF0000
  13. Box(2).Color = &HFF00FF00
  14. Box(3).Color = &HFF0000FF
  15.  
  16.  
  17.  
  18.     _LIMIT 60
  19.     CLS
  20.     FOR i = 1 TO 3
  21.         LINE (Box(i).x, Box(i).y)-STEP(100, 100), Box(i).Color, BF
  22.     NEXT
  23.  
  24.     IF OMB = 0 THEN 'The mouse button was up on a previous pass
  25.         IF _MOUSEBUTTON(1) THEN
  26.             StartX = _MOUSEX: StartY = _MOUSEY
  27.             t# = TIMER(0.001)
  28.             WHILE _MOUSEBUTTON(1)
  29.                 junk = _MOUSEINPUT
  30.                 held = TIMER(0.001) - t# 'check to see if the button is held down for .2 seconds or more
  31.                 IF held > 0.2 THEN EXIT WHILE 'After .2 seconds, we declare this a "hold event"
  32.             WEND
  33.  
  34.             IF held < 0.2 THEN 'if we're not held down, it's a click
  35.                 FOR i = 1 TO 3
  36.                     IF _MOUSEX >= Box(i).x AND _MOUSEX <= Box(i).x + 100 AND _MOUSEY >= Box(i).y AND _MOUSEY <= Box(i).y + 100 THEN 'we clicked a box
  37.                         Box(i).Click = Box(i).Click + 1
  38.                     END IF
  39.                 NEXT
  40.             ELSE ' If we're held down, let's store the original coordinates of the box we're held over (if any)
  41.                 BO = 0
  42.                 FOR i = 1 TO 3
  43.                     IF StartX >= Box(i).x AND StartX <= Box(i).x + 100 AND StartY >= Box(i).y AND StartY <= Box(i).y + 100 THEN
  44.                         BOX = Box(i).x: BOY = Box(i).y 'Box Original X and Box Original Y
  45.                         BO = i 'Box the mouse is Over
  46.                     END IF
  47.                 NEXT
  48.             END IF
  49.         END IF
  50.     ELSE 'If the button was down on a previous pass, we'll deal with a "hold button" event, if we have one.
  51.         IF held THEN
  52.             IF StartX >= BOX AND StartX <= BOX + 100 AND StartY >= BOY AND StartY <= BOY + 100 THEN 'we held the mouse down over a box
  53.                 Xshift = StartX - _MOUSEX
  54.                 Yshift = StartY - _MOUSEY
  55.                 Box(BO).x = BOX - Xshift
  56.                 Box(BO).y = BOY - Yshift
  57.             END IF
  58.         END IF
  59.     END IF
  60.     LOCATE 1, 1
  61.     FOR i = 1 TO 3: PRINT "Box"; i; "Clicked:", Box(i).Click: NEXT
  62.     OMB = _MOUSEBUTTON(1) 'Old Mouse Button
  63.     IF _MOUSEBUTTON(1) = 0 THEN held = 0
  64.     _DISPLAY
  65.  

For this sample, click on the boxes just as you did before, and you can see how we interact with a "click event".

Then click on a box and hold the mouse down and move it across the screen.  You can see how we'd deal with a "mouse down/ drag event". 

In either case, our main routine for mouse handling is:

Code: QB64: [Select]



If you notice, I *do* have a routine in this code which looks rather similar to the one you posted:

Code: QB64: [Select]
  1.                 WHILE _MOUSEBUTTON(1)
  2.                     junk = _MOUSEINPUT
  3.                     held = TIMER(0.001) - t# 'check to see if the button is held down for .2 seconds or more
  4.                     IF held > 0.2 THEN EXIT WHILE
  5.                 WEND

The difference here?

The main process handles all the real mouse input work, and I only trap the input for 2/10ths of a second, so I can to see if I'm dealing with a "click event", or starting a "hold button" event.  The "WHILE _MOUSEINPUT: WEND" keeps the mousebuffer clear for us, and stops the input backlog from building up like we saw in the very first little demo I showcased above. 

"WHILE _MOUSEINPUT: WEND" is normally your main mouse loop, and the only thing you normally see inside it might be a counter if you're tracking the mouse scroll status.  ;)
« Last Edit: January 03, 2019, 09:47:49 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #6 on: January 03, 2019, 09:49:25 am »
Instead of timers, I'd recommend using flags for mouse down, as in the code I posted at https://www.qb64.org/forum/index.php?topic=912.0 (and everything mouse related I post).

Look in SUB checkMouseAction.

FellippeHeitor

  • Guest
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #7 on: January 03, 2019, 09:53:22 am »
In summary:

'poll mouse buffer
WHILE _MOUSEINPUT: WEND

SUB checkMouseAction STATIC
    IF _MOUSEBUTTON(1) THEN
        IF mouseDown = 0 THEN
            'first pressed
            mouseDown = -1
        ELSE
            'dragging
        END IF
    ELSE
        IF mouseDown THEN
            mouseDown = 0
            'release/click (if st same coordinates of initial mousedown above)
        END IF
    END IF
END SUB
« Last Edit: January 03, 2019, 09:54:35 am by FellippeHeitor »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #8 on: January 03, 2019, 09:57:32 am »
Instead of timers, I'd recommend using flags for mouse down, as in the code I posted at https://www.qb64.org/forum/index.php?topic=912.0 (and everything mouse related I post).

Look in SUB checkMouseAction.

That’s what OMB does for us.  The 0.2 second timer is basically an “escape timer”, so a user won’t hold the button forever and pause program execution, like I’ve seen in some mouse routines.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #9 on: January 03, 2019, 09:59:03 am »
The above leaves little to no room for hanging, check it out.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #10 on: January 03, 2019, 10:39:22 am »
The above leaves little to no room for hanging, check it out.

It also leaves no time for someone to do a mouse click with a sticky mouse button.  As long as it polls down then up, it’s a “mouse click”.  If your button sticks for a few milliseconds, it’s called a “drag event”.

And, correct me if I’m wrong, but doesn’t it also generate a “click event” when the “drag event” ends?  Or is that accounted for in the commented out ‘dragging section? 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #11 on: January 03, 2019, 10:48:55 am »
It does, just like all modern systems. It's up to the programmer to ignore a drag if a drag is not interesting in context.

Like a double click always implies a single click.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #12 on: January 04, 2019, 07:40:53 am »
O Magnificent Gurus of the Great Spiritual Mouse, what then is the correct method for using up stray mouse clicks?  Pray, graciously enlighten your lowly, humble and ignorant follower.

From Steve (edited):
For a simple mouseclick type event, to see if an user has clicked inside a proper boundry for you, try something like this:

Code: QB64: [Select]
  1.     _LIMIT 60
  2.     CLS
  3.    
  4.             FOR i = 1 TO 3
  5.                 IF _MOUSEX >= Box(i).x AND _MOUSEX <= Box(i).x + 100 AND _MOUSEY >= Box(i).y AND _MOUSEY <= Box(i).y + 100 THEN 'we clicked a box
  6.                     Box(i).Click = Box(i).Click + 1
  7.                 END IF
  8.             NEXT
  9.     END IF
  10.     _DISPLAY
  11.  


Steve's mouse polling is inside a limited WHILE/WEND.

My code would look like:

Code: QB64: [Select]
  1. WHILE SomeCondition`
  2.     _LIMIT 60
  3.     'Do Something
  4.         IF _MOUSEBUTTON(1) THEN
  5.             'Set some flag
  6.         END IF
  7.     WEND
  8.     '_DISPLAY if display update required

The program actioning is inside a WHILE/WEND with a _LIMIT, but inside that the Mouse polling is inside an unlimited WHILE/WEND, and therfore there is no delay.  My Use-Up-Mouse Routine would be before the next required mouse polling.

When I first coded a use up mouse click routine, I did the simple WHILE _MOUSEINPUT: WEND, and I thought that it didn't seem to work properly, hence my version.  Maybe I just didn't look correctly.  If WHILE _MOUSEINPUT:WEND is guaranteed to use up mouse clicks (it ought, I suppose), I'll use that in future.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #13 on: January 04, 2019, 08:12:16 am »
Ah!  My Use-Up-Mouse Routine mouse polling (_MOUSEINPUT) is NOT inside an umilited WHILE:WEND (whereas all my other mouse polling is).  I see Steve's concerns now.  Will change to WHILE _MOUSEINPUT: WEND

What a goon!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Is There a Mouse Equivalent of _KEYCLEAR?
« Reply #14 on: January 04, 2019, 10:01:27 am »
O Magnificent Gurus of the Great Spiritual Mouse, what then is the correct method for using up stray mouse clicks?  Pray, graciously enlighten your lowly, humble and ignorant follower.

From Steve (edited):
For a simple mouseclick type event, to see if an user has clicked inside a proper boundry for you, try something like this:

Code: QB64: [Select]
  1.     _LIMIT 60
  2.     CLS
  3.    
  4.             FOR i = 1 TO 3
  5.                 IF _MOUSEX >= Box(i).x AND _MOUSEX <= Box(i).x + 100 AND _MOUSEY >= Box(i).y AND _MOUSEY <= Box(i).y + 100 THEN 'we clicked a box
  6.                     Box(i).Click = Box(i).Click + 1
  7.                 END IF
  8.             NEXT
  9.     END IF
  10.     _DISPLAY
  11.  


Steve's mouse polling is inside a limited WHILE/WEND.

My code would look like:

Code: QB64: [Select]
  1. WHILE SomeCondition`
  2.     _LIMIT 60
  3.     'Do Something
  4.         IF _MOUSEBUTTON(1) THEN
  5.             'Set some flag
  6.         END IF
  7.     WEND
  8.     '_DISPLAY if display update required

The program actioning is inside a WHILE/WEND with a _LIMIT, but inside that the Mouse polling is inside an unlimited WHILE/WEND, and therfore there is no delay.  My Use-Up-Mouse Routine would be before the next required mouse polling.

When I first coded a use up mouse click routine, I did the simple WHILE _MOUSEINPUT: WEND, and I thought that it didn't seem to work properly, hence my version.  Maybe I just didn't look correctly.  If WHILE _MOUSEINPUT:WEND is guaranteed to use up mouse clicks (it ought, I suppose), I'll use that in future.

If you look, my mouse polling is in an unlimited WHILE: WEND, inside the DO:LOOP...

DO
   LIMIT
   WHILE _MOUSEINPUT: WEND
   IF _MOUSEBUTTON .....


Compared to your:

WHILE
   LIMIT
   WHILE _MOUSEINPUT
        IF _MOUSEBUTTON.....
   WEND



The mouse polls an unbelievable number of times each second.  Adding IF conditions and other code inside the update/polling routine is almost guaranteed to create a backlog of information to be processed, resulting in your program always racing to try and catch up to past events and getting stuck inside that loop much longer than you’d intend/want.

The best practice is:  WHILE _MOUSEINPUT: WEND.    It truly is the equivalent to _KEYCLEAR, for the mouse. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!