BUTTON_LABEL_COLOR = 0x000000 #--| Button Config |------------------------------------------------- # Setup touchscreen (PyPortal) ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR, board.TOUCH_YD, board.TOUCH_YU, calibration=((5200, 59000), (5800, 57000)), size=(320, 240)) # Make the display context splash = displayio.Group() board.DISPLAY.show(splash) # Make the button button = Button(x=BUTTON_X, y=BUTTON_Y, width=BUTTON_WIDTH, height=BUTTON_HEIGHT, style=BUTTON_STYLE, fill_color=BUTTON_FILL_COLOR, outline_color=BUTTON_OUTLINE_COLOR, label="HELLO WORLD", label_font=terminalio.FONT, label_color=BUTTON_LABEL_COLOR) # Add button to the display context splash.append(button.group) # Loop and look for touches while True: p = ts.touch_point if p: if button.contains(p): button.selected = True else: button.selected = False
width=40, height=40, label=i['label'], label_font=font, style=Button.SHADOWROUNDRECT) buttons.append(button) # add buttons to the group for b in buttons: button_group.append(b.group) while True: touch = ts.touch_point if touch: for i, button in enumerate(buttons): if button.contains(touch): button.selected = True if button.name == 'lamp': current_light = lifx_lights[0] print('Switching to ', current_light) elif button.name == 'room': current_light = lifx_lights[1] print('Switching to ', current_light) elif button.name == 'onoff': print('Toggling {0}...'.format(current_light)) lifx.toggle_light(current_light) elif button.name == 'up': light_brightness += 0.25 print('Setting {0} brightness to {1}'.format( current_light, light_brightness)) lifx.set_brightness(current_light, light_brightness)
class PYOA_Graphics: # pylint: disable=too-many-instance-attributes """A choose your own adventure game framework.""" def __init__(self) -> None: self.root_group = displayio.Group() self._display = board.DISPLAY self._background_group = displayio.Group() self.root_group.append(self._background_group) self._text_group = displayio.Group() self.root_group.append(self._text_group) self._button_group = displayio.Group() self.root_group.append(self._button_group) if self._display.height > 250: self._text_group.scale = 2 self._button_group.scale = 2 self._speaker_enable = DigitalInOut(board.SPEAKER_ENABLE) self._speaker_enable.switch_to_output(False) if hasattr(board, "AUDIO_OUT"): self.audio = audioio.AudioOut(board.AUDIO_OUT) elif hasattr(board, "SPEAKER"): self.audio = audioio.AudioOut(board.SPEAKER) else: raise AttributeError("Board does not have an audio output!") self._background_file = None self._wavfile = None self._display.auto_brightness = False self.backlight_fade(0) self._display.show(self.root_group) self.touchscreen = None self.mouse_cursor = None if hasattr(board, "TOUCH_XL"): self.touchscreen = adafruit_touchscreen.Touchscreen( board.TOUCH_XL, board.TOUCH_XR, board.TOUCH_YD, board.TOUCH_YU, calibration=((5200, 59000), (5800, 57000)), size=(self._display.width, self._display.height), ) elif hasattr(board, "BUTTON_CLOCK"): self.mouse_cursor = Cursor(self._display, display_group=self.root_group, cursor_speed=8) self.cursor = CursorManager(self.mouse_cursor) else: raise AttributeError("PYOA requires a touchscreen or cursor.") self._gamedirectory = None self._gamefilename = None self._game = None self._text = None self._background_sprite = None self._text_font = None self._left_button = None self._right_button = None self._middle_button = None def load_game(self, game_directory: str) -> None: """Load a game. :param str game_directory: where the game files are stored """ self._gamedirectory = game_directory self._text_font = terminalio.FONT # Possible Screen Sizes are: # 320x240 PyPortal and PyPortal Pynt # 160x128 PyBadge and PyGamer # 480x320 PyPortal Titano # 240x240 if we wanted to use HalloWing M4 # Button Attributes btn_left = 10 btn_right = btn_left + 180 btn_mid = btn_left + 90 button_y = 195 button_width = 120 button_height = 40 if self._display.height < 200: button_y //= 2 button_y += 10 button_width //= 2 button_height //= 2 btn_right //= 2 btn_mid //= 2 elif self._display.height > 250: button_y = (button_y * 3) // 4 button_y -= 20 button_width = (button_width * 3) // 4 button_height = (button_height * 3) // 4 btn_right = (btn_right * 3) // 4 btn_mid = (btn_right * 3) // 4 self._left_button = Button( x=btn_left, y=button_y, width=button_width, height=button_height, label="Left", label_font=self._text_font, style=Button.SHADOWROUNDRECT, ) self._right_button = Button( x=btn_right, y=button_y, width=button_width, height=button_height, label="Right", label_font=self._text_font, style=Button.SHADOWROUNDRECT, ) self._middle_button = Button( x=btn_mid, y=button_y, width=button_width, height=button_height, label="Middle", label_font=self._text_font, style=Button.SHADOWROUNDRECT, ) self._gamefilename = game_directory + "/cyoa.json" try: with open( # pylint: disable=unspecified-encoding self._gamefilename, "r") as game_file: self._game = json.load(game_file) except OSError as err: raise OSError("Could not open game file " + self._gamefilename) from err def _fade_to_black(self) -> None: """Turn down the lights.""" if self.mouse_cursor: self.mouse_cursor.is_hidden = True self.backlight_fade(0) # turn off background so we can render the text self.set_background(None, with_fade=False) self.set_text(None, None) for _ in range(len(self._button_group)): self._button_group.pop() if self.mouse_cursor: self.mouse_cursor.is_hidden = False def _display_buttons(self, card: Dict[str, str]) -> None: """Display the buttons of a card. :param card: The active card :type card: dict(str, str) """ button01_text = card.get("button01_text", None) button02_text = card.get("button02_text", None) self._left_button.label = button01_text self._middle_button.label = button01_text self._right_button.label = button02_text if button01_text and not button02_text: # show only middle button self._button_group.append(self._middle_button) if button01_text and button02_text: self._button_group.append(self._right_button) self._button_group.append(self._left_button) def _display_background_for(self, card: Dict[str, str]) -> None: """If there's a background on card, display it. :param card: The active card :type card: dict(str, str) """ self.set_background(card.get("background_image", None), with_fade=False) def _display_text_for(self, card: Dict[str, str]) -> None: """Display the main text of a card. :param card: The active card :type card: dict(str, str) """ text = card.get("text", None) text_color = card.get("text_color", 0x0) # default to black text_background_color = card.get("text_background_color", None) if text: try: text_color = int( text_color) # parse the JSON string to hex int except ValueError: text_color = 0x0 try: text_background_color = int( text_background_color) # parse the JSON string to hex int except ValueError: text_background_color = None except TypeError: text_background_color = None self.set_text(text, text_color, background_color=text_background_color) def _play_sound_for(self, card: Dict[str, str]) -> None: """If there's a sound, start playing it. :param card: The active card :type card: dict(str, str) """ sound = card.get("sound", None) loop = card.get("sound_repeat", False) if sound: loop = loop == "True" print("Loop:", loop) self.play_sound(sound, wait_to_finish=False, loop=loop) def _wait_for_press(self, card: Dict[str, str]) -> str: """Wait for a button to be pressed. :param card: The active card :type card: dict(str, str) :return: The id of the destination card :rtype: str """ button01_text = card.get("button01_text", None) button02_text = card.get("button02_text", None) point_touched = None while True: if self.touchscreen is not None: point_touched = self.touchscreen.touch_point else: self.cursor.update() if self.cursor.is_clicked is True: point_touched = self.mouse_cursor.x, self.mouse_cursor.y if point_touched is not None: point_touched = ( point_touched[0] // self._button_group.scale, point_touched[1] // self._button_group.scale, ) print("touch: ", point_touched) if button01_text and not button02_text: # showing only middle button if self._middle_button.contains(point_touched): print("Middle button") return card.get("button01_goto_card_id", None) if button01_text and button02_text: if self._left_button.contains(point_touched): print("Left button") return card.get("button01_goto_card_id", None) if self._right_button.contains(point_touched): print("Right button") return card.get("button02_goto_card_id", None) time.sleep(0.1) def display_card(self, card_num: int) -> int: """Display and handle input on a card. :param int card_num: the index of the card to process :return: the card number of the selected card :rtype: int """ card = self._game[card_num] print(card) print("*" * 32) print("****{:^24s}****".format(card["card_id"])) print("*" * 32) self._fade_to_black() self._display_buttons(card) self._display_background_for(card) self.backlight_fade(1.0) self._display_text_for(card) self._display.refresh(target_frames_per_second=60) self._play_sound_for(card) auto_adv = card.get("auto_advance", None) if auto_adv is not None: auto_adv = float(auto_adv) print("Auto advancing after %0.1f seconds" % auto_adv) time.sleep(auto_adv) return card_num + 1 destination_card_id = self._wait_for_press(card) self.play_sound(None) # stop playing any sounds for card_number, card_struct in enumerate(self._game): if card_struct.get("card_id", None) == destination_card_id: return card_number # found the matching card! # eep if we got here something went wrong raise RuntimeError("Could not find card with matching 'card_id': ", destination_card_id) def play_sound(self, filename: Optional[str], *, wait_to_finish: bool = True, loop: bool = False) -> None: """Play a sound :param filename: The filename of the sound to play. Use `None` to stop playing anything. :type filename: str or None :param bool wait_to_finish: Whether playing the sound should block :param bool loop: Whether the sound should loop """ self._speaker_enable.value = False self.audio.stop() if self._wavfile: self._wavfile.close() self._wavfile = None if not filename: return # nothing more to do, just stopped filename = self._gamedirectory + "/" + filename print("Playing sound", filename) self._display.refresh(target_frames_per_second=60) try: self._wavfile = open(filename, "rb") # pylint: disable=consider-using-with except OSError as err: raise OSError("Could not locate sound file", filename) from err wavedata = audiocore.WaveFile(self._wavfile) self._speaker_enable.value = True self.audio.play(wavedata, loop=loop) if loop or not wait_to_finish: return while self.audio.playing: pass self._wavfile.close() self._wavfile = None self._speaker_enable.value = False def set_text( self, text: Optional[str], color: Optional[str], background_color: Optional[int] = None, ) -> None: """Display the test for a card. :param text: the text to display :type text: str or None :param color: the text color :type color: str or None :param background_color: the background color of the text :type background_color: int or None """ if self._text_group: self._text_group.pop() if not text or not color: return # nothing to do! text_wrap = 37 if self._display.height < 130: text_wrap = 25 text = self.wrap_nicely(text, text_wrap) text = "\n".join(text) print("Set text to", text, "with color", hex(color)) text_x = 8 text_y = 95 if self._display.height < 130: text_x = 3 text_y = 38 elif self._display.height > 250: text_y = 50 if text: self._text = Label(self._text_font, text=str(text)) self._text.x = text_x self._text.y = text_y self._text.color = color if background_color: self._text.background_color = background_color self._text_group.append(self._text) def set_background(self, filename: Optional[str], *, with_fade: bool = True) -> None: """The background image to a bitmap file. :param filename: The filename of the chosen background :type filename: str or None :param bool with_fade: If `True` fade out the backlight while loading the new background and fade in the backlight once completed. """ print("Set background to", filename) if with_fade: self.backlight_fade(0) if self._background_group: self._background_group.pop() if filename: background = displayio.OnDiskBitmap(self._gamedirectory + "/" + filename) self._background_sprite = displayio.TileGrid( background, pixel_shader=background.pixel_shader, ) self._background_group.append(self._background_sprite) if with_fade: self._display.refresh(target_frames_per_second=60) self.backlight_fade(1.0) def backlight_fade(self, to_light: float) -> None: """ Adjust the TFT backlight. Fade from the current value to the ``to_light`` value :param float to_light: the desired backlight brightness between :py:const:`0.0` and :py:const:`1.0`. """ from_light = self._display.brightness from_light = int(from_light * 100) to_light = max(0, min(100, int(to_light * 100))) delta = 1 if from_light > to_light: delta = -1 for val in range(from_light, to_light, delta): self._display.brightness = val / 100 time.sleep(0.003) self._display.brightness = to_light / 100 # return a list of lines with wordwrapping @staticmethod def wrap_nicely(string: str, max_chars: int) -> List[str]: """A helper that will return a list of lines with word-break wrapping. :param str string: The text to be wrapped. :param int max_chars: The maximum number of characters on a line before wrapping. :return: The list of lines :rtype: list(str) """ # string = string.replace('\n', '').replace('\r', '') # strip confusing newlines words = string.split(" ") the_lines = [] the_line = "" for w in words: if "\n" in w: _w1, _w2 = w.split("\n") the_line += " " + _w1 the_lines.append(the_line) the_line = _w2 elif len(the_line + " " + w) > max_chars: the_lines.append(the_line) the_line = "" + w else: the_line += " " + w if the_line: # last line remaining the_lines.append(the_line) # remove first space from first line: the_lines[0] = the_lines[0][1:] return the_lines
touch_deck_config["layers"][layer_index]["shortcuts"]): _new_icon = IconWidget(shortcut["label"], shortcut["icon"]) _icons.append(_new_icon) layout.add_content(_new_icon, grid_position=(i % 4, i // 4), cell_size=(1, 1)) load_layer(current_layer) main_group.append(layout) while True: p = ts.touch_point if p: _now = time.monotonic() if _now - LAST_PRESS_TIME > COOLDOWN_TIME: if next_layer_btn.contains(p): current_layer += 1 if current_layer >= len(touch_deck_config["layers"]): current_layer = 0 load_layer(current_layer) LAST_PRESS_TIME = time.monotonic() if home_layer_btn.contains(p): current_layer = 0 load_layer(current_layer) LAST_PRESS_TIME = time.monotonic() for index, icon_shortcut in enumerate(_icons): if icon_shortcut.contains(p): if index not in _pressed_icons: print("pressed {}".format(index))
class PYOA_Graphics(): """A choose your own adventure game framework.""" def __init__(self): self.root_group = displayio.Group(max_size=15) self._background_group = displayio.Group(max_size=1) self.root_group.append(self._background_group) self._text_group = displayio.Group(max_size=1) self.root_group.append(self._text_group) self._button_group = displayio.Group(max_size=2) self.root_group.append(self._button_group) self._speaker_enable = DigitalInOut(board.SPEAKER_ENABLE) self._speaker_enable.switch_to_output(False) if hasattr(board, 'AUDIO_OUT'): self.audio = audioio.AudioOut(board.AUDIO_OUT) elif hasattr(board, 'SPEAKER'): self.audio = audioio.AudioOut(board.SPEAKER) else: raise AttributeError('Board does not have an audio output!') self._background_file = None self._wavfile = None board.DISPLAY.auto_brightness = False self.backlight_fade(0) board.DISPLAY.show(self.root_group) self.touchscreen = None if hasattr(board, 'TOUCH_XL'): self.touchscreen = adafruit_touchscreen.Touchscreen( board.TOUCH_XL, board.TOUCH_XR, board.TOUCH_YD, board.TOUCH_YU, calibration=((5200, 59000), (5800, 57000)), size=(320, 240)) elif hasattr(board, 'BUTTON_CLOCK'): self.mouse_cursor = Cursor(board.DISPLAY, display_group=self.root_group, cursor_speed=8) self.cursor = CursorManager(self.mouse_cursor) else: raise AttributeError('PYOA requires a touchscreen or cursor.') self._gamedirectory = None self._gamefilename = None self._game = None self._text = None self._background_sprite = None self._text_font = None self._left_button = None self._right_button = None self._middle_button = None def load_game(self, game_directory): """Load a game. :param game_directory: where the game files are stored """ self._gamedirectory = game_directory self._text_font = terminalio.FONT # Button Attributes btn_left = 10 btn_right = btn_left + 180 btn_mid = btn_left + 90 button_y = 195 button_width = 120 button_height = 40 if board.DISPLAY.height < 200: button_y /= 2 button_y += 10 button_width /= 2 button_height /= 2 btn_right /= 2 btn_mid /= 2 self._left_button = Button(x=int(btn_left), y=int(button_y), width=int(button_width), height=int(button_height), label="Left", label_font=self._text_font, style=Button.SHADOWROUNDRECT) self._right_button = Button(x=int(btn_right), y=int(button_y), width=int(button_width), height=int(button_height), label="Right", label_font=self._text_font, style=Button.SHADOWROUNDRECT) self._middle_button = Button(x=int(btn_mid), y=int(button_y), width=int(button_width), height=int(button_height), label="Middle", label_font=self._text_font, style=Button.SHADOWROUNDRECT) self._gamefilename = game_directory + "/cyoa.json" try: game_file = open(self._gamefilename, "r") except OSError: raise OSError("Could not open game file " + self._gamefilename) self._game = json.load(game_file) game_file.close() def _fade_to_black(self): """Turn down the lights.""" self.mouse_cursor.is_hidden = True self.backlight_fade(0) # turn off background so we can render the text self.set_background(None, with_fade=False) self.set_text(None, None) for _ in range(len(self._button_group)): self._button_group.pop() self.mouse_cursor.is_hidden = False def _display_buttons(self, card): """Display the buttons of a card. :param card: The active card """ button01_text = card.get('button01_text', None) button02_text = card.get('button02_text', None) self._left_button.label = button01_text self._middle_button.label = button01_text self._right_button.label = button02_text if button01_text and not button02_text: # show only middle button self._button_group.append(self._middle_button.group) if button01_text and button02_text: self._button_group.append(self._right_button.group) self._button_group.append(self._left_button.group) def _display_background_for(self, card): """If there's a background on card, display it. :param card: The active card """ self.set_background(card.get('background_image', None), with_fade=False) def _display_text_for(self, card): """Display the main text of a card. :param card: The active card """ text = card.get('text', None) text_color = card.get('text_color', 0x0) # default to black if text: try: text_color = int( text_color) # parse the JSON string to hex int except ValueError: text_color = 0x0 self.set_text(text, text_color) def _play_sound_for(self, card): """If there's a sound, start playing it. :param card: The active card """ sound = card.get('sound', None) loop = card.get('sound_repeat', False) if sound: loop = loop == "True" print("Loop:", loop) self.play_sound(sound, wait_to_finish=False, loop=loop) def _wait_for_press(self, card): """Wait for a button to be pressed. :param card: The active card Return the id of the destination card. """ button01_text = card.get('button01_text', None) button02_text = card.get('button02_text', None) point_touched = None while True: if self.touchscreen is not None: point_touched = self.touchscreen.touch_point else: self.cursor.update() if self.cursor.is_clicked is True: point_touched = self.mouse_cursor.x, self.mouse_cursor.y if point_touched is not None: print("touch: ", point_touched) if button01_text and not button02_text: # showing only middle button if self._middle_button.contains(point_touched): print("Middle button") return card.get('button01_goto_card_id', None) if button01_text and button02_text: if self._left_button.contains(point_touched): print("Left button") return card.get('button01_goto_card_id', None) if self._right_button.contains(point_touched): print("Right button") return card.get('button02_goto_card_id', None) time.sleep(0.1) def display_card(self, card_num): """Display and handle input on a card. :param card_num: the index of the card to process """ card = self._game[card_num] print(card) print("*" * 32) print('****{:^24s}****'.format(card['card_id'])) print("*" * 32) self._fade_to_black() self._display_buttons(card) self._display_background_for(card) self.backlight_fade(1.0) self._display_text_for(card) board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() self._play_sound_for(card) auto_adv = card.get('auto_advance', None) if auto_adv is not None: auto_adv = float(auto_adv) print("Auto advancing after %0.1f seconds" % auto_adv) time.sleep(auto_adv) return card_num + 1 destination_card_id = self._wait_for_press(card) self.play_sound(None) # stop playing any sounds for card_number, card_struct in enumerate(self._game): if card_struct.get('card_id', None) == destination_card_id: return card_number # found the matching card! # eep if we got here something went wrong raise RuntimeError("Could not find card with matching 'card_id': ", destination_card_id) def play_sound(self, filename, *, wait_to_finish=True, loop=False): """Play a sound :param filename: The filename of the sound to play :param wait_to_finish: Whether playing the sound should block :param loop: Whether the sound should loop """ self._speaker_enable.value = False self.audio.stop() if self._wavfile: self._wavfile.close() self._wavfile = None if not filename: return # nothing more to do, just stopped filename = self._gamedirectory + "/" + filename print("Playing sound", filename) board.DISPLAY.wait_for_frame() try: self._wavfile = open(filename, "rb") except OSError: raise OSError("Could not locate sound file", filename) wavedata = audioio.WaveFile(self._wavfile) self._speaker_enable.value = True self.audio.play(wavedata, loop=loop) if loop or not wait_to_finish: return while self.audio.playing: pass self._wavfile.close() self._wavfile = None self._speaker_enable.value = False def set_text(self, text, color): """Display the test for a card. :param text: the text to display :param color: the text color """ if self._text_group: self._text_group.pop() if not text or not color: return # nothing to do! text_wrap = 37 if board.DISPLAY.height < 130: text_wrap = 25 text = self.wrap_nicely(text, text_wrap) text = '\n'.join(text) print("Set text to", text, "with color", hex(color)) text_x = 8 text_y = 95 if board.DISPLAY.height < 130: text_y = 38 text_x = 3 if text: self._text = Label(self._text_font, text=str(text)) self._text.x = text_x self._text.y = text_y self._text.color = color self._text_group.append(self._text) def set_background(self, filename, *, with_fade=True): """The background image to a bitmap file. :param filename: The filename of the chosen background """ print("Set background to", filename) if with_fade: self.backlight_fade(0) if self._background_group: self._background_group.pop() if filename: if self._background_file: self._background_file.close() self._background_file = open(self._gamedirectory + "/" + filename, "rb") background = displayio.OnDiskBitmap(self._background_file) self._background_sprite = displayio.TileGrid( background, pixel_shader=displayio.ColorConverter(), x=0, y=0) self._background_group.append(self._background_sprite) if with_fade: board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() self.backlight_fade(1.0) def backlight_fade(self, to_light): """Adjust the TFT backlight. Fade from one value to another """ from_light = board.DISPLAY.brightness from_light = int(from_light * 100) to_light = max(0, min(1.0, to_light)) to_light = int(to_light * 100) delta = 1 if from_light > to_light: delta = -1 for val in range(from_light, to_light, delta): board.DISPLAY.brightness = val / 100 time.sleep(0.003) board.DISPLAY.brightness = to_light / 100 # return a list of lines with wordwrapping #pylint: disable=invalid-name @staticmethod def wrap_nicely(string, max_chars): """A helper that will return a list of lines with word-break wrapping. :param str string: The text to be wrapped. :param int max_chars: The maximum number of characters on a line before wrapping. """ #string = string.replace('\n', '').replace('\r', '') # strip confusing newlines words = string.split(' ') the_lines = [] the_line = "" for w in words: if '\n' in w: w1, w2 = w.split('\n') the_line += ' ' + w1 the_lines.append(the_line) the_line = w2 elif len(the_line + ' ' + w) > max_chars: the_lines.append(the_line) the_line = '' + w else: the_line += ' ' + w if the_line: # last line remaining the_lines.append(the_line) # remove first space from first line: the_lines[0] = the_lines[0][1:] return the_lines
button = Button(x=10, y=10, width=120, height=60, style=Button.SHADOWROUNDRECT, fill_color=(255, 0, 0), outline_color=0x222222, name='/sd/music/bad_to_the_bone.wav', label_font = font, label='Bad to the Bone', ) pyportal.splash.append(button.group) buttons.append(button) # Next button wavfile = get_wavfile('/sd/music/bad_to_the_bone.wav') #play_audio(pyportal, wavfile) while True: touched = pyportal.touchscreen.touch_point # Returns tuple of (X,Y,?) # X range 0...320 # Y range 0...240 if touched: for button in buttons: if button.contains(touched): print("Touched", button.name) print("file", button.name) # Call play_audio(pyportal, filename) #play_audio(pyportal,get_wavfile(button.name)) my_play_audio(pyportal, button.name) time.sleep(0.3)
class Loader: def __init__(self): self.display = board.DISPLAY self.display.brightness = 0.1 self.cursor_index = 0 self.init_cursor() self.files_available = self.check_for_apps() self.file_count = len(self.files_available) self.init_menu() self.display.rotation = 270 self.display.show(self.screen_group) def init_cursor(self): self.cursor_group = displayio.Group() cursor_bmp, cursor_pal = adafruit_imageload.load( CURSOR_FILENAME, bitmap=displayio.Bitmap, palette=displayio.Palette) self.cursor = displayio.TileGrid(cursor_bmp, pixel_shader=cursor_pal, width=1, height=1, tile_width=8, tile_height=8) self.cursor[0] = 0 self.cursor.x = 0 self.cursor.y = MENU_START + (self.cursor_index * 8) def init_menu(self): self.screen_group = displayio.Group(max_size=6) self.program_menu = displayio.Group(max_size=20, scale=2) loader_banner = label.Label(FONT, text="Choose to Run", color=0xFF00FF) loader_banner.x = 10 loader_banner.y = TOP_OFFSET self.program_menu.append(loader_banner) for list_index, program_name in enumerate(self.files_available): menu_item_str = "%s" % '{:>5}'.format(program_name) menu_item = label.Label(FONT, text=menu_item_str, color=COLOR) menu_item.x = 10 menu_item.y = MENU_START + (list_index * 10) self.program_menu.append(menu_item) print("making up button") # Make the button self.up_button = Button( x=BUTTON_X, y=BUTTON_Y, width=BUTTON_WIDTH, height=BUTTON_HEIGHT, style=BUTTON_STYLE, fill_color=BUTTON_FILL_COLOR, outline_color=BUTTON_OUTLINE_COLOR, label=BUTTON_LABEL, label_font=terminalio.FONT, label_color=BUTTON_LABEL_COLOR, ) self.down_button = Button( x=BUTTON_X + BUTTON_WIDTH + 4, y=BUTTON_Y, width=BUTTON_WIDTH, height=BUTTON_HEIGHT, style=BUTTON_STYLE, fill_color=BUTTON_FILL_COLOR, outline_color=BUTTON_OUTLINE_COLOR, label="DOWN", label_font=terminalio.FONT, label_color=BUTTON_LABEL_COLOR, ) self.run_button = Button( x=BUTTON_X + BUTTON_WIDTH * 2 + 4 + 4, y=BUTTON_Y, width=BUTTON_WIDTH, height=BUTTON_HEIGHT, style=BUTTON_STYLE, fill_color=BUTTON_FILL_COLOR, outline_color=BUTTON_OUTLINE_COLOR, label="RUN", label_font=terminalio.FONT, label_color=BUTTON_LABEL_COLOR, ) self.program_menu.append(self.cursor) self.screen_group.append(self.program_menu) self.screen_group.append(self.up_button.group) self.screen_group.append(self.down_button.group) self.screen_group.append(self.run_button.group) def run_file(self, filename): module_name = APP_DIR + "/" + filename.strip(".py") mod = __import__(module_name) self.display.show(None) mod.main() ok = False while not ok: if mod.running: print("mod stopped") self.display.show(self.screen_group) break def check_for_apps(self, appdir=APP_DIR): return os.listdir(appdir) #def print_list(display, programs, cur_index): def run(self): last_update = time.monotonic() i = 0 current_time = time.monotonic() prev_btns = {"up": False, "down": False, "run": False} while True: current_time = time.monotonic() if current_time - last_update > 0.2: last_update = current_time i += 1 self.cursor[0] = i % 3 self.cursor.y = MENU_START + (self.cursor_index * 10) - 2 p = ts.touch_point if p: self.was_touched = True if self.up_button.contains(p): self.up_button.selected = True else: self.up_button.selected = False if self.down_button.contains(p): self.down_button.selected = True else: self.down_button.selected = False if self.run_button.contains(p): self.run_button.selected = True else: self.run_button.selected = False else: self.was_touched = False self.run_button.selected = False self.up_button.selected = False self.down_button.selected = False buttons = { "up": self.up_button.selected, "down": self.down_button.selected, "run": self.run_button.selected } if buttons["up"] and not prev_btns["up"]: if self.cursor_index > 0: self.cursor_index -= 1 if buttons["down"] and not prev_btns["down"]: if self.cursor_index < self.file_count - 1: self.cursor_index += 1 if buttons["run"] and not prev_btns["run"]: self.run_file(self.files_available[self.cursor_index]) prev_btns = buttons
buttons = [] for peg in pegs: button = Button(x=peg['pos'][0], y=peg['pos'][1], width=peg['size'][0], height=peg['size'][1], style=Button.RECT, fill_color=None, outline_color=0x5C3C15, name=peg['label']) pyportal.splash.append(button.group) buttons.append(button) note_select = None while True: touch = pyportal.touchscreen.touch_point if not touch and note_select: note_select = False if touch: for i in range(6): tuning = notes[i] button = buttons[i] if button.contains(touch) and not note_select: print("Touched", button.name) note_select = True for z in range(3): pyportal.play_file(tuning) time.sleep(0.1)
point = touch_screen.touch_point if point: # append each touch connection to a list point_list.append(point) # after three trouch detections have occured. if len(point_list) == 3: # discard the first touch detection and average the other # two get the x,y of the touch x = int((point_list[1][0] + point_list[2][0]) / 2) y = int((point_list[1][1] + point_list[2][1]) / 2) log("(" + str(x) + "/" + str(y) + ") pressed") pyportal.play_file(BEEP_SOUND_FILE) button_controller.check_and_send_shortcut_to_host(x, y) if dim_button.contains((x, y, 65000)): print("dim button pressed") if display_on: pyportal.set_backlight(0) else: pyportal.set_backlight(0.55) display_on = not display_on # clear list for next detection point_list = []