def main_loop(): import gc global app_pointer get_key_event = hal_keypad.get_key_event parse_key_event = hal_keypad.parse_key_event KEY_LEFT = hal_keypad.KEY_LEFT KEY_RIGHT = hal_keypad.KEY_RIGHT KEY_A = hal_keypad.KEY_A KEY_B = hal_keypad.KEY_B t_update_battery_ms = ticks_ms() cpu.set_cpu_speed(cpu.VERY_SLOW) while True: should_refresh_screen = False for event in get_key_event(): event_type, key = parse_key_event(event) if event_type == hal_keypad.EVENT_KEY_PRESS: if key == KEY_LEFT: app_pointer -= 1 if key == KEY_RIGHT: app_pointer += 1 # ensure pointer if key == KEY_LEFT or key == KEY_RIGHT: SIZE = len(app_list) if 0 > app_pointer or SIZE <= app_pointer: app_pointer = (app_pointer + SIZE) % SIZE with cpu.cpu_speed_context(cpu.FAST): render_point_app() render_battery_level() should_refresh_screen = True if key == KEY_A: with cpu.cpu_speed_context(cpu.FAST): run_app() if key == KEY_B: # entering setup mode with cpu.cpu_speed_context(cpu.FAST): render_loading() hal_sdcard.init() hal_sdcard.mount() gc.collect() app.call_component("ftp_mode") gc.collect() load_app_list() render_point_app() render_battery_level() t_update_battery_ms = ticks_ms() should_refresh_screen = True import gc gc.collect() # app.reset_and_run_app("") # reset if ticks_diff(ticks_ms(), t_update_battery_ms) >= 500: t_update_battery_ms = ticks_add(t_update_battery_ms, 500) with cpu.cpu_speed_context(cpu.FAST): render_battery_level() should_refresh_screen = True else: battery.measure() if should_refresh_screen: hal_screen.refresh()
def dialog(text="", title="", text_yes="OK", text_no="OK"): """ show a dialog and display some text. return True/False """ with cpu_speed_context(VERY_SLOW): for v in dialog_gen(text, title, text_yes, text_no): if v != None: return v lightsleep(33) # save power
def select_list(title="", options=[], text_yes="OK", text_no="CANCEL"): """ show a menu and display some text. select_menu has a big area to display text, it is suitable for explaining your options. """ with cpu_speed_context(VERY_SLOW): for v in select_list_gen(title, options, text_yes, text_no): if v != None: return v lightsleep(33) # save power
def input_text(text="", title="Edit Text"): """ show a dialog and display some text. return True/False """ with cpu_speed_context(VERY_SLOW): for v in input_text_gen(text, title): if v != None: return v lightsleep(15) # save power
def draw(self, frame, x, y, w, h, font, white, force=False): if self.__redraw or force: with cpu_speed_context(FAST): black = white if self.__focus else 0 white = 0 if self.__focus else white frame.fill_rect(x, y, w, h, black) draw_label_nav(frame, x, y, w, h, font, white, self.get_focused_text()) self.__redraw = False return True # changed return False # nothing change
def draw(self, frame, x, y, w, h, font, white, force=False): if self.__redraw or force: with cpu_speed_context(FAST): frame.fill_rect(x, y, w, h, 0) if self.__focus: draw_label_invert(frame, x, y, w, h, font, white, self.__im.get_input_code()) else: draw_button(frame, x, y, w, h, font, white, self.__im.get_input_code()) self.__redraw = False return True # changed return False # nothing change
def input_slide(title="", text_yes="OK", text_no="CANCEL", slide_start=0, slide_size=100): """ show a dialog and display some text. return True/False """ with cpu_speed_context(VERY_SLOW): for v in input_slide_gen(title, text_yes, text_no, slide_start, slide_size): if v != None: return v lightsleep(33) # save power
def draw(self, frame, x, y, w, h, font, white, force=False): if self.__redraw or force: with cpu_speed_context(FAST): frame.fill_rect(x, y, w, h, 0) FW, FH = font.get_font_size() tw = len(self.__chs) * FW offset = (w - tw) // 2 font.draw_on_frame(self.__chs, frame, x + offset, y, white, w, h) if self.__focus >= 0: ch = self.__chs[self.__focus] off = offset + FW * self.__focus frame.fill_rect(x + off, y, FW, FH, white) font.draw_on_frame(ch, frame, x + off, y, 0, FW, FH) self.__redraw = False return True # changed return False # nothing change
def dialog_gen(text="", title="", text_yes="OK", text_no="OK"): WHITE = get_white_color(hal_screen.get_format()) SW, SH = hal_screen.get_size() F8 = get_font_8px() FW, FH = F8.get_font_size() TITLE_H = FH if title else 0 TEXT_H = SH - FH - TITLE_H if isinstance(text, str): paged_text = PagedText(text, SW, TEXT_H, FW, FH) else: paged_text = None redraw = True while True: for event in hal_keypad.get_key_event(): etype, ekey = parse_key_event(event) if etype != EVENT_KEY_PRESS: continue if ekey == KEY_A or ekey == KEY_B: yield ekey == KEY_A if ekey == KEY_LEFT or ekey == KEY_UP: paged_text.page_up() redraw = True if ekey == KEY_RIGHT or ekey == KEY_DOWN: paged_text.page_down() redraw = True if redraw: with cpu_speed_context(FAST): frame = hal_screen.get_framebuffer() frame.fill(0) # draw title if TITLE_H > 0: draw_label_header(frame, 0, 0, SW, TITLE_H, F8, WHITE, title) # draw text if callable(text): text(frame, 0, TITLE_H, SW, TEXT_H, F8, WHITE) else: paged_text.draw(frame, 0, TITLE_H, SW, TEXT_H, F8, WHITE) # draw button draw_buttons_at_last_line(frame, SW, SH, F8, WHITE, text_yes, text_no) redraw = False hal_screen.refresh() yield None
def draw(self, frame, x, y, w, h, font, white, force=False): now = ticks_ms() if ticks_diff(now, self.__last_ms) > 500: self.__redraw = True self.__show_cursor = (not self.__show_cursor) self.__last_ms = now if self.__redraw or force: with cpu_speed_context(FAST): black = white if self.__focus else 0 white = 0 if self.__focus else white FW, FH = font.get_font_size() char_count = w // FW t = self._get_text_with_cursor(char_count) offset_x = (w % FW) // 2 offset_y = (h % FH) // 2 frame.fill_rect(x, y, w, h, black) font.draw_on_frame(t, frame, x + offset_x, y + offset_y, white, w, h) self.__redraw = False return True # changed return False # nothing change
def input_slide_gen(title="", text_yes="OK", text_no="CANCEL", slide_start=0, slide_size=100): assert slide_start >= 0 WHITE = get_white_color(hal_screen.get_format()) SW, SH = hal_screen.get_size() F8 = get_font_8px() FW, FH = F8.get_font_size() TITLE_H = FH if title else 0 H_SLIDE_H = (SH - FH - TITLE_H) // 2 SLIDE_W = SW - FW - FW value = slide_start redraw = True while True: for event in hal_keypad.get_key_event(): etype, ekey = parse_key_event(event) if etype != EVENT_KEY_PRESS: continue if ekey == KEY_A or ekey == KEY_B: yield value if ekey == KEY_A else -1 - value if ekey == KEY_UP or ekey == KEY_DOWN: value += int(slide_size * 0.1) if ekey == KEY_UP else -int(slide_size * 0.1) value = max(slide_start, value) value = min(slide_start + slide_size, value) redraw = True if ekey == KEY_LEFT or ekey == KEY_RIGHT: value += 1 if ekey == KEY_RIGHT else -1 value = max(slide_start, value) value = min(slide_start + slide_size, value) redraw = True if redraw: with cpu_speed_context(FAST): frame = hal_screen.get_framebuffer() frame.fill(0) # draw title if TITLE_H > 0: draw_label_header(frame, 0, 0, SW, TITLE_H, F8, WHITE, title) # draw slide text t = str(value) tw = len(t) * FW offset_x = (SW - tw) // 2 offset_y = ((H_SLIDE_H - FH) // 2) + TITLE_H F8.draw_on_frame(t, frame, offset_x, offset_y, WHITE, SW, FH) # draw slide offset_y = ((H_SLIDE_H - FH) // 2) + H_SLIDE_H + TITLE_H ava_w = SLIDE_W - 4 bar_w = int(ava_w * (value / slide_size)) bar_w = min(ava_w, bar_w) bar_w = max(1, bar_w) frame.rect(FW, offset_y, SLIDE_W, FH, WHITE) frame.fill_rect(FW + 2, offset_y + 2, bar_w, FH - 4, WHITE) # draw button draw_buttons_at_last_line(frame, SW, SH, F8, WHITE, text_yes, text_no) redraw = False hal_screen.refresh() yield None
def select_file(cwd=None, title="Files", text_yes="OK", text_no="CANCEL", f_file=True, f_dir=True): with cpu_speed_context(VERY_SLOW): for v in select_file_gen(cwd, title, text_yes, text_no, f_file, f_dir): if v != None: return v lightsleep(33) # save power
def input_text_gen(text="", title="Edit Text"): # test # im = InputMethod(get_input_dict()) # for c in b"long": # im.input_byte(c) # print(im.all_words()) # test end WHITE = get_white_color(hal_screen.get_format()) SW, SH = hal_screen.get_size() F8 = get_font_8px() FW, FH = F8.get_font_size() EDIT_TEXT_H = SH - (FH * 7) frame = hal_screen.get_framebuffer() kbdl_piy = _KBD_PINYIN() kbdl_txt = _KBD_TEXT(text.replace("\n", "")) kbdl_spc = _KBD_OPTION(_SPECIAL_C) kbdl_num = _KBD_LINE(_KBD_C_1) kbdl_a2n = _KBD_LINE(_KBD_C_2) kbdl_o2z = _KBD_LINE(_KBD_C_3) kbdl_sym = _KBD_LINE(_KBD_C_4) kbdl_mod = _KBD_OPTION(_MODE_C) kbd_list = [ kbdl_txt, kbdl_spc, kbdl_num, kbdl_a2n, kbdl_o2z, kbdl_sym, kbdl_mod, ] redraw = True refresh = False focus_line = 0 focus_col = 0 # init kbdl_spc.change_op(1) focus_col = kbd_list[focus_line].set_focus(focus_col) kbd_line_size = len(kbd_list) mode = 0 # 0: a 1: A 2: 中 while True: action_code = None for event in hal_keypad.get_key_event(): etype, ekey = parse_key_event(event) if etype != EVENT_KEY_PRESS: continue if ekey == KEY_A: kbd = kbd_list[focus_line] if isinstance(kbd, _KBD_LINE): action_code = kbd.get_focused_text() elif isinstance(kbd, _KBD_OPTION) and kbd != kbdl_mod: action_code = kbd.get_focused_text() elif isinstance(kbd, _KBD_PINYIN): # select word for v in kbdl_piy.select_word_gen(): yield None if v == None: continue if len(v) > 0: kbdl_txt.insert(v) break redraw = True # select word end if ekey == KEY_B: kbd = kbd_list[focus_line] if isinstance(kbd, (_KBD_TEXT, _KBD_PINYIN, _KBD_LINE)): action_code = _SPECIAL_C[0] # delete if ekey == KEY_LEFT or ekey == KEY_RIGHT: off = 1 if ekey == KEY_RIGHT else -1 kbd = kbd_list[focus_line] if isinstance(kbd, _KBD_TEXT): kbd.move_cursor(off) elif isinstance(kbd, _KBD_LINE): focus_col = kbd.set_focus(focus_col + off) elif isinstance(kbd, _KBD_OPTION): kbd.change_op(off) if kbd == kbdl_mod: # special action_code = kbd.get_focused_text() if ekey == KEY_UP or ekey == KEY_DOWN: off = 1 if ekey == KEY_DOWN else -1 newf = focus_line + off # newf = max(newf, 0) # newf = min(newf, kbd_line_size - 1) newf = newf % kbd_line_size if newf != focus_line: kbd_list[focus_line].set_focus(None) kbd_list[newf].set_focus(focus_col) focus_line = newf # process action if isinstance(action_code, str): # print(action_code) if action_code.startswith("mode:"): if mode == 2: # from mode 2 kbd_list[2] = kbdl_num kbdl_num.redraw() if action_code == _MODE_C[2]: mode = 2 elif action_code == _MODE_C[1]: mode = 1 else: mode = 0 if mode == 2: # to mode 2 kbd_list[2] = kbdl_piy kbdl_piy.redraw() elif action_code == _SPECIAL_C[-1]: # confirm yield kbdl_txt.get_text() elif action_code == _SPECIAL_C[0]: # delete if mode == 2 and kbdl_piy.can_delete(): kbdl_piy.delete() else: kbdl_txt.delete() else: # insert if mode == 2: if action_code == " ": # select word for v in kbdl_piy.select_word_gen(): yield None if v == None: continue if len(v) > 0: kbdl_txt.insert(v) break redraw = True # select word end else: kbdl_piy.insert(action_code) elif mode == 1: try: kbdl_txt.insert(action_code.upper()) except: kbdl_txt.insert(action_code) else: kbdl_txt.insert(action_code) # draw all element if redraw: with cpu_speed_context(FAST): frame.fill(0) draw_label_header(frame, 0, 0, SW, FH, F8, WHITE, title) refresh = True for i in range(len(kbd_list)): if kbd_list[i] == kbdl_txt: refresh |= kbdl_txt.draw(frame, 0, FH, SW, EDIT_TEXT_H, F8, WHITE, redraw) continue base_y = SH - FH * (kbd_line_size - i) refresh |= kbd_list[i].draw(frame, 0, base_y, SW, FH, F8, WHITE, redraw) redraw = False if refresh: with cpu_speed_context(FAST): hal_screen.refresh() refresh = False yield None
def select_list_gen(title="", options=[], text_yes="OK", text_no="CANCEL"): WHITE = get_white_color(hal_screen.get_format()) SW, SH = hal_screen.get_size() F8 = get_font_8px() FW, FH = F8.get_font_size() OP_SIZE = len(options) SCROLL_BAR_W = 4 if OP_SIZE > 1 else 0 LIST_AREA_W = SW - SCROLL_BAR_W LIST_AREA_H = SH - FH - FH LIST_PAGE_SIZE = LIST_AREA_H // FH LIST_OFFSET_X = (LIST_AREA_W % FW) // 2 if OP_SIZE > 0: paged_text = PagedText(options[0], LIST_AREA_W, FH, FW, FH, style_inline=True) else: paged_text = PagedText("", LIST_AREA_W, FH, FW, FH, style_inline=True) pointer = 0 redraw = True while True: for event in hal_keypad.get_key_event(): etype, ekey = parse_key_event(event) if etype != EVENT_KEY_PRESS: continue if ekey == KEY_A or ekey == KEY_B: yield pointer if ekey == KEY_A and OP_SIZE > 0 else -1 - pointer if ekey == KEY_LEFT: paged_text.page_up() redraw = True if ekey == KEY_RIGHT: paged_text.page_down() redraw = True if OP_SIZE > 0 and (ekey == KEY_UP or ekey == KEY_DOWN): pointer += 1 if ekey == KEY_DOWN else -1 pointer %= OP_SIZE paged_text = PagedText(options[pointer], LIST_AREA_W, FH, FW, FH, style_inline=True) redraw = True if redraw: with cpu_speed_context(FAST): frame = hal_screen.get_framebuffer() frame.fill(0) # draw title draw_label_header(frame, 0, 0, SW, FH, F8, WHITE, title) # draw options page = pointer // LIST_PAGE_SIZE for i in range(OP_SIZE): if i // LIST_PAGE_SIZE != page: continue offset_y = FH + FH * (i % LIST_PAGE_SIZE) if i == pointer: frame.fill_rect(0, offset_y, LIST_AREA_W, FH, WHITE) paged_text.draw(frame, 0, offset_y, LIST_AREA_W, FH, F8, 0) else: F8.draw_on_frame(options[i], frame, LIST_OFFSET_X, offset_y, WHITE, LIST_AREA_W, FH) # draw scroll bar if SCROLL_BAR_W > 0: area_h = LIST_AREA_H - 4 scroll_h = max(int(area_h / OP_SIZE), 1) scroll_start = int(pointer * area_h / OP_SIZE) frame.fill_rect(SW - 3, FH + scroll_start + 2, 2, scroll_h, WHITE) frame.hline(SW - 4, FH, 4, WHITE) frame.hline(SW - 4, FH + LIST_AREA_H - 1, 4, WHITE) # draw button draw_buttons_at_last_line(frame, SW, SH, F8, WHITE, text_yes, text_no) redraw = False hal_screen.refresh() yield None
def select_menu_gen(text="", title="", options=[], text_yes="OK", text_no="CANCEL"): WHITE = get_white_color(hal_screen.get_format()) SW, SH = hal_screen.get_size() F8 = get_font_8px() FW, FH = F8.get_font_size() TITLE_H = FH if title else 0 TEXT_H = SH - FH - FH - TITLE_H OP_SIZE = len(options) if isinstance(text, str): paged_text = PagedText(text, SW, TEXT_H, FW, FH) else: paged_text = None pointer = 0 redraw = True while True: for event in hal_keypad.get_key_event(): etype, ekey = parse_key_event(event) if etype != EVENT_KEY_PRESS: continue if ekey == KEY_A or ekey == KEY_B: yield pointer if ekey == KEY_A and OP_SIZE > 0 else -1 - pointer if ekey == KEY_UP: paged_text.page_up() redraw = True if ekey == KEY_DOWN: paged_text.page_down() redraw = True if OP_SIZE > 0 and ekey == KEY_LEFT: pointer -= 1 pointer %= OP_SIZE redraw = True if OP_SIZE > 0 and ekey == KEY_RIGHT: pointer += 1 pointer %= OP_SIZE redraw = True if redraw: with cpu_speed_context(FAST): frame = hal_screen.get_framebuffer() frame.fill(0) # draw title if TITLE_H > 0: draw_label_header(frame, 0, 0, SW, TITLE_H, F8, WHITE, title) # draw text if callable(text): text(frame, 0, TITLE_H, SW, TEXT_H, F8, WHITE) else: paged_text.draw(frame, 0, TITLE_H, SW, TEXT_H, F8, WHITE) # draw options if OP_SIZE > 0: draw_label_nav(frame, 0, TEXT_H + TITLE_H, SW, FH, F8, WHITE, options[pointer]) # draw button draw_buttons_at_last_line(frame, SW, SH, F8, WHITE, text_yes, text_no) redraw = False hal_screen.refresh() yield None