wuttapos/wuttapos/controls/keyboard.py
2023-09-23 21:28:24 -05:00

180 lines
5.4 KiB
Python

# -*- coding: utf-8; -*-
################################################################################
#
# WuttaPOS -- Pythonic Point of Sale System
# Copyright © 2023 Lance Edgar
#
# This file is part of WuttaPOS.
#
# WuttaPOS is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# WuttaPOS is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# WuttaPOS. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
WuttaPOS - keyboard control
"""
import flet as ft
from .base import WuttaControl
class WuttaKeyboard(WuttaControl):
default_font_size = 20
default_button_size = 80
def __init__(self, *args, **kwargs):
self.on_keypress = kwargs.pop('on_keypress', None)
super().__init__(*args, **kwargs)
self.caps_lock = False
self.caps_map = dict([(k, k.upper())
for k in 'abcdefghijklmnopqrstuvwxyz'])
self.shift = False
self.shift_map = {
'`': '~',
'1': '!',
'2': '@',
'3': '#',
'4': '$',
'5': '%',
'6': '^',
'7': '&',
'8': '*',
'9': '(',
'0': ')',
'-': '_',
'=': '+',
'[': '{',
']': '}',
'\\': '|',
';': ':',
"'": '"',
',': '<',
'.': '>',
'/': '?',
}
def update_caps_lock(self, caps_lock):
self.caps_lock = caps_lock
if self.caps_lock:
self.caps_key.bgcolor = 'blue'
else:
self.caps_key.bgcolor = None
for key, button in self.keys.items():
if key in self.caps_map:
if self.caps_lock:
button.content.value = self.caps_map[key]
else:
button.content.value = key
self.update()
def update_shift(self, shift):
self.shift = shift
if self.shift:
self.shift_key.bgcolor = 'blue'
else:
self.shift_key.bgcolor = None
for key, button in self.keys.items():
if key in self.caps_map:
if self.shift:
button.content.value = self.caps_map[key]
else:
button.content.value = key
elif key in self.shift_map:
if self.shift:
button.content.value = self.shift_map[key]
else:
button.content.value = key
self.update()
def simple_keypress(self, e):
# maybe inform parent
if self.on_keypress:
key = e.control.content.value
# avoid callback for certain keys
if key not in ('CAPS', 'SHIFT'):
# translate certain keys
if key == 'SPACE':
key = ' '
# let 'em know
self.on_keypress(key)
# turn off shift key if set
if self.shift:
self.update_shift(False)
def build(self):
self.keys = {}
def make_key(key, data=None, on_click=self.simple_keypress,
width=self.default_button_size,
bgcolor=None):
button = ft.Container(content=ft.Text(key, size=self.default_font_size,
weight=ft.FontWeight.BOLD),
data=data or key,
height=self.default_button_size,
width=width,
on_click=on_click,
alignment=ft.alignment.center,
border=ft.border.all(1, 'black'),
border_radius=ft.border_radius.all(5),
bgcolor=bgcolor,
)
self.keys[key] = button
return button
def caps_click(e):
self.update_caps_lock(not self.caps_lock)
self.caps_key = make_key('CAPS', on_click=caps_click)
if self.caps_lock:
self.caps_key.bgcolor = 'blue'
def shift_click(e):
self.update_shift(not self.shift)
self.shift_key = make_key('SHIFT', on_click=shift_click)
if self.shift:
self.shift_key.bgcolor = 'blue'
rows = [
[make_key(k) for k in "`1234567890-="] + [make_key('', bgcolor='yellow')],
[make_key(k) for k in "qwertyuiop[]\\"],
[self.caps_key] + [make_key(k) for k in "asdfghjkl;'"] + [make_key('', bgcolor='blue')],
[self.shift_key] + [make_key(k) for k in "zxcvbnm,./"],
[make_key('SPACE', width=self.default_button_size * 5)],
]
rows = [ft.Row(controls, alignment=ft.MainAxisAlignment.CENTER)
for controls in rows]
return ft.Container(
content=ft.Column(
rows,
),
)