Skip to content

Commit 024885e

Browse files
committed
displayio cursor mouse circuitpython example
1 parent b8f6058 commit 024885e

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
"""
4+
This example is made for a basic boot mouse with
5+
two buttons and a wheel that can be pressed.
6+
7+
It assumes there is a single mouse connected to USB Host,
8+
and no other devices connected.
9+
"""
10+
import array
11+
from displayio import Group, OnDiskBitmap, TileGrid
12+
import supervisor
13+
import terminalio
14+
import usb.core
15+
from adafruit_display_text.bitmap_label import Label
16+
import adafruit_usb_host_descriptors
17+
18+
display = supervisor.runtime.display
19+
20+
# group to hold visual elements
21+
main_group = Group()
22+
23+
# make the group visible on the display
24+
display.root_group = main_group
25+
26+
# load the mouse cursor bitmap
27+
mouse_bmp = OnDiskBitmap("mouse_cursor.bmp")
28+
29+
# make the background pink pixels transparent
30+
mouse_bmp.pixel_shader.make_transparent(0)
31+
32+
# create a TileGrid for the mouse, using its bitmap and pixel_shader
33+
mouse_tg = TileGrid(mouse_bmp, pixel_shader=mouse_bmp.pixel_shader)
34+
35+
# move it to the center of the display
36+
mouse_tg.x = display.width // 2
37+
mouse_tg.y = display.height // 2
38+
39+
# text label to show the x, y coordinates on the screen
40+
output_lbl = Label(
41+
terminalio.FONT, text=f"{mouse_tg.x},{mouse_tg.y}", color=0xFFFFFF, scale=1
42+
)
43+
44+
# move it to the upper left corner
45+
output_lbl.anchor_point = (0, 0)
46+
output_lbl.anchored_position = (1, 1)
47+
48+
# add it to the main group
49+
main_group.append(output_lbl)
50+
51+
# add the mouse tile grid to the main group
52+
main_group.append(mouse_tg)
53+
54+
# button names
55+
# This is ordered by bit position.
56+
BUTTONS = ["left", "right", "middle"]
57+
58+
# scan for connected USB device and loop over any found
59+
for device in usb.core.find(find_all=True):
60+
# print device info
61+
print(f"{device.idVendor:04x}:{device.idProduct:04x}")
62+
print(device.manufacturer, device.product)
63+
print(device.serial_number)
64+
65+
# try to find mouse endpoint on the current device.
66+
mouse_interface_index, mouse_endpoint_address = (
67+
adafruit_usb_host_descriptors.find_boot_mouse_endpoint(device)
68+
)
69+
if mouse_interface_index is not None and mouse_endpoint_address is not None:
70+
mouse = device
71+
print(
72+
f"mouse interface: {mouse_interface_index} "
73+
+ f"endpoint_address: {hex(mouse_endpoint_address)}"
74+
)
75+
76+
# detach the kernel driver if needed
77+
if mouse.is_kernel_driver_active(0):
78+
mouse.detach_kernel_driver(0)
79+
80+
# set configuration on the mouse so we can use it
81+
mouse.set_configuration()
82+
83+
break
84+
85+
# buffer to hold mouse data
86+
buf = array.array("b", [0] * 8)
87+
88+
# main loop
89+
while True:
90+
try:
91+
# attempt to read data from the mouse
92+
# 20ms timeout, so we don't block long if there
93+
# is no data
94+
count = mouse.read(0x81, buf, timeout=20)
95+
except usb.core.USBTimeoutError:
96+
# skip the rest of the loop if there is no data
97+
continue
98+
99+
# update the mouse tilegrid x and y coordinates
100+
# based on the delta values read from the mouse
101+
mouse_tg.x = max(0, min(display.width - 1, mouse_tg.x + buf[1]))
102+
mouse_tg.y = max(0, min(display.height - 1, mouse_tg.y + buf[2]))
103+
104+
# string with updated coordinates for the text label
105+
out_str = f"{mouse_tg.x},{mouse_tg.y}"
106+
107+
# loop over the button names
108+
for i, button in enumerate(BUTTONS):
109+
# check if each button is pressed using bitwise AND shifted
110+
# to the appropriate index for this button
111+
if buf[0] & (1 << i) != 0:
112+
# append the button name to the string to show if
113+
# it is being clicked.
114+
out_str += f" {button}"
115+
116+
# update the text label with the new coordinates
117+
# and buttons being pressed
118+
output_lbl.text = out_str
Binary file not shown.

0 commit comments

Comments
 (0)