Author Topic: Mouse question  (Read 4141 times)

0 Members and 1 Guest are viewing this topic.

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Mouse question
« on: February 08, 2020, 04:32:36 am »
I'm going crazy!

I thought I had solved this question long, long ago and instead... no.
I searched the forum and saw many examples but still have problems.

Code: QB64: [Select]
  1. i=0    
  2.         if _MOUSEBUTTON(1) = -1 or _MOUSEBUTTON(2) = -1 or _MOUSEBUTTON(3) = -1 then i = 1
  3.    LOOP
  4. loop until inkey$ <> "" or i = 1

The code is easy to understand and works in all cases except one.

It does not work when you get to that point after clicking with the mouse, for example on a menu item.
Evidently the mouse buffer is not empty and by entering the do-loop it immediately passes over.

With the following code I think it is possible to clear the mouse buffer:

Code: QB64: [Select]
  1.     _LIMIT 60
  2.     x = _DEVICEINPUT(2)
  3.     WHILE _DEVICEINPUT(2): WEND 'clear the mouse buffer
  4.  

How to combine the two codes to get the following?
Exit the loop when:
1) having pressed any key
2) clicking on any mouse button

The problem (which is mine: I can't write the code!) occurs ONLY, as I said, when the mouse buffer is not empty.

The error is certainly subtle and small ... that's why it is difficult to find it. Will you help me please?








« Last Edit: February 08, 2020, 04:39:11 am 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: Mouse question
« Reply #1 on: February 08, 2020, 06:43:48 am »
Frankly, it does not seem to me an elegant solution, much less brilliant.
So it seems to work but I'm sure there is a better solution.

Well:

Code: QB64: [Select]
  1. i = 0
  2.    x = _DEVICEINPUT(2)
  3.    if _mouseinput = -1 then i = i +1
  4. LOOP UNTIL INKEY$ <>"" or (i > 5 and (_buttonchange(1)=-1 or _buttonchange(2)=-1 or _buttonchange(3)=-1))
  5.  


___

Advice (that you may already know): try a code 10 times. if it doesn't work, get up and go for a ride, maybe outdoors. then come back and try again...
I fall every time: before getting up I try 35,000 times and for many hours... even days!

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

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Mouse question
« Reply #2 on: February 08, 2020, 08:56:56 am »
Not sure if I'm understanding the problem completely here, just throwing this out for your consideration.

When I'm getting a mouse button input, I add the following code after I've gotten the result I want in order to stop accidental "click through" to other procedures that might read remnant clicks in the buffer.

While the code is specifically for mousebutton 1, it gives the basic idea.

Code: QB64: [Select]
  1.         WHILE _MOUSEINPUT: WEND
  2.     LOOP
  3.  

edit: added back the underscores for those not using $NOPREFIX
« Last Edit: February 08, 2020, 09:00:08 am by OldMoses »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Mouse question
« Reply #3 on: February 08, 2020, 11:49:49 am »
I mean in its simplest bare bones form...

Code: QB64: [Select]
  1.     _LIMIT 60
  2.     selkey$ = INKEY$
  3.     IF LEN(selkey$) THEN EXIT DO
  4. PRINT "Button or key press detected. Press any key to test again..."
  5. b$ = INKEY$ ' Clear keyboard buffer because RUN is buggy and doesn't do it!!!
  6.  

And as a continuous test...

Code: QB64: [Select]
  1.     DO
  2.         _LIMIT 60
  3.         selkey$ = INKEY$
  4.         IF LEN(selkey$) THEN EXIT DO
  5.         WHILE _MOUSEINPUT: WEND
  6.     LOOP
  7.     PRINT "Button or key press detected."
  8.     IF CSRLIN > 23 THEN CLS

You could also define the mouse actions to not execute until the buttons were released or execute when pressed, but not execute again until released Those "features" would require additional internal LOOPs.

Pete

Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse question
« Reply #4 on: February 08, 2020, 12:00:52 pm »
Quote
It does not work when you get to that point after clicking with the mouse, for example on a menu item.
Evidently the mouse buffer is not empty and by entering the do-loop it immediately passes over.

Here is Steve's oldMouse trick that after responding to a _MOUSEBUTTON waits for a release of that button before responding to a (new) click:

Demo menu in screen 0:
Code: QB64: [Select]
  1.     CLS
  2.     PRINT "Press menu # key or click menu item:"
  3.     FOR m = 1 TO 8
  4.         ms$ = _TRIM$(STR$(m))
  5.         PRINT ms$; ") Menu item "; ms$
  6.     NEXT
  7.     PRINT "9) Quit this demo"
  8.     mx = _MOUSEX: my = _MOUSEY
  9.     k$ = INKEY$
  10.     PRINT
  11.     PRINT "INKEY$:"; k$; "   _MOUSEBUTTON(X) pressed "; mb; "  Current _MOUSEX"; mx; "  Current _MOUSEY"; my
  12.     PRINT
  13.     IF mb AND oldMouse = 0 OR LEN(k$) THEN
  14.         FOR m = 1 TO 9
  15.             IF mb AND my = m + 1 OR k$ = _TRIM$(STR$(m)) THEN 'for screen 0 or default my = line number
  16.                 PRINT "You selected menu"; m: _DELAY 2
  17.                 IF m = 9 THEN SYSTEM
  18.             END IF
  19.         NEXT
  20.     END IF
  21.  
  22.  
  23.  
  24.     oldMouse = mb ' <<<<<<<<<<<<  comment on and off to see difference when hold mouse button down and go up and down menu
  25.     '               oldMouse will wait until you release mousebutton before accepting another menu selection
  26.  
  27.  
  28.     _LIMIT 60
  29.  
  30.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Mouse question
« Reply #5 on: February 08, 2020, 12:35:14 pm »
Yep, it all depends on what you need to do. For instance, some programs require timers to detect double clicks. Some can have loops to wait for press release combos, but like Mark's example using Steve's code, you might need that flow-through ability, which allows for other events to not be held up by a prolonged mouse action. Drag and drop, or drag to highlight are other mouse coding events you could add, if needed. All of these require the user think through what is required first, and then build an engine to support those requirements. Hell, I should talk. I've done all of the above and got there mostly by run and gun. :D

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline krovit

  • Forum Regular
  • Posts: 179
    • View Profile
Re: Mouse question
« Reply #6 on: February 11, 2020, 07:27:21 am »
Thank you for your contributions!

This 3D has become a useful catalog of solutions to manage the mouse and keyboard.

I have not verified all the examples but I can confirm that when the mouse buffer is not null they do NOT work as we would expect.  I confirm that the solution I inserted in any case.

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

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Mouse question
« Reply #7 on: February 12, 2020, 08:16:27 pm »
Strange!

It doesn't clear the buffer of mouse! The oldX and x are the same, and so for OldY and y.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(600, 800, 32)
  2.         Omx = _MOUSEX
  3.         Omy = _MOUSEY
  4.         DO WHILE _MOUSEINPUT: LOOP ' clear mouse buffer or no?
  5.         LOCATE 10, 1: PRINT _MOUSEX, _MOUSEY
  6.         LOCATE 11, 1: PRINT Omx, Omy
  7.     END IF
  8.  
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Mouse question
« Reply #8 on: February 13, 2020, 02:19:20 pm »
going deeper!
it seems that the _mouseinput event is so much in a second that we must stop the time for a bit to see that just for that so little bit mouse buffer is empty

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(600, 800, 32)
  2.         Omx = _MOUSEX
  3.         Omy = _MOUSEY
  4.         DO WHILE _MOUSEINPUT
  5.  
  6.         LOOP ' clear mouse buffer
  7.         LOCATE 10, 1: PRINT _MOUSEX, _MOUSEY
  8.         LOCATE 11, 1: PRINT Omx, Omy
  9.         IF NOT _MOUSEX = Omx THEN _DELAY .5
  10.         IF NOT _MOUSEY = Omy THEN _DELAY .5
  11.     END IF
so it seems that the solution is to put a _delay into the clear buffer loop!

Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Mouse question
« Reply #9 on: February 13, 2020, 02:54:03 pm »
Why does it seem everyone always makes mouse input so complicated?

Code: QB64: [Select]
  1.     WHILE _MOUSEINPUT: WEND ‘Update the mouse
  2.     MBIND = _MOUSEBUTTON(1) ‘Mouse Button Is Now Down
  3.     IF MBWU AND MBIND THENIf Mouse Button Was Up AND Mouse Button Is Now Down
  4.         PRINT “You clicked the button!”
  5.     END IF
  6.     MBWU = NOT MBIND ‘Mouse Button Was Up
  7.     _LIMIT 30
  8.  

Mouse input, by itself, is a very simple thing.  Basically, all the commands tell us is:  Where’s the cursor and which buttons are up and down.

It’s up to the programmer to setermine what their program actually needs to function properly. 

In a game, you might just want to know if the button is up or down to shoot at enemies.

You might need a “click event” for a button — so you need to decide exactly what qualifies as a click event in your program.  My example above may not suit your needs, if you need a click to be counted as an “UP-DOWN-UP” event.  All my little demo above worries about is “was it up, and is it now down?; it doesn’t track “is it now up again?”

Decide what you need for your mouse events and then code for them. 

Click — Up, Down.
Double Click — Click + Click within X miliseconds.
Down and Hold — Down for X+ miliseconds
Hover — Up for X seconds without mouse x/y changing

And so on...
« Last Edit: February 13, 2020, 03:07:51 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Mouse question
« Reply #10 on: February 13, 2020, 04:07:03 pm »
Thanks Steve
you're right!
For my problem I have had searched where to put loop washing out buffer of mouse and how to solve the bad passage through it!
My problem (now solved thanks to your encouragement) is a simple issue to put (more bad app design than bad coding) in the same place two different buttons that are activated in different but sequential events... so when the user did click on the first button it activated the second button in the same place of the first and the program activated also the second button as clicked!
A bad event cascade! :-)
Programming isn't difficult, only it's  consuming time and coffee