diff --git a/ports/stm32/boards/Passport/modpassport_lv-keypad.h b/ports/stm32/boards/Passport/modpassport_lv-keypad.h index 03a30dbbb..eee21393c 100644 --- a/ports/stm32/boards/Passport/modpassport_lv-keypad.h +++ b/ports/stm32/boards/Passport/modpassport_lv-keypad.h @@ -291,7 +291,7 @@ STATIC void mod_passport_lv_Keypad_read_cb(lv_indev_drv_t* drv, lv_indev_data_t* } if (from_keypad) { - if (is_pressed && key_time - key_filter[key_index].release_time < 20) { + if (is_pressed && key_time - key_filter[key_index].release_time < 120) { key_filter[key_index].eat_next_release = true; return; } diff --git a/ports/stm32/boards/Passport/modules/views/keypad.py b/ports/stm32/boards/Passport/modules/views/keypad.py index a00b5f9fa..7fe5c6317 100644 --- a/ports/stm32/boards/Passport/modules/views/keypad.py +++ b/ports/stm32/boards/Passport/modules/views/keypad.py @@ -3,20 +3,23 @@ # import lvgl as lv -from styles.colors import FD_BLUE, TEXT_GREY, VERY_LIGHT_GREY, WHITE +from styles.colors import FD_BLUE, TEXT_GREY, VERY_LIGHT_GREY, WHITE, RED from styles.local_style import LocalStyle from styles.style import Stylize from .view import View +# Define custom colors for the keypad +LIGHT_PINK = lv.color_hex(0xFFB6C1) +LIGHT_BLUE = lv.color_hex(0xADD8E6) + WIDTH = 210 HEIGHT = 300 HALF_WIDTH = WIDTH // 2 -SIDE_MARGIN = 15 TOP_MARGIN = 10 -NUMKEY_HGAP = 10 -NUMKEY_VGAP = 5 -KEY_WIDTH = 50 +NUMKEY_HGAP = 4 +NUMKEY_VGAP = 1 +KEY_WIDTH = 46 KEY_HEIGHT = 24 Keys = [ @@ -42,35 +45,35 @@ def __init__(self): self.set_size(lv.pct(100), lv.pct(100)) self.key_state = { - '1': {'pressed': False, 'released': False, 'frame': None}, - '2': {'pressed': False, 'released': False, 'frame': None}, - '3': {'pressed': False, 'released': False, 'frame': None}, - '4': {'pressed': False, 'released': False, 'frame': None}, - '5': {'pressed': False, 'released': False, 'frame': None}, - '6': {'pressed': False, 'released': False, 'frame': None}, - '7': {'pressed': False, 'released': False, 'frame': None}, - '8': {'pressed': False, 'released': False, 'frame': None}, - '9': {'pressed': False, 'released': False, 'frame': None}, - '0': {'pressed': False, 'released': False, 'frame': None}, - '*': {'pressed': False, 'released': False, 'frame': None}, - '#': {'pressed': False, 'released': False, 'frame': None}, - 'l': {'pressed': False, 'released': False, 'frame': None}, - 'r': {'pressed': False, 'released': False, 'frame': None}, - 'u': {'pressed': False, 'released': False, 'frame': None}, - 'd': {'pressed': False, 'released': False, 'frame': None}, - 'x': {'pressed': False, 'released': False, 'frame': None}, - 'y': {'pressed': False, 'released': False, 'frame': None}, + '1': {'pressed': 0, 'released': 0, 'frame': None}, + '2': {'pressed': 0, 'released': 0, 'frame': None}, + '3': {'pressed': 0, 'released': 0, 'frame': None}, + '4': {'pressed': 0, 'released': 0, 'frame': None}, + '5': {'pressed': 0, 'released': 0, 'frame': None}, + '6': {'pressed': 0, 'released': 0, 'frame': None}, + '7': {'pressed': 0, 'released': 0, 'frame': None}, + '8': {'pressed': 0, 'released': 0, 'frame': None}, + '9': {'pressed': 0, 'released': 0, 'frame': None}, + '0': {'pressed': 0, 'released': 0, 'frame': None}, + '*': {'pressed': 0, 'released': 0, 'frame': None}, + '#': {'pressed': 0, 'released': 0, 'frame': None}, + 'l': {'pressed': 0, 'released': 0, 'frame': None}, + 'r': {'pressed': 0, 'released': 0, 'frame': None}, + 'u': {'pressed': 0, 'released': 0, 'frame': None}, + 'd': {'pressed': 0, 'released': 0, 'frame': None}, + 'x': {'pressed': 0, 'released': 0, 'frame': None}, + 'y': {'pressed': 0, 'released': 0, 'frame': None}, } y = TOP_MARGIN - self.add_key('u', HALF_WIDTH - KEY_WIDTH // 4, y, small=True) - self.add_key('d', HALF_WIDTH - KEY_WIDTH // 4, y + NUMKEY_VGAP + KEY_HEIGHT, small=True) - self.add_key('l', HALF_WIDTH - KEY_WIDTH // 4 - NUMKEY_HGAP - - KEY_WIDTH // 2, y + (NUMKEY_VGAP + KEY_HEIGHT) // 2, small=True) - self.add_key('r', HALF_WIDTH - KEY_WIDTH // 4 + NUMKEY_HGAP + - KEY_WIDTH // 2, y + (NUMKEY_VGAP + KEY_HEIGHT) // 2, small=True) - self.add_key('x', SIDE_MARGIN, y + (NUMKEY_VGAP + KEY_HEIGHT) // 2, small=True) - self.add_key('y', WIDTH - SIDE_MARGIN - KEY_WIDTH // 2, y + (NUMKEY_VGAP + KEY_HEIGHT) // 2, small=True) + self.add_key('u', HALF_WIDTH - KEY_WIDTH // 2, y) + self.add_key('d', HALF_WIDTH - KEY_WIDTH // 2, y + NUMKEY_VGAP + KEY_HEIGHT * 2) + self.add_key('l', HALF_WIDTH - KEY_WIDTH - NUMKEY_HGAP // 2, + y + (NUMKEY_VGAP + KEY_HEIGHT)) + self.add_key('r', HALF_WIDTH + NUMKEY_HGAP // 2, + y + (NUMKEY_VGAP + KEY_HEIGHT)) + self.add_key('x', HALF_WIDTH - 2 * KEY_WIDTH - 3 * NUMKEY_HGAP // 2, y + (NUMKEY_VGAP + KEY_HEIGHT)) + self.add_key('y', HALF_WIDTH + KEY_WIDTH + 3 * NUMKEY_HGAP // 2, y + (NUMKEY_VGAP + KEY_HEIGHT)) y += NUMKEY_VGAP + (NUMKEY_VGAP + KEY_HEIGHT) * 2 @@ -78,8 +81,8 @@ def __init__(self): for row in range(len(Keys)): for col in range(len(Keys[row])): key = Keys[row][col] - key_x = (SIDE_MARGIN + SIDE_MARGIN // 2) + (col * (KEY_WIDTH + NUMKEY_HGAP)) - key_y = y + row * (KEY_HEIGHT + NUMKEY_VGAP) + key_x = HALF_WIDTH + ((col - 1) * (KEY_WIDTH + NUMKEY_HGAP)) - KEY_WIDTH // 2 + key_y = y + row * (KEY_HEIGHT + NUMKEY_VGAP) + KEY_HEIGHT self.add_key(key, key_x, key_y) def add_key(self, key, key_x, key_y, small=False): @@ -101,6 +104,8 @@ def add_key(self, key, key_x, key_y, small=False): label = '##' else: label = key + + label = "{}: {}".format(label, self.key_state[key]['released']) key_label = Label(text=label, color=TEXT_GREY) with Stylize(key_label) as label: label.align(lv.ALIGN.CENTER) @@ -120,42 +125,62 @@ def update_key(self, key): if key_state is not None: key_frame = key_state.get('frame') if key_frame is not None: - pressed = key_state.get('pressed') - released = key_state.get('released') + pressed_count = key_state.get('pressed') + released_count = key_state.get('released') with LocalStyle(key_frame) as style: - if pressed: - style.border_width(3) - else: + # Border styling based on pressed count + if pressed_count == 0: style.border_width(1) style.border_color(TEXT_GREY) + elif pressed_count % 2 == 1: # odd + style.border_width(3) + style.border_color(FD_BLUE) + else: # even and > 0 + style.border_width(3) + style.border_color(RED) - if released: - style.bg_color(FD_BLUE) - style.text_color(WHITE) - else: + # Background styling based on released count + if released_count == 0: style.bg_color(VERY_LIGHT_GREY) + elif released_count % 2 == 1: # odd + style.bg_color(LIGHT_BLUE) + else: # even and > 0 + style.bg_color(LIGHT_PINK) key_label = key_state.get('label') if key_label is not None: + released_count = key_state.get('released') + + if key == '#': + label = '##' + else: + label = key + + label = "{}: {}".format(label, released_count) + key_label.set_text(label) + with LocalStyle(key_label) as style: - if released: + # Adjust text color based on background + if released_count == 0: + style.text_color(TEXT_GREY) + else: style.text_color(WHITE) def should_finish(self): all_were_pressed = True for key in self.key_state: - if not self.key_state[key]['released']: + if self.key_state[key]['released'] == 0: all_were_pressed = False - return all_were_pressed + # Allow pressing all multiple times, exit by pressing the enter key 5 times + return all_were_pressed and self.key_state['y']['released'] >= 5 def on_key(self, key, pressed): if key in self.key_state: - # Setting these states is a one-way trip - if self.key_state.get(key)['pressed'] is False and pressed: - self.key_state.get(key)['pressed'] = True - - if self.key_state.get(key)['released'] is False and not pressed: - self.key_state.get(key)['released'] = True + # Increment counts on each event + if pressed: + self.key_state.get(key)['pressed'] += 1 + else: + self.key_state.get(key)['released'] += 1 self.update_key(key)