|
17 | 17 | """ |
18 | 18 |
|
19 | 19 | import gc |
| 20 | +import sys |
20 | 21 | import time |
21 | 22 | import supervisor |
| 23 | +import atexit |
22 | 24 | import board |
23 | 25 | import displayio |
| 26 | +import terminalio |
| 27 | +from adafruit_display_text import label |
24 | 28 |
|
25 | 29 | try: |
26 | | - from adafruit_usb_host_mouse import find_and_init_boot_mouse |
| 30 | + from adafruit_usb_host_mouse import find_and_init_boot_mouse, find_and_init_report_mouse |
27 | 31 | usb_available = True |
28 | 32 | except ImportError: |
29 | 33 | usb_available = False |
@@ -208,13 +212,16 @@ def __init__(self, splash, cursor_bmp, screen_width, screen_height, sensitivity= |
208 | 212 | def find_mouse(self): # pylint: disable=too-many-statements, too-many-locals |
209 | 213 | """Find and initialize the USB mouse.""" |
210 | 214 | self.mouse = find_and_init_boot_mouse() |
| 215 | + if self.mouse is None: |
| 216 | + self.mouse = find_and_init_report_mouse() |
| 217 | + self.sensitivity = 1 |
211 | 218 | if self.mouse is None: |
212 | 219 | print("No mouse found.") |
213 | 220 | return False |
214 | 221 |
|
215 | 222 | # Change the mouse resolution so it's not too sensitive |
216 | 223 | self.mouse.display_size = (supervisor.runtime.display.width*self.sensitivity, |
217 | | - supervisor.runtime.display.height*self.sensitivity) |
| 224 | + (supervisor.runtime.display.height - terminalio.FONT.get_bounding_box()[1])*self.sensitivity) |
218 | 225 | return True |
219 | 226 |
|
220 | 227 | def poll(self): |
@@ -324,12 +331,24 @@ def _cursor_bitmap_3(): |
324 | 331 |
|
325 | 332 | self._display = display |
326 | 333 | self._w = self._display.width |
327 | | - self._h = self._display.height |
| 334 | + self._h = self._display.height - terminalio.FONT.get_bounding_box()[1] |
328 | 335 | self._x = self._w // 2 |
329 | 336 | self._y = self._h // 2 |
330 | 337 |
|
331 | 338 | self._splash = displayio.Group() |
332 | 339 |
|
| 340 | + self._info_label = label.Label( |
| 341 | + terminalio.FONT, |
| 342 | + text = "Right Click->Palette:Exit Right Click->Canvas:Fill"[:self._w], |
| 343 | + color = 0xFFFFFF, |
| 344 | + x = 0, |
| 345 | + y = self._h |
| 346 | + ) |
| 347 | + self._info_label.anchor_point = (0.0, 1.0) |
| 348 | + self._info_label.anchored_position = (2, display.height - 2) |
| 349 | + |
| 350 | + self._splash.append(self._info_label) |
| 351 | + |
333 | 352 | self._bg_bitmap = displayio.Bitmap(self._w, self._h, 1) |
334 | 353 | self._bg_palette = displayio.Palette(1) |
335 | 354 | self._bg_palette[0] = Color.BLACK |
@@ -386,7 +405,7 @@ def _cursor_bitmap_3(): |
386 | 405 | if not self._poller.mouse: |
387 | 406 | raise RuntimeError("No mouse found. Please connect a USB mouse.") |
388 | 407 | else: |
389 | | - raise AttributeError("PyPaint requires a touchscreen or cursor.") |
| 408 | + raise AttributeError("PyPaint requires a mouse, touchscreen or cursor.") |
390 | 409 |
|
391 | 410 | self._a_pressed = False |
392 | 411 | self._last_a_pressed = False |
@@ -603,6 +622,8 @@ def _handle_b_release(self, location): |
603 | 622 | if location[0] >= self._w // 10: # not in color picker |
604 | 623 | self._fill(location[0], location[1], self._pencolor) |
605 | 624 | self._poller.poke() |
| 625 | + else: |
| 626 | + supervisor.reload() |
606 | 627 |
|
607 | 628 | @property |
608 | 629 | def _was_a_just_pressed(self): |
@@ -646,6 +667,23 @@ def run(self): |
646 | 667 | self._handle_motion(self._last_location, self._location) |
647 | 668 | time.sleep(0.1) |
648 | 669 |
|
649 | | - |
650 | 670 | painter = Paint() |
| 671 | + |
| 672 | +def atexit_callback(): |
| 673 | + """ |
| 674 | + re-attach USB devices to kernel if needed. |
| 675 | + :return: |
| 676 | + """ |
| 677 | + print("inside atexit callback") |
| 678 | + if type(painter._poller) == MousePoller: |
| 679 | + mouse = painter._poller.mouse |
| 680 | + if mouse.was_attached and not mouse.device.is_kernel_driver_active(0): |
| 681 | + mouse.device.attach_kernel_driver(0) |
| 682 | + # The keyboard buffer seems to have data left over from when it was detached |
| 683 | + # This clears it before the next process starts |
| 684 | + while supervisor.runtime.serial_bytes_available: |
| 685 | + sys.stdin.read(1) |
| 686 | + |
| 687 | +atexit.register(atexit_callback) |
| 688 | + |
651 | 689 | painter.run() |
0 commit comments