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.