Blog Post

Small Basic Blog
2 MIN READ

Small Basic - Mouse Position

Ed Price's avatar
Ed Price
Former Employee
Feb 12, 2019
First published on MSDN on Nov 22, 2014

Authored by LitDev


Mouse Position Methods


There are 2 ways to get the position of the mouse cursor in Small Basic.



gwX = GraphicsWindow . MouseX

gwY = GraphicsWindow . MouseY


mX = Mouse . MouseX

mY = Mouse . MouseY


GraphicsWindow.MouseX(Y)


The GraphicsWindow variant gets the X and Y coordinates of the mouse cursor relative to the top left corner of the GraphicsWindow.  These coordinates are the same as pixel coordinates within the GraphicsWindow.  We can then use these to move a shape within the GraphicsWindow or otherwise detect and use the current mouse position within the GraphicsWindow.


Recall that (X,Y) coordinates are X pixels from the left and Y pixels from the top.



ball = Shapes . AddEllipse ( 50 , 50 )

While ( "True" )

Shapes . Move ( ball , GraphicsWindow . MouseX - 25 , GraphicsWindow . MouseY - 25 )

Program . Delay ( 20 )

EndWhile


Mouse.MouseX(Y)


The Mouse variant is less commonly used and it gets the X and Y coordinates of the mouse cursor relative to the top left of the desktop, even if no GraphicsWindow is present.


One feature of the Mouse variant is that we can also change or move the mouse cursor to any coordinates we want on the desktop.  The GraphicsWindow variant cannot be used to set the mouse position.


We can find a dispacement (offset) between the desktop and GraphicsWindow coordinates to position the cursur as we want within the GraphicsWindow.



'Position Mouse over a ball

ball = Shapes . AddEllipse ( 50 , 50 )

While ( "True" )

xPos = 25 + Math . GetRandomNumber ( GraphicsWindow . Width - 50 )

yPos = 25 + Math . GetRandomNumber ( GraphicsWindow . Height - 50 )

Shapes . Move ( ball , xPos - 25 , yPos - 25 )

offsetX = Mouse . MouseX - GraphicsWindow . MouseX

offsetY = Mouse . MouseY - GraphicsWindow . MouseY

Mouse . MouseX = offsetX + xPos

Mouse . MouseY = offsetY + yPos

Program . Delay ( 2000 ) 'Plenty delay to end program!

EndWhile


Problem


The code above doesn't work as we might hope, see Mouse Object Bug forum post for Jibba Jabba's original identification of this problem.


Solution


After some playing I determined that the problem lies in the fact that there is a device dependent scaling difference between GraphicsWindow and Mouse coordinates.


On my display each GraphicsWindow pixel is equal to 1.25 Mouse (device) pixels.


So here is my fix.



'Position Mouse over a ball

ball = Shapes . AddEllipse ( 50 , 50 )

scale = 1.25

While ( "True" )

xPos = 25 + Math . GetRandomNumber ( GraphicsWindow . Width - 50 )

yPos = 25 + Math . GetRandomNumber ( GraphicsWindow . Height - 50 )

Shapes . Move ( ball , xPos - 25 , yPos - 25 )

offsetX = Mouse . MouseX / scale - GraphicsWindow . MouseX

offsetY = Mouse . MouseY / scale - GraphicsWindow . MouseY

Mouse . MouseX = scale * ( offsetX + xPos )

Mouse . MouseY = scale * ( offsetY + yPos )

Program . Delay ( 2000 ) 'Plenty delay to end program!

EndWhile


If the cursor starts outside the GraphcsWindow then it fails (not surprisingly) and in general the scaling may be different for different monitors or display devices.


Also note that the GraphicsWindow coordinates are only updated when the mouse moves (reasonable), but it is done asynchronously and may take a millisecond or so to update and be out of sync with our code.  This slight delay effect initially misled me and also confused the issue when Jibba Jabba was trying to find a workaround.


So I guess this is a bug, not a feature.

Published Feb 12, 2019
Version 1.0
No CommentsBe the first to comment