Skip to content
Merged
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
2 changes: 1 addition & 1 deletion ports/stm32/boards/Passport/modpassport_lv-keypad.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
127 changes: 76 additions & 51 deletions ports/stm32/boards/Passport/modules/views/keypad.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand All @@ -42,44 +45,44 @@ 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

# Draw the Numeric keypad grid
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):
Expand All @@ -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)
Expand All @@ -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)
Loading