Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Fruit_Jam/Larsio_Paint_Music/code.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

import time
import gc
import sys
import atexit
import supervisor
from sound_manager import SoundManager
from note_manager import NoteManager
from ui_manager import UIManager
Expand Down Expand Up @@ -86,6 +89,23 @@ def run(self):
gc.collect()
print("Starting Music Staff Application...")

def atexit_callback():
"""
re-attach USB devices to kernel if needed.
:return:
"""
print("inside atexit callback")
if app.ui_manager.input_handler.mouse is not None:
mouse = app.ui_manager.input_handler.mouse
mouse.release()
if mouse.was_attached:
# The keyboard buffer seems to have data left over from when it was detached
# This clears it before the next process starts
while supervisor.runtime.serial_bytes_available:
sys.stdin.read(1)

atexit.register(atexit_callback)

try:
app = MusicStaffApp(audio_output=AUDIO_OUTPUT)
app.run()
Expand All @@ -102,3 +122,5 @@ def run(self):
app.run()
except Exception as e2: # pylint: disable=broad-except
print(f"Fatal error: {e2}")

supervisor.reload()
5 changes: 4 additions & 1 deletion Fruit_Jam/Larsio_Paint_Music/input_handler.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# input_handler.py: CircuitPython Music Staff Application component
"""

from adafruit_usb_host_mouse import find_and_init_boot_mouse
from adafruit_usb_host_mouse import find_and_init_boot_mouse, find_and_init_report_mouse

# pylint: disable=invalid-name,no-member,too-many-instance-attributes,too-many-arguments
# pylint: disable=too-many-branches,too-many-statements,broad-except
Expand Down Expand Up @@ -34,6 +34,9 @@ def __init__(self, screen_width, screen_height, staff_y_start, staff_height):

def find_mouse(self):
self.mouse = find_and_init_boot_mouse(cursor_image=None)
if self.mouse is None:
self.mouse = find_and_init_report_mouse(cursor_image=None)

if self.mouse is None:
print("Failed to find a working mouse after multiple attempts")
return False
Expand Down
37 changes: 34 additions & 3 deletions Fruit_Jam/Larsio_Paint_Music/ui_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(self, sound_manager, note_manager):
self.triangle_cursor = None
self.tempo_minus_label = None
self.tempo_plus_label = None
self.exit_button_label = None

# Channel setting
self.current_channel = 0
Expand Down Expand Up @@ -124,6 +125,9 @@ def setup_display(self):
# Create tempo display
self._create_tempo_display()

# Add Exit button
self._create_exit_button()

# Create highlight
self.highlight_grid = self.staff_view.create_highlight()
self.main_group.append(self.highlight_grid)
Expand Down Expand Up @@ -206,6 +210,21 @@ def _create_note_name_label(self):
self.note_name_label.anchored_position = (10, self.SCREEN_HEIGHT - 70)
self.main_group.append(self.note_name_label)

def _create_exit_button(self):
"""Create a lable to be used as an "Exit" button"""
gc.collect()

self.exit_button_label = Label(
terminalio.FONT,
text="Exit",
color=0xFFFFFF,
background_color=0xFF0000,
scale=1
)
self.exit_button_label.anchor_point = (0.5, 0.5)
self.exit_button_label.anchored_position = (self.SCREEN_WIDTH - 135, 10)
self.main_group.append(self.exit_button_label)

def _create_tempo_display(self):
"""Create a label for the tempo display with + and - buttons"""
gc.collect() # Force garbage collection before creating the label
Expand Down Expand Up @@ -496,17 +515,26 @@ def handle_mouse_buttons(self):
# Check for tempo button clicks
minus_button_x, minus_button_y = self.tempo_minus_label.anchored_position
plus_button_x, plus_button_y = self.tempo_plus_label.anchored_position
exit_button_x, exit_button_y = self.exit_button_label.anchored_position
button_radius = 8 # Allow a bit of space around the button for easier clicking

# Radius 16**2 = 256, but squared to a y < 16
if (
((mouse_x - exit_button_x)**2 + (mouse_y - exit_button_y)**2) < 256 and
mouse_y < 16):

# Clicked Exit button
return False

if ((mouse_x - minus_button_x)**2 + (mouse_y - minus_button_y)**2) < button_radius**2:
# Clicked minus button - decrease tempo
self.adjust_tempo(-1)
return
return True

if ((mouse_x - plus_button_x)**2 + (mouse_y - plus_button_y)**2) < button_radius**2:
# Clicked plus button - increase tempo
self.adjust_tempo(1)
return
return True

# Check if a channel button was clicked
channel_clicked = False
Expand Down Expand Up @@ -565,6 +593,8 @@ def handle_mouse_buttons(self):
)
self.note_name_label.text = message

return True

def _add_note_based_on_channel(self, x, y):
"""Add a note based on the current channel"""
if self.current_channel == 0:
Expand Down Expand Up @@ -641,4 +671,5 @@ def main_loop(self):
self.handle_mouse_position()

# Handle mouse button presses
self.handle_mouse_buttons()
if not self.handle_mouse_buttons():
break