def __init__(self, title="Enter account number", current_val='0'): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") self.note = add_label("Current account number: %s" % current_val, scr=self, style="hint") self.note.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) self.kb = lv.btnm(self) self.kb.set_map(self.NUMERIC_CHARSET) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 2) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label('', style="title", scr=self) lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) self.ta = lv.ta(self) self.ta.set_text("") self.ta.set_width(HOR_RES - 2 * PADDING - 40) self.ta.set_x(PADDING + 40) self.ta.set_y(PADDING + 150) self.ta.set_cursor_type(lv.CURSOR.HIDDEN) self.ta.set_one_line(True) self.kb.set_event_cb(self.cb)
def __init__(self, title="Enter your bip-39 password:"******"It is never stored on the device", suggestion=""): super().__init__() self.title = add_label(title, scr=self, style="title") if note is not None: self.note = add_label(note, scr=self, style="hint") self.note.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) self.kb = HintKeyboard(self) self.kb.set_map(type(self).CHARSET) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 3) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) self.ta = lv.ta(self) self.ta.set_text(suggestion) # self.ta.set_pwd_mode(True) self.ta.set_width(HOR_RES - 2 * PADDING) self.ta.set_x(PADDING) self.ta.set_text_align(lv.label.ALIGN.CENTER) self.ta.set_y(PADDING + 150) # self.ta.set_cursor_type(lv.CURSOR.HIDDEN) self.ta.set_one_line(True) # self.ta.set_pwd_show_time(0) self.kb.set_event_cb(self.cb)
def show_password_input(self): self.screen = lv.obj() self.wallet_paddword_screen_label = lv.label(self.screen) self.wallet_paddword_screen_label.set_text( " Enter your recovery\nphrase password (if any)") self.wallet_paddword_screen_label.align(self.screen, lv.ALIGN.CENTER, 0, -350) self.password_input = lv.ta(self.screen) self.password_input.set_one_line(True) self.password_input.set_text("") self.password_input.align(self.screen, lv.ALIGN.CENTER, 0, -275) self.password_back_button = lv.btn(self.screen) self.password_back_button.set_size(125, 60) self.password_back_button_label = lv.label(self.password_back_button) self.password_back_button_label.set_text("Back") self.password_back_button.align(self.screen, lv.ALIGN.CENTER, -100, -150) self.password_back_button.set_event_cb( self.handle_password_back_button) self.password_finish_button = lv.btn(self.screen) self.password_finish_button.set_size(150, 60) self.password_finish_button_label = lv.label( self.password_finish_button) self.password_finish_button_label.set_text("Finish") self.password_finish_button.align(self.screen, lv.ALIGN.CENTER, 100, -150) self.password_finish_button.set_event_cb( self.handle_password_finish_button) self.toggle_keyboard_button = lv.btn(self.screen) self.toggle_keyboard_button.set_size(230, 100) self.toggle_keyboard_button_label = lv.label( self.toggle_keyboard_button) self.toggle_keyboard_button_label.set_text( self.UPPER_CASE_KEYBOARD_SYMBOL) self.toggle_keyboard_button.align(self.screen, lv.ALIGN.CENTER, -118, 50) self.toggle_keyboard_button.set_event_cb( self.handle_toggle_password_keyboard_button) self.backspace_button = lv.btn(self.screen) self.backspace_button.set_size(230, 100) self.backspace_button_label = lv.label(self.backspace_button) self.backspace_button_label.set_text("Bksp") self.backspace_button.align(self.screen, lv.ALIGN.CENTER, 118, 50) self.backspace_button.set_event_cb( self.handle_password_backspace_button) self.keyboard = lv.kb(self.screen) self.keyboard.set_height(300) self.keyboard.align(self.screen, lv.ALIGN.IN_BOTTOM_MID, 0, 0) self.keyboard.set_map(self.PASSWORD_KEYBOARD_MAP_LOWER_CASE) self.keyboard.set_ta(self.password_input) lv.scr_load(self.screen)
def __init__(self, parent, x, y, width, height): self.lv_obj = lv.ta(parent) self.x = x self.y = y self.width = width self.height = height self.lv_obj.set_size(self.width, self.height) self.lv_obj.set_pos(x, y) self.lv_obj.set_cursor_type(lv.CURSOR.NONE)
def __init__(self, title="Enter your PIN code", note=None, get_word=None, subtitle=None): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") if subtitle is not None: lbl = add_label(subtitle, scr=self, style="hint") lbl.set_recolor(True) lbl.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 10) if note is not None: lbl = add_label(note, scr=self, style="hint") lbl.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 180) self.get_word = get_word if get_word is not None: self.words = add_label(get_word(b""), scr=self) self.words.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 210) btnm = lv.btnm(self) # shuffle numbers to make sure # no constant fingerprints left on screen buttons = ["%d" % i for i in range(0, 10)] btnmap = [] for j in range(3): for i in range(3): v = rng.get_random_bytes(1)[0] % len(buttons) btnmap.append(buttons.pop(v)) btnmap.append("\n") btnmap = btnmap + [lv.SYMBOL.CLOSE, buttons.pop(), lv.SYMBOL.OK, ""] btnm.set_map(btnmap) btnm.set_width(HOR_RES) btnm.set_height(HOR_RES) btnm.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) # increase font size style = lv.style_t() lv.style_copy(style, btnm.get_style(lv.btnm.STYLE.BTN_REL)) style.text.font = lv.font_roboto_28 # remove feedback on press to avoid sidechannels btnm.set_style(lv.btnm.STYLE.BTN_REL, style) btnm.set_style(lv.btnm.STYLE.BTN_PR, style) self.pin = lv.ta(self) self.pin.set_text("") self.pin.set_pwd_mode(True) style = lv.style_t() lv.style_copy(style, styles["theme"].style.ta.oneline) style.text.font = lv.font_roboto_28 style.text.color = styles["theme"].style.scr.text.color style.text.letter_space = 15 self.pin.set_style(lv.label.STYLE.MAIN, style) self.pin.set_width(HOR_RES - 2 * PADDING) self.pin.set_x(PADDING) self.pin.set_y(PADDING + 50) self.pin.set_cursor_type(lv.CURSOR.HIDDEN) self.pin.set_one_line(True) self.pin.set_text_align(lv.label.ALIGN.CENTER) self.pin.set_pwd_show_time(0) self.pin.align(btnm, lv.ALIGN.OUT_TOP_MID, 0, -150) btnm.set_event_cb(feed_rng(self.cb))
def show_set_password(self): self.screen = lv.obj() self.create_password_screen_label = lv.label(self.screen) self.create_password_screen_label.set_text("Set a password (optional)") self.create_password_screen_label.align(self.screen, lv.ALIGN.CENTER, 0, -360) self.password_input = lv.ta(self.screen) self.password_input.set_one_line(True) self.password_input.set_text("") self.password_input.align(self.screen, lv.ALIGN.CENTER, 0, -285) self.submit_password_button = lv.btn(self.screen) self.submit_password_button.set_size(125, 60) self.submit_password_button.align(self.screen, lv.ALIGN.CENTER, 0, -220) self.submit_password_button.set_event_cb( self.handle_submit_password_button) self.submit_password_button_label = lv.label( self.submit_password_button) self.submit_password_button_label.set_text("Set") self.password_tips_label = lv.label(self.screen) self.password_tips_label.set_text( "-Avoid common passwords\n" "-Use at least 11 characters\n" "-Use letters, numbers and\nspecial characters") self.password_tips_label.align(self.screen, lv.ALIGN.CENTER, 0, -90) self.toggle_keyboard_button = lv.btn(self.screen) self.toggle_keyboard_button.set_size(230, 100) self.toggle_keyboard_button_label = lv.label( self.toggle_keyboard_button) self.toggle_keyboard_button_label.set_text( self.UPPER_CASE_KEYBOARD_SYMBOL) self.toggle_keyboard_button.align(self.screen, lv.ALIGN.CENTER, -118, 50) self.toggle_keyboard_button.set_event_cb( self.handle_toggle_password_keyboard_button) self.backspace_button = lv.btn(self.screen) self.backspace_button.set_size(230, 100) self.backspace_button_label = lv.label(self.backspace_button) self.backspace_button_label.set_text("Bksp") self.backspace_button.align(self.screen, lv.ALIGN.CENTER, 118, 50) self.backspace_button.set_event_cb( self.handle_password_backspace_button) self.keyboard = lv.kb(self.screen) self.keyboard.set_height(300) self.keyboard.align(self.screen, lv.ALIGN.IN_BOTTOM_MID, 0, 0) self.keyboard.set_map(self.PASSWORD_KEYBOARD_MAP_LOWER_CASE) self.keyboard.set_ta(self.password_input) lv.scr_load(self.screen)
def show_phrase_input(self): self.phrase_input_length = 0 self.screen = lv.obj() self.recovery_phrase_length_screen_label = lv.label(self.screen) self.recovery_phrase_length_screen_label.set_text( "Recovery phrase word {page_number}/{recovery_phrase_target_length}" .format(page_number=len(self.recovery_phrase) + 1, recovery_phrase_target_length=self. recovery_phrase_target_length)) self.recovery_phrase_length_screen_label.align(self.screen, lv.ALIGN.CENTER, 0, -350) self.recovery_phrase_input = lv.ta(self.screen) self.recovery_phrase_input.set_one_line(True) self.recovery_phrase_input.set_text("") self.recovery_phrase_input.set_max_length(16) self.recovery_phrase_input.align(self.screen, lv.ALIGN.CENTER, 0, -275) self.recovery_phrase_input.set_event_cb( self.handle_recovery_phrase_input_change) # need to keep track of this for the autocomplete self.autocompleted = False self.phrase_input_length = 0 self.prev_recovery_phrase_word_button = lv.btn(self.screen) self.prev_recovery_phrase_word_button.set_size(125, 60) self.prev_recovery_phrase_word_button_label = lv.label( self.prev_recovery_phrase_word_button) self.prev_recovery_phrase_word_button_label.set_text("Back") self.prev_recovery_phrase_word_button.align(self.screen, lv.ALIGN.CENTER, -100, -150) self.prev_recovery_phrase_word_button.set_event_cb( self.handle_previous_recovery_phrase_word_button) self.next_recovery_phrase_word_button = lv.btn(self.screen) self.next_recovery_phrase_word_button.set_size(125, 60) self.next_recovery_phrase_word_button_label = lv.label( self.next_recovery_phrase_word_button) self.next_recovery_phrase_word_button_label.set_text("Next") self.next_recovery_phrase_word_button.align(self.screen, lv.ALIGN.CENTER, 100, -150) self.next_recovery_phrase_word_button.set_state(BUTTON_DISABLED_STATE) self.next_recovery_phrase_word_button.set_event_cb( self.handle_next_recovery_phrase_word_button) self.keyboard = lv.kb(self.screen) self.keyboard.set_map(self.RECOVERY_PHRASE_KEYBOARD_MAP) self.keyboard.set_ta(self.recovery_phrase_input) lv.scr_load(self.screen)
def ask_for_password(cb_continue, title="Enter your password (optional)"): scr = switch_to_new_screen() add_label(title, style="title") btnm = lv.btnm(scr) btnm.set_map(CHARSET) btnm.set_width(HOR_RES) btnm.set_height(VER_RES // 3) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) ta = lv.ta(scr) ta.set_text("") # ta.set_pwd_mode(True) ta.set_width(HOR_RES - 2 * PADDING) ta.set_x(PADDING) ta.set_text_align(lv.label.ALIGN.CENTER) ta.set_y(PADDING + 150) ta.set_cursor_type(lv.CURSOR.HIDDEN) ta.set_one_line(True) # ta.set_pwd_show_time(0) def cb(obj, event): if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c[0] == lv.SYMBOL.LEFT: ta.del_char() elif c == lv.SYMBOL.UP or c == lv.SYMBOL.DOWN: for i, ch in enumerate(CHARSET): if ch.isalpha(): if c == lv.SYMBOL.UP: CHARSET[i] = CHARSET[i].upper() else: CHARSET[i] = CHARSET[i].lower() elif ch == lv.SYMBOL.UP: CHARSET[i] = lv.SYMBOL.DOWN elif ch == lv.SYMBOL.DOWN: CHARSET[i] = lv.SYMBOL.UP btnm.set_map(CHARSET) elif c == "#@": btnm.set_map(CHARSET_EXTRA) elif c == "aA": btnm.set_map(CHARSET) elif c[0] == lv.SYMBOL.CLOSE: ta.set_text("") elif c[0] == lv.SYMBOL.OK: cb_continue(ta.get_text()) ta.set_text("") else: ta.add_text(c) btnm.set_event_cb(cb)
def ask_for_derivation(cb_continue, cb_back, title="Enter desired derivation path"): scr = switch_to_new_screen() add_label(title, style="title") btnm = lv.btnm(scr) btnm.set_map(PATH_CHARSET) btnm.set_width(HOR_RES) btnm.set_height(VER_RES // 2) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label("m/", style="title") lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) ta = lv.ta(scr) ta.set_text("") ta.set_width(HOR_RES - 2 * PADDING - 40) ta.set_x(PADDING + 40) ta.set_y(PADDING + 150) ta.set_cursor_type(lv.CURSOR.HIDDEN) ta.set_one_line(True) @feed_rng def cb(obj, event): if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c == "Back": cb_back() ta.set_text("") if c[0] == lv.SYMBOL.LEFT: ta.del_char() elif c[0] == lv.SYMBOL.CLOSE: ta.set_text("") elif c[0] == lv.SYMBOL.OK: cb_continue("m/" + ta.get_text()) ta.set_text("") elif c[0] == "h": ta.add_text("h/") else: ta.add_text(c) btnm.set_event_cb(cb)
def __init__(self): self.PrevPage = lv.disp_get_scr_act(lv_disp) self.CurPage = lv.obj() self.CurPage.set_size(320, 240) lv.disp_load_scr(self.CurPage) self.BtnValue = 1000 self.Plus1Btn = lv.btn(self.CurPage) self.Plus1Btn.set_pos(10, 25) self.Plus1Btn.set_size(50, 40) self.Plus1Btn.set_event_cb(self.Plus1EventCB) self.Plus1Label = lv.label(self.Plus1Btn) self.Plus1Label.set_text("+1") self.Plus100Btn = lv.btn(self.CurPage) self.Plus100Btn.set_pos(10, 75) self.Plus100Btn.set_size(50, 40) self.Plus100Btn.set_event_cb(self.Plus100EventCB) self.Plus100Label = lv.label(self.Plus100Btn) self.Plus100Label.set_text("+100") self.Minus1Btn = lv.btn(self.CurPage) self.Minus1Btn.set_pos(10, 125) self.Minus1Btn.set_size(50, 40) self.Minus1Btn.set_event_cb(self.Minus1EventCB) self.Minus1Label = lv.label(self.Minus1Btn) self.Minus1Label.set_text("-1") self.Minus100Btn = lv.btn(self.CurPage) self.Minus100Btn.set_pos(10, 175) self.Minus100Btn.set_size(50, 40) self.Minus100Btn.set_event_cb(self.Minus100EventCB) self.Minus100Label = lv.label(self.Minus100Btn) self.Minus100Label.set_text("-100") self.ValueLable = lv.label(self.CurPage) self.ValueLable.set_text("Value:") self.ValueLable.set_align(lv.ALIGN.CENTER) self.ValueLable.set_pos(140, 110) self.ValueText = lv.ta(self.CurPage) self.ValueText.set_pos(190, 100) self.ValueText.set_size(100, 40) self.ValueText.set_text(str(self.BtnValue))
def __init__(self, title="Enter derivation path"): super().__init__() self.title = add_label(title, scr=self, y=PADDING, style="title") self.kb = lv.btnm(self) self.kb.set_map(type(self).PATH_CHARSET) self.kb.set_width(HOR_RES) self.kb.set_height(VER_RES // 2) self.kb.align(self, lv.ALIGN.IN_BOTTOM_MID, 0, 0) lbl = add_label("m/", style="title", scr=self) lbl.set_y(PADDING + 150) lbl.set_width(40) lbl.set_x(PADDING) self.ta = lv.ta(self) self.ta.set_text("") self.ta.set_width(HOR_RES - 2 * PADDING - 40) self.ta.set_x(PADDING + 40) self.ta.set_y(PADDING + 150) self.ta.set_cursor_type(lv.CURSOR.HIDDEN) self.ta.set_one_line(True) self.kb.set_event_cb(self.cb)
else: with open(TOUCH_CALI_FILE, 'r') as f: param = ujson.load(f) touch_x0 = param['cal_x0'] touch_x1 = param['cal_x1'] touch_y0 = param['cal_y0'] touch_y1 = param['cal_y1'] touch = xpt2046( cs=TOUCH_CS, transpose=TFT_IS_PORTRAIT, cal_x0=touch_x0, cal_x1=touch_x1, cal_y0=touch_y0, cal_y1=touch_y1, ) TOUCH_READY = 1 #表示已经配置好触摸参数 ############################################# ############### Textarea ############## ############################################# if TOUCH_READY: ta1 = lv.ta(lv.scr_act()) ta1.set_size(200, 100) ta1.align(None, lv.ALIGN.CENTER, 0, 0) ta1.set_cursor_type(lv.CURSOR.BLOCK) ta1.set_text("A text in a Text Area") # Set an initial text
rel_style.body.radius = 0 rel_style.body.border.width = 1 lv.style_copy(pr_style, lv.style_btn_pr) pr_style.body.radius = 0 pr_style.body.border.width = 1 # Create a keyboard and apply the styles kb = lv.kb(lv.scr_act()) kb.set_cursor_manage(True) kb.set_style(lv.kb.STYLE.BG, lv.style_transp_tight) kb.set_style(lv.kb.STYLE.BTN_REL, rel_style) kb.set_style(lv.kb.STYLE.BTN_PR, pr_style) # Create a text area. The keyboard will write here ta = lv.ta(lv.scr_act()) ta.align(None, lv.ALIGN.IN_TOP_MID, 0, 10) ta.set_text("") # Assign the text area to the keyboard kb.set_ta(ta) # ********************************** # End your codes here. # ********************************** def on_timer(timer): lv.tick_inc(5) timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode = Timer.MODE_PERIODIC, period = 5, unit = Timer.UNIT_MS, callback = on_timer, arg = None)
pr_style = lv.style_t() lv.style_copy(rel_style, lv.style_btn_rel) rel_style.body.radius = 0 rel_style.body.border.width = 1 lv.style_copy(pr_style, lv.style_btn_pr) pr_style.body.radius = 0 pr_style.body.border.width = 1 # Create a keyboard and apply the styles kb = lv.kb(scr1) kb.set_cursor_manage(True) # Create a text area. The keyboard will write here ta = lv.ta(scr1) ta.set_width(450) ta.set_height(70) ta.align(kb, lv.ALIGN.OUT_TOP_MID, 0, -10) ta.set_text("") # Assign the text area to the keyboard kb.set_ta(ta) # Create a style for the Preloader style = lv.style_t() lv.style_copy(style, lv.style_plain) style.line.width = 10 # 10 px thick arc style.line.color = lv.color_hex3(0x258) # Blueish arc color style.body.border.color = lv.color_hex3(0xBBB) # Gray background color
def ask_pin(first_time_usage, callback): scr = switch_to_new_screen() first_time_title = "Choose a PIN code" title = "Enter your PIN code" if first_time_usage: title = first_time_title title_lbl = add_label(title, y=PADDING, style="title") btnm = lv.btnm(scr) # shuffle numbers to make sure # no constant fingerprints left on screen buttons = ["%d" % i for i in range(0,10)] btnmap = [] for j in range(3): for i in range(3): v = rng.get_random_bytes(1)[0] % len(buttons) btnmap.append(buttons.pop(v)) btnmap.append("\n") btnmap = btnmap+[lv.SYMBOL.CLOSE, buttons.pop(), lv.SYMBOL.OK, ""] btnm.set_map(btnmap) btnm.set_width(HOR_RES) btnm.set_height(HOR_RES) btnm.align(scr, lv.ALIGN.IN_BOTTOM_MID, 0, 0) # remove feedback on press to avoid sidechannels btnm.set_style(lv.btnm.STYLE.BTN_PR,btnm.get_style(lv.btnm.STYLE.BTN_REL)) pin_lbl = lv.ta(scr) pin_lbl.set_text("") pin_lbl.set_pwd_mode(True) style = lv.style_t() lv.style_copy(style, styles["theme"].style.ta.oneline) style.text.font = lv.font_roboto_28 style.text.color = lv.color_hex(0xffffff) style.text.letter_space = 15 pin_lbl.set_style(lv.label.STYLE.MAIN, style) pin_lbl.set_width(HOR_RES-2*PADDING) pin_lbl.set_x(PADDING) pin_lbl.set_y(PADDING+50) pin_lbl.set_cursor_type(lv.CURSOR.HIDDEN) pin_lbl.set_one_line(True) pin_lbl.set_text_align(lv.label.ALIGN.CENTER) pin_lbl.set_pwd_show_time(0) instruct_txt = "Device tamper check.\nThese words should remain #ffffff the same every time#:" instruct_label = add_label(instruct_txt, 180, style="hint") instruct_label.set_recolor(True) antiphish_label = add_label(antiphishing_word(""), 250) Pin.read_counter() @feed_rng def cb(obj, event): nonlocal first_time_usage if event == lv.EVENT.RELEASED: c = obj.get_active_btn_text() if c is None: return if c == lv.SYMBOL.CLOSE: pin_lbl.set_text("") antiphish_label.set_text(antiphishing_word("")) elif c == lv.SYMBOL.OK: # FIXME: check PIN len Key.generate_key(pin_lbl.get_text()); if first_time_usage: Secret.save_secret(alert); callback() else: Pin.counter -= 1 Pin.save_counter(alert) if Pin.is_pin_valid(): Pin.reset_counter(alert) callback() else: instruct_label.set_text("#f07070 Wrong pin: %d/%d #" % (Pin.counter, Pin.ATTEMPTS_MAX)) if Pin.counter <= 0: Factory_settings.restore(alert) Secret.generate_secret() alert("Security","Device has been factory reset!") first_time_usage = True title_lbl.set_text(first_time_title) instruct_label.set_text(instruct_txt) pin_lbl.set_text("") antiphish_label.set_text(antiphishing_word("")) else: instruct_label.set_text(instruct_txt) pin_lbl.add_text(c) word = antiphishing_word(pin_lbl.get_text()) antiphish_label.set_text(antiphish_label.get_text() + " " + word) btnm.set_event_cb(cb);
def popup_pid_params(self): """ The popup window of PID params settings """ modal_style = lv.style_t() lv.style_copy(modal_style, lv.style_plain_color) modal_style.body.main_color = modal_style.body.grad_color = lv.color_make( 0, 0, 0) modal_style.body.opa = lv.OPA._50 bg = lv.obj(self.main_scr) bg.set_style(modal_style) bg.set_pos(0, 0) bg.set_size(self.main_scr.get_width(), self.main_scr.get_height()) bg.set_opa_scale_enable(True) # init mbox and title popup_pid = lv.mbox(bg) popup_pid.set_text('Set PID Params') popup_pid.set_size(220, 300) popup_pid.align(bg, lv.ALIGN.CENTER, 0, 0) input_cont = lv.cont(popup_pid) input_cont.set_size(210, 180) def input_event_cb(ta, event): if event == lv.EVENT.CLICKED: self.current_input_placeholder = ta.get_placeholder_text() if self.current_input_placeholder == 'Set Offset': popup_pid.align(bg, lv.ALIGN.CENTER, 0, -55) else: popup_pid.align(bg, lv.ALIGN.CENTER, 0, 0) if kb.get_hidden(): kb.set_hidden(False) # Focus on the clicked text area kb.set_ta(ta) def keyboard_event_cb(event_kb, event): event_kb.def_event_cb(event) if event == lv.EVENT.CANCEL or event == lv.EVENT.APPLY: kb.set_hidden(True) if self.current_input_placeholder == 'Set Offset': popup_pid.align(bg, lv.ALIGN.CENTER, 0, 0) # init keyboard kb = lv.kb(bg) kb.set_cursor_manage(True) kb.set_event_cb(keyboard_event_cb) lv.kb.set_mode(kb, lv.kb.MODE.NUM) rel_style = lv.style_t() pr_style = lv.style_t() lv.style_copy(rel_style, lv.style_btn_rel) rel_style.body.radius = 0 rel_style.body.border.width = 1 lv.style_copy(pr_style, lv.style_btn_pr) pr_style.body.radius = 0 pr_style.body.border.width = 1 kb.set_style(lv.kb.STYLE.BG, lv.style_transp_tight) kb.set_style(lv.kb.STYLE.BTN_REL, rel_style) kb.set_style(lv.kb.STYLE.BTN_PR, pr_style) # init text areas kp_input = lv.ta(input_cont) kp_input.set_text(str(self.pid_params.get('kp'))) kp_input.set_placeholder_text('Set Kp') kp_input.set_accepted_chars('0123456789.+-') kp_input.set_one_line(True) kp_input.set_width(120) kp_input.align(input_cont, lv.ALIGN.IN_TOP_MID, 30, 20) kp_input.set_event_cb(input_event_cb) kp_label = lv.label(input_cont) kp_label.set_text("Kp: ") kp_label.align(kp_input, lv.ALIGN.OUT_LEFT_MID, 0, 0) pid_title_label = lv.label(input_cont) pid_title_label.set_text("PID Params:") pid_title_label.align(kp_input, lv.ALIGN.OUT_TOP_LEFT, -65, 0) ki_input = lv.ta(input_cont) ki_input.set_text(str(self.pid_params.get('ki'))) ki_input.set_placeholder_text('Set Ki') ki_input.set_accepted_chars('0123456789.+-') ki_input.set_one_line(True) ki_input.set_width(120) ki_input.align(input_cont, lv.ALIGN.IN_TOP_MID, 30, 55) ki_input.set_event_cb(input_event_cb) ki_input.set_cursor_type(lv.CURSOR.LINE | lv.CURSOR.HIDDEN) ki_label = lv.label(input_cont) ki_label.set_text("Ki: ") ki_label.align(ki_input, lv.ALIGN.OUT_LEFT_MID, 0, 0) kd_input = lv.ta(input_cont) kd_input.set_text(str(self.pid_params.get('kd'))) kd_input.set_placeholder_text('Set Kd') kd_input.set_accepted_chars('0123456789.+-') kd_input.set_one_line(True) kd_input.set_width(120) kd_input.align(input_cont, lv.ALIGN.IN_TOP_MID, 30, 90) kd_input.set_event_cb(input_event_cb) kd_input.set_cursor_type(lv.CURSOR.LINE | lv.CURSOR.HIDDEN) kd_label = lv.label(input_cont) kd_label.set_text("Kd: ") kd_label.align(kd_input, lv.ALIGN.OUT_LEFT_MID, 0, 0) temp_offset_input = lv.ta(input_cont) temp_offset_input.set_text(str(self.temp_offset)) temp_offset_input.set_placeholder_text('Set Offset') temp_offset_input.set_accepted_chars('0123456789.+-') temp_offset_input.set_one_line(True) temp_offset_input.set_width(120) temp_offset_input.align(input_cont, lv.ALIGN.IN_TOP_MID, 30, 145) temp_offset_input.set_event_cb(input_event_cb) temp_offset_input.set_cursor_type(lv.CURSOR.LINE | lv.CURSOR.HIDDEN) temp_offset_label = lv.label(input_cont) temp_offset_label.set_text("Offset: ") temp_offset_label.align(temp_offset_input, lv.ALIGN.OUT_LEFT_MID, 0, 0) offset_title_label = lv.label(input_cont) offset_title_label.set_text("Temp Correction:") offset_title_label.align(temp_offset_input, lv.ALIGN.OUT_TOP_LEFT, -65, 0) # set btns to mbox btns = ['Save', 'Cancel', ''] popup_pid.add_btns(btns) lv.cont.set_fit(popup_pid, lv.FIT.NONE) mbox_style = popup_pid.get_style(popup_pid.STYLE.BTN_REL) popup_pid_style = lv.style_t() lv.style_copy(popup_pid_style, mbox_style) popup_pid_style.body.padding.bottom = 46 popup_pid.set_style(popup_pid.STYLE.BTN_REL, popup_pid_style) popup_pid.set_size(220, 300) def event_handler(obj, event): if event == lv.EVENT.VALUE_CHANGED: active_btn_text = popup_pid.get_active_btn_text() if active_btn_text == 'Save': kp_value = float(kp_input.get_text()) ki_value = float(ki_input.get_text()) kd_value = float(kd_input.get_text()) temp_offset_value = float(temp_offset_input.get_text()) self.config['pid'] = { 'kp': kp_value, 'ki': ki_value, 'kd': kd_value } self.config['sensor_offset'] = temp_offset_value self.pid_params = self.config.get('pid') self.temp_offset = self.config.get('sensor_offset') # Save settings to config.json with open('config.json', 'w') as f: ujson.dump(self.config, f) # Apply settings immediately self.pid.reset(kp_value, ki_value, kd_value) self.sensor.set_offset(temp_offset_value) bg.del_async() popup_pid.start_auto_close(5) popup_pid.set_event_cb(event_handler) popup_pid.align(bg, lv.ALIGN.CENTER, 0, 0) kb.set_ta(kp_input) kb.set_hidden(True)