Stav 23.06.2026
This commit is contained in:
+135
@@ -0,0 +1,135 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.metrics import dp
|
||||
from kivy.logger import Logger
|
||||
from kivy.app import App
|
||||
from kivy.clock import Clock
|
||||
|
||||
from ui_utils import _popup_info
|
||||
import numberpad
|
||||
from kivy.uix.anchorlayout import AnchorLayout
|
||||
from kivy.core.window import Window
|
||||
|
||||
MAX_LOGIN_FAILS = 3 # nebo treba 5
|
||||
|
||||
|
||||
|
||||
class LoginUserScreen(Screen):
|
||||
def __init__(self, controller, on_success, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.fail_count = 0
|
||||
self.controller = controller
|
||||
self.on_success = on_success
|
||||
root = BoxLayout(orientation="vertical")
|
||||
self.lbl_info = Label(
|
||||
text="Zadej PIN číšníka",
|
||||
size_hint_y=None,
|
||||
height=40,
|
||||
)
|
||||
self.lbl_error = Label(
|
||||
text="",
|
||||
color=(1, 0, 0, 1),
|
||||
size_hint_y=None,
|
||||
height=30,
|
||||
)
|
||||
root.add_widget(self.lbl_info)
|
||||
root.add_widget(self.lbl_error)
|
||||
self.center_layout = AnchorLayout(anchor_x="center", anchor_y="center")
|
||||
root.add_widget(self.center_layout)
|
||||
self.pad = None
|
||||
self._keyboard_bound = False
|
||||
self.add_widget(root)
|
||||
|
||||
def _on_key_down(self, window, key, scancode, codepoint, modifiers):
|
||||
if self.manager and self.manager.current != self.name:
|
||||
return False
|
||||
if self.pad:
|
||||
if key == 27:
|
||||
self.pad._cancel()
|
||||
return True # 🔥 zabráni zatvoreniu appky
|
||||
if key in range(48, 58): # top row
|
||||
self.pad._press(chr(key))
|
||||
return True
|
||||
elif key in range(256, 266): # numpad
|
||||
self.pad._press(str(key - 256))
|
||||
return True
|
||||
elif chr(key)=='*' or key == 268:
|
||||
self.pad._press("*")
|
||||
return True
|
||||
elif chr(key)=='.' or key == 266:
|
||||
self.pad._press(".")
|
||||
return True
|
||||
elif key > 300:
|
||||
print("pass")
|
||||
pass
|
||||
return True
|
||||
elif codepoint and (codepoint.isalpha() or codepoint.isdigit()):
|
||||
self.pad._press(codepoint)
|
||||
return True
|
||||
elif key == 8:
|
||||
self.pad._press('⌫')
|
||||
return True
|
||||
elif key in (13, 40, 10, 271): # Enter / Numpad Enter
|
||||
self.pad._accept()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def on_enter(self):
|
||||
self._bind_keyboard()
|
||||
self.lbl_error.text = ""
|
||||
if self.pad:
|
||||
self.center_layout.remove_widget(self.pad)
|
||||
self.pad = numberpad.NumberPad(
|
||||
mode="code",
|
||||
max_len=10,
|
||||
on_accept=self._accept,
|
||||
on_cancel=self._cancel,
|
||||
)
|
||||
self.pad.size_hint = (None, None)
|
||||
self.pad.size = (dp(300), dp(400))
|
||||
self.center_layout.add_widget(self.pad)
|
||||
|
||||
def on_leave(self):
|
||||
self._unbind_keyboard()
|
||||
if self.pad:
|
||||
self.center_layout.remove_widget(self.pad)
|
||||
self.pad = None
|
||||
|
||||
def _bind_keyboard(self):
|
||||
if self._keyboard_bound:
|
||||
return
|
||||
Window.unbind(on_key_down=self._on_key_down)
|
||||
Window.bind(on_key_down=self._on_key_down)
|
||||
self._keyboard_bound = True
|
||||
|
||||
def _unbind_keyboard(self):
|
||||
Window.unbind(on_key_down=self._on_key_down)
|
||||
self._keyboard_bound = False
|
||||
|
||||
def _accept(self, pin: str):
|
||||
try:
|
||||
self.controller.login_user(pin)
|
||||
# úspěch → reset čítače
|
||||
self.fail_count = 0
|
||||
Logger.info("LOGIN USER OK")
|
||||
self.on_success()
|
||||
except Exception as e:
|
||||
self.fail_count += 1
|
||||
Logger.warning(
|
||||
f"LOGIN FAILED ({self.fail_count}): {type(e).__name__}: {e}"
|
||||
)
|
||||
self.pad.clear()
|
||||
# příliš mnoho pokusů → konec aplikace
|
||||
if self.fail_count >= MAX_LOGIN_FAILS:
|
||||
Logger.error("MAX LOGIN FAILS REACHED")
|
||||
_popup_info("Chyba", "Příliš mnoho chybných pokusů.\nAplikace bude ukončena.")
|
||||
Clock.schedule_once(lambda *_: App.get_running_app().stop(), 2)
|
||||
|
||||
def _cancel(self):
|
||||
# v POS obvykle znamená ukončení aplikace
|
||||
Logger.info("LOGIN CANCEL")
|
||||
App.get_running_app().stop()
|
||||
Reference in New Issue
Block a user