4343BUTTONS = ["left" , "right" , "middle" ]
4444
4545
46- def find_and_init_boot_mouse (cursor_image = "/launcher_assets/mouse_cursor.bmp" ):
46+ def find_and_init_boot_mouse (cursor_image = None ): # noqa: PLR0912
4747 """
4848 Scan for an attached boot mouse connected via USB host.
4949 If one is found initialize an instance of BootMouse class
5050 and return it.
51+
52+ :param cursor_image: Provide the absolute path to the desired cursor bitmap image. If not
53+ provided or set to `None`, the bitmap image included with this library will be used. If set as
54+ `False`, the BootMouse instance will not control a :class:`displayio.TileGrid`.
5155 :return: The BootMouse instance or None if no mouse was found.
5256 """
5357 mouse_interface_index , mouse_endpoint_address = None , None
@@ -100,18 +104,24 @@ def find_and_init_boot_mouse(cursor_image="/launcher_assets/mouse_cursor.bmp"):
100104 # set configuration on the mouse so we can use it
101105 mouse_device .set_configuration ()
102106
107+ # get path of included cursor bitmap
108+ if cursor_image is None :
109+ cursor_image = "/" .join (__file__ .split ("/" )[:- 1 ]) + "/mouse_cursor.bmp"
110+
103111 # load the mouse cursor bitmap
104- if not isinstance (cursor_image , str ):
105- raise TypeError ("cursor_image must be a string" )
106- mouse_bmp = OnDiskBitmap (cursor_image )
112+ if isinstance (cursor_image , str ):
113+ mouse_bmp = OnDiskBitmap (cursor_image )
107114
108- # make the background pink pixels transparent
109- mouse_bmp .pixel_shader .make_transparent (0 )
115+ # make the background pink pixels transparent
116+ mouse_bmp .pixel_shader .make_transparent (0 )
110117
111- # create a TileGrid for the mouse, using its bitmap and pixel_shader
112- mouse_tg = TileGrid (mouse_bmp , pixel_shader = mouse_bmp .pixel_shader )
118+ # create a TileGrid for the mouse, using its bitmap and pixel_shader
119+ mouse_tg = TileGrid (mouse_bmp , pixel_shader = mouse_bmp .pixel_shader )
120+
121+ else :
122+ mouse_tg = None
113123
114- return BootMouse (mouse_device , mouse_endpoint_address , mouse_tg , mouse_was_attached )
124+ return BootMouse (mouse_device , mouse_endpoint_address , mouse_was_attached , mouse_tg )
115125
116126 # if no mouse found
117127 return None
@@ -125,41 +135,55 @@ class BootMouse:
125135
126136 :param device: The usb device instance for the mouse
127137 :param endpoint_address: The address of the mouse endpoint
128- :param tilegrid: The TileGrid that holds the visible mouse cursor
129138 :param was_attached: Whether the usb device was attached to the kernel
139+ :param tilegrid: The TileGrid that holds the visible mouse cursor
130140 """
131141
132- def __init__ (self , device , endpoint_address , tilegrid , was_attached , scale = 1 ): # noqa: PLR0913, too many args
142+ def __init__ (self , device , endpoint_address , was_attached , tilegrid = None , scale = 1 ): # noqa: PLR0913, too many args
133143 self .device = device
134- self .tilegrid = tilegrid
135144 self .endpoint = endpoint_address
136145 self .buffer = array .array ("b" , [0 ] * 4 )
137146 self .was_attached = was_attached
147+ self .tilegrid = tilegrid
138148 self .scale = scale
139-
140- self .display_size = (supervisor .runtime .display .width , supervisor .runtime .display .height )
149+ if tilegrid is not None :
150+ self .display_size = (
151+ supervisor .runtime .display .width ,
152+ supervisor .runtime .display .height ,
153+ )
154+ self .tilegrid .x , self .tilegrid .y = (
155+ x // 2 for x in self .display_size
156+ ) # center cursor in display
157+ else :
158+ self ._x , self ._y = 0 , 0
141159
142160 @property
143161 def x (self ):
144162 """
145163 The x coordinate of the mouse cursor
146164 """
147- return self .tilegrid .x
165+ return self .tilegrid .x if self . tilegrid else self . _x
148166
149167 @x .setter
150168 def x (self , new_x ):
151- self .tilegrid .x = new_x
169+ if self .tilegrid :
170+ self .tilegrid .x = new_x
171+ else :
172+ self ._x = new_x
152173
153174 @property
154175 def y (self ):
155176 """
156177 The y coordinate of the mouse cursor
157178 """
158- return self .tilegrid .y
179+ return self .tilegrid .y if self . tilegrid else self . _y
159180
160181 @y .setter
161182 def y (self , new_y ):
162- self .tilegrid .y = new_y
183+ if self .tilegrid :
184+ self .tilegrid .y = new_y
185+ else :
186+ self ._y = new_y
163187
164188 def release (self ):
165189 """
@@ -188,14 +212,19 @@ def update(self):
188212 except usb .core .USBError :
189213 return None
190214
191- # update the mouse tilegrid x and y coordinates
215+ # update the mouse x and y coordinates
192216 # based on the delta values read from the mouse
193- self .tilegrid .x = max (
194- 0 , min ((self .display_size [0 ] // self .scale ) - 1 , self .tilegrid .x + self .buffer [1 ])
195- )
196- self .tilegrid .y = max (
197- 0 , min ((self .display_size [1 ] // self .scale ) - 1 , self .tilegrid .y + self .buffer [2 ])
198- )
217+ dx , dy = self .buffer [1 :3 ]
218+ if self .tilegrid :
219+ self .tilegrid .x = max (
220+ 0 , min ((self .display_size [0 ] // self .scale ) - 1 , self .tilegrid .x + dx )
221+ )
222+ self .tilegrid .y = max (
223+ 0 , min ((self .display_size [1 ] // self .scale ) - 1 , self .tilegrid .y + dy )
224+ )
225+ else :
226+ self ._x += dx
227+ self ._y += dy
199228
200229 pressed_btns = []
201230 for i , button in enumerate (BUTTONS ):
0 commit comments