Add support for 10-key menu on login screen

if so configured, show that instead of full keyboard
This commit is contained in:
Lance Edgar 2023-10-05 16:27:32 -05:00
parent 734600817f
commit e59c398b45
2 changed files with 164 additions and 67 deletions

View file

@ -35,6 +35,7 @@ class WuttaTenkeyMenu(WuttaControl):
default_button_size = 100 default_button_size = 100
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.simple = kwargs.pop('simple', False)
self.on_char = kwargs.pop('on_char', None) self.on_char = kwargs.pop('on_char', None)
self.on_enter = kwargs.pop('on_enter', None) self.on_enter = kwargs.pop('on_enter', None)
self.on_up_click = kwargs.pop('on_up_click', None) self.on_up_click = kwargs.pop('on_up_click', None)
@ -45,45 +46,67 @@ class WuttaTenkeyMenu(WuttaControl):
def build(self): def build(self):
row1 = [
self.make_tenkey_button("1"),
self.make_tenkey_button("2"),
self.make_tenkey_button("3"),
]
if not self.simple:
row1.extend([
self.make_tenkey_button("@"),
])
row2 = [
self.make_tenkey_button("4"),
self.make_tenkey_button("5"),
self.make_tenkey_button("6"),
]
if not self.simple:
row2.extend([
self.make_tenkey_button("", on_long_press=self.up_long_press),
])
row3 = [
self.make_tenkey_button("7"),
self.make_tenkey_button("8"),
self.make_tenkey_button("9"),
]
if not self.simple:
row3.extend([
self.make_tenkey_button("", on_long_press=self.down_long_press),
])
row4 = [
self.make_tenkey_button("0"),
# self.make_tenkey_button("00"),
self.make_tenkey_button("."),
]
if self.simple:
row4.extend([
self.make_tenkey_button(""),
])
else:
row4.extend([
self.make_tenkey_button("ENTER", width=self.default_button_size * 2),
])
return ft.Container( return ft.Container(
content=ft.Column( content=ft.Column(
[ [
ft.Row( ft.Row(
[ controls=row1,
self.make_tenkey_button("1"),
self.make_tenkey_button("2"),
self.make_tenkey_button("3"),
self.make_tenkey_button("@"),
],
spacing=0, spacing=0,
), ),
ft.Row( ft.Row(
[ controls=row2,
self.make_tenkey_button("4"),
self.make_tenkey_button("5"),
self.make_tenkey_button("6"),
self.make_tenkey_button("", on_long_press=self.up_long_press),
],
spacing=0, spacing=0,
), ),
ft.Row( ft.Row(
[ controls=row3,
self.make_tenkey_button("7"),
self.make_tenkey_button("8"),
self.make_tenkey_button("9"),
self.make_tenkey_button("", on_long_press=self.down_long_press),
],
spacing=0, spacing=0,
), ),
ft.Row( ft.Row(
[ controls=row4,
self.make_tenkey_button("0"),
# self.make_tenkey_button("00"),
self.make_tenkey_button("."),
# TODO: should just specify 2x multiplier instead
self.make_tenkey_button("ENTER", width=self.default_button_size * 2),
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
spacing=0, spacing=0,
), ),
], ],
@ -118,7 +141,7 @@ class WuttaTenkeyMenu(WuttaControl):
def tenkey_click(self, e): def tenkey_click(self, e):
value = e.control.content.value value = e.control.content.value
if value == 'ENTER': if value in ('ENTER', ''):
if self.on_enter: if self.on_enter:
self.on_enter(e) self.on_enter(e)

View file

@ -28,6 +28,7 @@ import flet as ft
from .base import WuttaView from .base import WuttaView
from wuttapos.controls.keyboard import WuttaKeyboard from wuttapos.controls.keyboard import WuttaKeyboard
from wuttapos.controls.tenkey import WuttaTenkeyMenu
class LoginView(WuttaView): class LoginView(WuttaView):
@ -45,6 +46,13 @@ class LoginView(WuttaView):
self.show_username = config.getbool('wuttapos', 'login.show_username', self.show_username = config.getbool('wuttapos', 'login.show_username',
default=True) default=True)
# may or may not show 10-key menu instead of full keyboard
if 'use_tenkey' in kwargs:
self.use_tenkey = kwargs.pop('use_tenkey')
else:
self.use_tenkey = config.getbool('wuttapos', 'login.use_tenkey',
default=False)
# build controls # build controls
super().__init__(config, *args, **kwargs) super().__init__(config, *args, **kwargs)
@ -67,6 +75,39 @@ class LoginView(WuttaView):
ft.Row(), ft.Row(),
] ]
login_form = self.build_login_form()
if self.use_tenkey:
controls.extend([
ft.Row(
[
login_form,
ft.VerticalDivider(),
WuttaTenkeyMenu(self.config, simple=True,
on_char=self.tenkey_char,
on_enter=self.tenkey_enter),
],
alignment=ft.MainAxisAlignment.CENTER,
),
])
else:
controls.extend([
login_form,
ft.Row(),
ft.Row(),
ft.Row(),
WuttaKeyboard(self.config, on_keypress=self.keypress,
on_long_backspace=self.long_backspace),
])
return [
self.build_header(),
ft.Column(controls=controls,
expand=True,
alignment=ft.MainAxisAlignment.CENTER),
]
def build_login_form(self):
form_fields = [] form_fields = []
self.password = ft.TextField(label="Password", width=200, password=True, self.password = ft.TextField(label="Password", width=200, password=True,
@ -85,51 +126,66 @@ class LoginView(WuttaView):
form_fields.append(self.password) form_fields.append(self.password)
controls.extend([ login_button = ft.Container(
ft.Row( content=ft.Text("Login", size=20,
controls=form_fields + [ weight=ft.FontWeight.BOLD),
ft.Container(content=ft.Text("Login", size=20, height=60,
weight=ft.FontWeight.BOLD), width=60 * 2.5,
height=60, alignment=ft.alignment.center,
width=60 * 2.5, border=ft.border.all(1, 'black'),
alignment=ft.alignment.center, border_radius=ft.border_radius.all(5),
border=ft.border.all(1, 'black'), bgcolor='blue',
border_radius=ft.border_radius.all(5), on_click=self.attempt_login)
bgcolor='blue',
on_click=self.attempt_login),
ft.Container(content=ft.Text("Clear", size=20, reset_button = ft.Container(
weight=ft.FontWeight.BOLD), content=ft.Text("Clear", size=20,
height=60, weight=ft.FontWeight.BOLD),
width=60 * 2.5, height=60,
alignment=ft.alignment.center, width=60 * 2.5,
border=ft.border.all(1, 'black'), alignment=ft.alignment.center,
border_radius=ft.border_radius.all(5), border=ft.border.all(1, 'black'),
on_click=self.clear_login), border_radius=ft.border_radius.all(5),
], on_click=self.clear_login)
if self.use_tenkey:
form_fields.extend([
ft.Row(),
ft.Row(),
ft.Row(
[
reset_button,
login_button,
],
),
])
else:
form_fields.extend([
login_button,
reset_button,
])
if self.use_tenkey:
return ft.Column(
controls=form_fields,
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
)
else:
return ft.Row(
controls=form_fields,
alignment=ft.MainAxisAlignment.CENTER, alignment=ft.MainAxisAlignment.CENTER,
), )
ft.Row(),
ft.Row(),
ft.Row(),
WuttaKeyboard(self.config, on_keypress=self.keypress,
on_long_backspace=self.long_backspace),
])
return [
self.build_header(),
ft.Column(controls=controls,
expand=True,
alignment=ft.MainAxisAlignment.CENTER),
]
def keypress(self, key): def keypress(self, key):
assert self.focused assert self.focused
if key == '': if key == '':
if self.focused is self.username: if self.show_username and self.focused is self.username:
self.username_submit() self.username_submit()
else: else:
self.password_submit() # nb. when this succeeds, we will have been redirected
# to /pos so must exit here to avoid update() etc.
if self.password_submit():
return
elif key == '': elif key == '':
self.focused.value = self.focused.value[:-1] self.focused.value = self.focused.value[:-1]
else: else:
@ -144,6 +200,21 @@ class LoginView(WuttaView):
self.focused.focus() self.focused.focus()
self.update() self.update()
def tenkey_char(self, key):
if key == '@':
return
self.focused.value = f"{self.focused.value or ''}{key}"
self.page.update()
def tenkey_enter(self, e):
if self.show_username and self.focused is self.username:
self.username_submit()
self.update()
else:
if not self.password_submit():
self.update()
def username_focus(self, e): def username_focus(self, e):
self.focused = self.username self.focused = self.username
@ -158,9 +229,10 @@ class LoginView(WuttaView):
def password_submit(self, e=None): def password_submit(self, e=None):
if self.password.value: if self.password.value:
self.attempt_login() return self.attempt_login()
else: else:
self.password.focus() self.password.focus()
return False
def clear_login(self, e): def clear_login(self, e):
if self.show_username: if self.show_username:
@ -175,10 +247,10 @@ class LoginView(WuttaView):
def attempt_login(self, e=None): def attempt_login(self, e=None):
if self.show_username and not self.username.value: if self.show_username and not self.username.value:
self.username.focus() self.username.focus()
return return False
if not self.password.value: if not self.password.value:
self.password.focus() self.password.focus()
return return False
session = self.app.make_session() session = self.app.make_session()
auth = self.app.get_auth_handler() auth = self.app.get_auth_handler()
@ -198,6 +270,7 @@ class LoginView(WuttaView):
self.page.client_storage.set('user_uuid', user.uuid) self.page.client_storage.set('user_uuid', user.uuid)
self.page.go('/pos') self.page.go('/pos')
return True
else: else:
# handle failure # handle failure
@ -209,3 +282,4 @@ class LoginView(WuttaView):
self.page.snack_bar.open = True self.page.snack_bar.open = True
self.password.focus() self.password.focus()
self.page.update() self.page.update()
return False