After Richard suggested a ON MOUSE solution to the calculator, I studied the information in help docs and created this sample:
IT WORKS WELL.. A random line gets drawn every time you left click the box, BUT it wont draw more than one as long as the mouse button remains pressed.
This will be handy in future projects.
Thanks for the suggestion Richard.
REM ON MOUSE experiment (non repeating key test)
MODE 8 :REM a graphics mode you could use
VDU 5 :REM make text placing of high res pixel location
REM lets work with the core colors (default GCOL 0-15)
GCOL 15
MOVE 100,100:PRINT "left click on the box and hold for 2 seconds"
RECTANGLE 200,200,50,50
REPEAT
ON MOUSE PROCmouse(@wparam%,@lparam%):RETURN :REM required
WAIT 5
UNTIL FALSE
END
DEFPROCmouse(mb%,mloc%)
LOCAL xpos%,ypos%,y%
REM @lparam% is a BBC Basic variable holding the location of your mouse
REM lets extract the locations into BBC Basic graphics coordinates with xpos% horizontal and ypos% vertical coordinates
xpos% = (@lparam% AND &FFFF) *2 - @vdu.o.x%
ypos% = (@vdu%!212-1-(@lparam% >>> 16))*2 - @vdu.o.y%
REM now we check the area (200,200,250,250) for mouse presence and left button)
IF xpos%> 200 AND ypos%>200 AND xpos%< 250 AND ypos%<250 AND mb%=1 THEN
REM if a unique mouse button is held it only will make 1 line
LINE 250,250,250+RND(500),250+RND(500)
ENDIF
REM if the mouse button is released then another button interface can occur and more lines made
ENDPROC
Focus is on code subject. Feel free to judge the quality of my work.
I agree using ON MOUSE can be useful, but you should be aware of a couple of factors:
1) The event is generated by PRESSING the button, not by releasing it. Most software uses the position where you RELEASE the button to determine what happens (so if you click down over the 8 button on your calculator, for example, it will return 8, even if you then "drag" over the 9. Most software would return the 9, I think. The event you are triggering will also happen immediately on the press down, not on the release, which is usually the case.
2) Using the interrupt routines only takes effect after the completion of the current BASIC command, so if you are in the middle of a WAIT/INPUT/INKEY/GET/SOUND etc there may be a delay which may not be appropriate. As noted in the manual, there is the NOWAIT library to get round this!
Richard made the points below relating to my last post: His comment about using ON MOUSE in conjunction with subsequent MOUSE x,y,z statements to determine the "mouse up" situation is exactly what I had in mind, but should perhaps have made more explicit. My comments on interrupts were drawn essentially straight from the manual, and were meant as a general caution about using interrupts, but I can see that in this situation it is unlikely to be an issue.
Best wishes,
D
> The event is generated by PRESSING the button, not by releasing it.
> Most software uses the position where you RELEASE the button to determine what happens
Whilst that is true, it isn't a reason not to use ON MOUSE. In applications like the Calculator, when a single click of the mouse (or tap of the finger) needs to result in *exactly one* action, ON MOUSE is the only acceptable approach.
This fundamentally comes down to the difference between a 'state' and an 'event'. The 'MOUSE x,y,b' statement tests the state of the mouse, specifically whether a button is currently pressed or not. This means that, depending on how long you keep the mouse button pressed, it may not be detected at all (if the button is pressed for a time shorter than the period between two consecutive MOUSE statements) or it may be detected multiple times (if the button is pressed for a longer time).
There is simply no way that, by polling with MOUSE, you can reliably detect a single press, just once, irrespective of how short or long a time it is kept pressed, which is what you need for a calculator. What you should be responding to is an event and not a state, and in BB4W and BBCSDL the statement which detects a mouse event is ON MOUSE: it is guaranteed to activate its handler just once for each individual mouse click.
If you are concerned that the action should take place on releasing rather than on pressing the mouse button (and I'm not convinced that it is as essential and universal as you suggest) then you can easily achieve that by using ON MOUSE in conjunction with a subsequent MOUSE.
When the ON MOUSE event has detected the press you can spin in MOUSE until you see that the button has been released; the 'exactly one event for each click' behaviour can be maintained.
If the implication is that ON MOUSE works incorrectly, and should trigger its event on a release, I would point out two things. Firstly, it has worked the same way since BB4W was first released, nearly 17 years ago, and I don't remember anybody having made that criticism before. Secondly, generating an event only on release would be less flexible because if you wanted to take some action on the press you couldn't (of course ON MOUSE could have generated an event on both press and release, but that would make it trickier to use).
> Using the interrupt routines only takes effect after the completion of the current BASIC command, so if you are in the middle of a WAIT/INPUT/INKEY/GET/SOUND etc there may be a delay which may not be appropriate
I'm afraid that doesn't make much sense to me. We are discussing the pros and cons of using ON MOUSE rather than MOUSE. If you are polling the state of the mouse using 'MOUSE x,y,b' then not only will the click not be detected until the end of the current statement, it won't be detected until the next MOUSE statement is executed (or indeed it may not be detected at all: an 'infinite' delay): the potential for an 'inappropriate' delay is therefore much *greater* than it is with ON MOUSE, not less!
If the delay resulting from ON MOUSE is unacceptable I don't know what alternative you are proposing, because there is no mechanism available to you in BBC BASIC to reduce it any further. You could perhaps run an assembly language routine in a high-priority thread, but even if that can detect a mouse click with less latency what is it supposed to do with it once it has happened?
I ON MOUSE is satisfactory for button interaction for me. MOUSE x,y,b is still useful for scrolling and drawing and other things, so each command is legit. Thanks Richard and DDRM for your wisdom. These new discoveries will advance the quality of future projects.
Focus is on code subject. Feel free to judge the quality of my work.