# tbox.py Test/demo of Textbox widget for micro-gui
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch
# Usage:
# import gui.demos.tbox
# Initialise hardware and framebuf before importing modules.
import hardware_setup # Create a display instance
import utime
from ugui import Screen, ssd
from writer import Writer
from machine import Pin
import uasyncio as asyncio
from colors import *
import arial10 as arial10
import arial50 as arial50
from label import Label
from textbox import Textbox
from buttons import Button, CloseButton, CustomMenuButton, CustomSubMenuButton
from adjuster import Adjuster, FloatAdj, IntegerAdjuster
wri = Writer(ssd, arial10) # verbose = True
def fwdbutton(wri, row, col, cls_screen, text='Next'):
def fwd(button):
Screen.change(cls_screen)
b = CustomMenuButton(wri, row, col,
callback = fwd, fgcolor = BLACK, bgcolor = BLACK,
text = text, shape = RECTANGLE)
return b.mrow
def fwdSubbutton(wri, row, col, cls_screen, text='Next'):
def fwd(button):
Screen.change(cls_screen)
b = CustomSubMenuButton(wri, row, col,
callback = fwd, fgcolor = BLACK, bgcolor = BLACK,
text = text, shape = RECTANGLE)
return b.mrow
def CustomCloseButton(wri, row, col, cls_screen, text='Next'):
def fwd(button):
Screen.back()
b = CustomSubMenuButton(wri, row, col,
callback = fwd, fgcolor = BLACK, bgcolor = BLACK,
text = text, shape = RECTANGLE)
return b.mrow
def set_nv_data(name, value):
try:
with open(name, "w") as f:
f.write(str(value))
except OSError:
print("Can't write to file %s" % name)
def get_car_number(name):
try:
with open(name) as f:
v = int(f.read())
except OSError:
v = 0
try:
with open(name, "w") as f:
f.write(str(v))
except OSError:
print("Can't create file %s" % name)
except ValueError:
print("invalid data in file %s" % name)
v = 1
set_nv_data("data.txt", v)
return v
class AdjusterScreen(Screen):
def __init__(self):
def my_callback(button):
v= int(self.lbl1.value())
set_nv_data("data.txt", v)
print(f"{v} salvato come numero macchina.")
super().__init__()
nMacchina = get_car_number("data.txt")
wri = Writer(ssd, arial10)
wribig = Writer(ssd, arial50)
col = 2
row = 2
self.lbl1 = Label(wribig, row, col + 2, "1000")
a = IntegerAdjuster(wri, 40, col, fgcolor=RED, value = nMacchina, width=60, height=20, text="Modifica",
callback=self.adj1_callback)
Button(wri, 40, col + 64, text='Salva', callback=my_callback, width=60, height=20)
CloseButton(wri, bgcolor=BLACK) # Quit the application
def adj1_callback(self, adj):
v = adj.value() # Typically do mapping here
self.lbl1.value(f"{int(v):4d}")
def adj2_callback(self, adj):
v = (adj.value() - 0.5) * 10 # Scale and offset
self.lbl2.value(f"{v:4.2f}")
def adj3_callback(self, adj):
v = 10 ** (3 * adj.value()) # Log 3 decades
self.lbl3.value(f"{v:4.2f}")
#def after_open(self): # Demo of programmatic change
#self.fa.value(0.8)
async def wrap(tb):
s = '''I CP520 5604
S 007 LAP TIME
10 | 13:32:54.074
11 | 16:20:24.287
213 | 17:18:05.852
321 | 17:18:07.445
361 | 17:18:09.325
71 | 17:18:11.406
2 | 17:18:12.914
7 | 17:18:14.095
'''
tb.clear()
tb.append(s, ntrim = 100, line = 0)
while True:
await asyncio.sleep(1)
if not tb.scroll(1):
break
async def clip(tb):
ss = ('clip demo', 'short', 'longer line', 'much longer line with spaces',
'antidisestablishmentarianism', 'line with\nline break', 'Done')
tb.clear()
for s in ss:
tb.append(s, ntrim = 100) # Default line=None scrolls to show most recent
await asyncio.sleep(1)
# Args for textboxes
# Positional
pargs = (2, 2, 100, 6) # Row, Col, Width, nlines
# Keyword
tbargs = {'fgcolor' : YELLOW,
'bdcolor' : RED,
'bgcolor' : BLACK,
}
class TBCScreen(Screen):
def __init__(self):
super().__init__()
self.tb = Textbox(wri, *pargs, clip=True, **tbargs)
CloseButton(wri)
asyncio.create_task(self.main())
async def main(self):
await clip(self.tb)
class TBWScreen(Screen):
def __init__(self):
super().__init__()
self.tb = Textbox(wri, *pargs, clip=False, **tbargs)
CloseButton(wri)
asyncio.create_task(self.main())
async def main(self):
await wrap(self.tb)
user_str = '''I CP520 5604
S 007 LAP TIME
10 || 13:32:54.074
11 | 16:20:24.287
213 | 17:18:05.852
321 | 17:18:07.445
361 | 17:18:09.325
71 | 17:18:11.406
2 | 17:18:12.914
7 | 17:18:14.095
'''
class TBUScreen(Screen):
def __init__(self):
super().__init__()
tb = Textbox(wri, *pargs, clip=False, active=True, **tbargs)
tb.append(user_str, ntrim=100)
CloseButton(wri, bgcolor=BLACK)
class NumberLockScreen(Screen):
def __init__(self):
super().__init__()
wribig = Writer(ssd, arial50)
col = 2
row = 2
nMacchina = get_car_number("data.txt")
lbl = Label(wribig, 25, col + 2, '1000')
lbl.value(f"{int(nMacchina):4d}")
def on_button_press(pin):
start_time = utime.time()
action_executed = False # Variabile per tracciare se l'azione è stata già eseguita
while hardware_setup.enc_btn.value() == 0:
if utime.time() - start_time >= 5 and not action_executed:
print("Unlocked")
action_executed = True # Imposta la variabile di controllo a True per indicare che l'azione è stata eseguita
# Disabilita l'interrupt sul pulsante per evitare ulteriori interruzioni durante l'esecuzione dell'azione
hardware_setup.enc_btn.irq(trigger=Pin.IRQ_FALLING, handler=None)
#Aggiungi buzzer
# Cambia schermata
Screen.change(MainScreen)
CustomMenuButton(wri, row, col,
callback = (lambda *_ : None), fgcolor = BLACK, bgcolor = BLACK,
text = "Concorrente numero:", shape = RECTANGLE, width=0)
# Aggiungi un gestore per l'evento di pressione del pulsante
hardware_setup.enc_btn.irq(trigger=Pin.IRQ_FALLING, handler=on_button_press)
class FunctionMenu(Screen):
def __init__(self):
super().__init__()
col = 4
row = 4
row = CustomCloseButton(wri, row, col, None, 'Indietro') + 2
row = fwdSubbutton(wri, row, col, TBCScreen, 'Cronometriaggio') + 2
row = fwdSubbutton(wri, row, col, TBUScreen, 'Visualizza tempi') + 2
row = fwdSubbutton(wri, row, col, TBWScreen, 'Sync tempo') + 2
row = fwdSubbutton(wri, row, col, TBWScreen, 'Testa segnale')
class OptionsMenu(Screen):
def __init__(self):
super().__init__()
col = 4
row = 4
row = CustomCloseButton(wri, row, col, None, 'Indietro') + 2
row = fwdSubbutton(wri, row, col, AdjusterScreen, 'N. Auto') + 2
row = fwdSubbutton(wri, row, col, NumberLockScreen, 'Lockscreen') + 2
row = fwdSubbutton(wri, row, col, TBWScreen, 'Null') + 2
row = fwdSubbutton(wri, row, col, TBWScreen, 'Null')
# Get the current time as a tuple
current_time_tuple = utime.localtime()
print("Current time tuple:", current_time_tuple)
current_time_string = "{:02}:{:02}:{:02}.{:03}".format(
current_time_tuple[3], # hour
current_time_tuple[4], # minute
current_time_tuple[5], # second
current_time_tuple[6] # second
)
print("Current time:", current_time_string)
class MainScreen(Screen):
def __init__(self):
super().__init__()
col = 4
row = 4
row = fwdbutton(wri, row, col, FunctionMenu, 'Funzioni') + 2
row = fwdbutton(wri, row, col, OptionsMenu, 'Opzioni')
# Your synchronization mechanism to trigger the synchronization function goes here
# For example, a button press, receiving a specific message over MQTT, etc.
# Call the synchronization function when triggered
class MillisecondTimer:
def __init__(self):
self.start_time = utime.ticks_ms()
def elapsed_ms(self):
return utime.ticks_diff(utime.ticks_ms(), self.start_time) % 1000
def test():
print('Initializing.')
# Get the current time as a tuple
# Set RTC time with desired timestamp
# Replace year, month, day, hour, minute, second, millisecond with your desired values
# Function to get current time with milliseconds
# Example usage
timer = MillisecondTimer()
# Some function you want to time
# For example, let's wait for 1 second
utime.sleep(1)
# Print elapsed time in milliseconds
print("Elapsed time:", timer.elapsed_ms(), "milliseconds")
utime.sleep_ms(45)
print("Elapsed time:", timer.elapsed_ms(), "milliseconds")
timer = MillisecondTimer()
print("Elapsed time:", timer.elapsed_ms(), "milliseconds")
utime.sleep_ms(999)
print("Elapsed time:", timer.elapsed_ms(), "milliseconds")
utime.sleep_ms(999)
start_time = None
Screen.change(MainScreen)
test()