def string_box(x, y, w, h, text, font, color, align, testMode=False, newHeight=0): lines = wordWrap(text, w, font).split("\n") if len(lines) < 1: return for i in range(len(lines)): textWidth = display.getTextWidth(lines[i], font) textHeight = display.getTextHeight(lines[0], font) text_x = x + w // 2 - textWidth // 2 text_y = y + h // 2 - textHeight // 2 + textHeight * i - ( textHeight * (len(lines) - 1)) // 2 if testMode: print("Components", y, h // 2, textHeight // 2, textHeight * i, (textHeight * (len(lines) - 1)) // 2) print("Line", i, lines[i], text_x, text_y) display.drawText(text_x, text_y, lines[i], color, font) if testMode: display.drawRect(text_x, text_y, textWidth, textHeight, 0, 0) display.drawRect(text_x, text_y, textWidth, newHeight, 0, 0)
def clear(self): """Clear the screen and draw the current channel number.""" display.drawFill(0x000000) display.drawText(0, 0, "microham channel {}".format(self.channel), 0xFFFFFF, "7x5") display.flush() print("microham channel {}".format(self.channel))
def _draw(self): if self._visible: display.drawRect(self.x, self.y, self.w, self.h, True, 0x000000) display.drawRect(self.x, self.y, self.w, self.h, False, 0xFFFFFF) cursor = (self.x + 1, self.y + 1) totalHeight = 0 for i in range(len(self.items) - self.offset): cursor = (self.x + 1, cursor[1]) item = self.items[self.offset + i] lineHeight = display.getTextHeight(item, "roboto_regular12") while display.getTextWidth(item, "roboto_regular12") > self.w: item = item[:-1] totalHeight += lineHeight + 6 if totalHeight >= self.h: break color = 0xFFFFFF if self.offset + i == self.selected: display.drawRect(self.x, cursor[1], self.w, lineHeight + 6, True, 0xFFFFFF) color = 0x000000 cursor = (self.x, cursor[1] + 3) display.drawText(cursor[0] + 2, cursor[1], item + "\n", color, "roboto_regular12") cursor = ( self.x, cursor[1] + 3 + display.getTextHeight(item + "\n", "roboto_regular12"))
def _draw_menu_item(item, menu_state): display.drawFill(0) display.drawText(0, 0, item, (0x00FF00 if (menu_state['selected'] is not None and item in menu_state['selected']) else 0xFFFFFF)) display.flush()
def drawApp(app, position, amount): display.drawFill(0x000000) display.drawRect(0, 0, display.width(), 10, True, 0xFFFFFF) display.drawText(2, 0, "RECOVERY", 0x000000, "org18") positionText = "{}/{}".format(position + 1, amount) if app["path"].startswith("/sd"): positionText = "SD " + positionText positionWidth = display.getTextWidth(positionText, "org18") display.drawText(display.width() - positionWidth - 2, 0, positionText, 0x000000, "org18") titleWidth = display.getTextWidth(app["name"], "7x5") titleHeight = display.getTextHeight(app["name"], "7x5") display.drawText((display.width() - titleWidth) // 2, (display.height() - titleHeight) // 2, app["name"], 0xFFFFFF, "7x5") if not position < 1: display.drawText(0, display.height() // 2 - 12, "<", 0xFFFFFF, "roboto_regular18") if not position >= (amount - 1): display.drawText(display.width() - 10, display.height() // 2 - 12, ">", 0xFFFFFF, "roboto_regular18") display.flush(display.FLAG_LUT_FASTEST)
def start(): ugfx.set_lut(ugfx.LUT_FASTER) ugfx.clear(ugfx.WHITE) x0 = int(display.width()/2) display.drawText(x0+10, 0, "Recovery mode!", 0x000000, "roboto_regular12") global options global install_path options = None install_path = None ugfx.input_attach(ugfx.BTN_A, input_a) ugfx.input_attach(ugfx.BTN_B, input_b) ugfx.input_attach(ugfx.BTN_SELECT, input_select) ugfx.input_attach(ugfx.JOY_UP, input_other) ugfx.input_attach(ugfx.JOY_DOWN, input_other) ugfx.input_attach(ugfx.JOY_LEFT, input_other) ugfx.input_attach(ugfx.JOY_RIGHT, input_other) ugfx.input_attach(ugfx.BTN_START, input_other) populate_apps() populate_category() populate_options() # do a greyscale flush on start ugfx.flush(ugfx.GREYSCALE)
def drawNickname(): owner = machine.nvs_getstr("owner", "name") or "BADGE.TEAM" display.drawFill(0xFFFF00) x = (display.width()-display.getTextWidth(owner, "ocra16"))//2 y = (display.height()-display.getTextHeight(owner, "ocra16"))//2 display.drawText(x,y,owner,0x000000,"ocra16") display.flush() # Send the new buffer to the display display.backlight(0xFF) # Turn on backlight
def display_app(position): try: gui_apps[gui_app_current].draw(position) except BaseException as e: sys.print_exception(e) display.drawText(5, position, "(" + gui_app_names[gui_app_current] + ")", COLOR_FG, "Roboto_Regular18")
def showLoadingScreen(app=""): try: display.drawFill(0x000000) display.drawText(0, 28, "LOADING APP...", 0xFFFFFF, "org18") display.drawText(0, 52, app, 0xFFFFFF, "org18") display.flush() except: pass
def drawMessageBox(text): width = display.getTextWidth(text, "org18") height = display.getTextHeight(text, "org18") display.drawRect((display.width() - width - 4) // 2, (display.height() - height - 4) // 2, width + 2, height + 2, True, 0xFFFFFF) display.drawText((display.width() - width) // 2, (display.height() - height) // 2 - 2, text, 0x000000, "org18")
def draw_climate_labels(rect, temperature, pressure, humidity): x, y, w, h = rect clear_rect(rect) label = '{:.2f}C {:.2f}%'.format(temperature, humidity) label_w = display.getTextWidth(label) label_h = display.getTextHeight(label) display.drawText(x + w // 2 - label_w // 2, y + h // 2 - label_h // 2, label, 0x000000)
def demoThread(): global demoThreadRunning counter = 0 fpsTrig = False w, h, _, _ = display.pngInfo(mascot.snek) display.drawFill(0xFFFF00) prev = time.ticks_ms() av = [0] * 100 while demoThreadRunning: if counter > 100: fpsTrig = True current = time.ticks_ms() if (current - prev) > 0: fps = 1000 // (current - prev) else: fps = 0 _ = av.pop(0) av.append(fps) fps = 0 for i in range(len(av)): fps += av[i] fps = fps // len(av) display.drawRect(0, 0, display.width() - 1, 20, True, 0xFFFF00) if fpsTrig: display.drawText(0, 0, "{} fps".format(fps), 0x000000, "ocra16") else: display.drawText(0, 0, "Demo time!", 0x000000, "ocra16") my = (display.height() - h) // 2 - (round(math.sin(counter)) - 1) * 10 mx = (display.width() - w) // 2 - (round(math.cos(counter)) - 1) * 10 display.drawPng(mx, my, mascot.snek) #Draw squares display.drawRect(display.width() - 39 - (counter % display.width()), display.height() // 2 - 20, 40, 40, True, 0x00FF00) display.drawRect(counter % display.width(), display.height() // 2 - 10, 20, 20, True, 0xFF0000) #Flush to display display.flush() #Clear away the squares display.drawRect(display.width() - 39 - (counter % display.width()), display.height() // 2 - 20, 40, 40, True, 0xFFFF00) display.drawRect(counter % display.width(), display.height() // 2 - 10, 20, 20, True, 0xFFFF00) #Clear away the mascot display.drawRect(mx, my, w, h, True, 0xFFFF00) #Increment counter counter += 1 #time.sleep(0.01) prev = current drawNickname()
def show(text, speed='normal'): if speed == 'slow': display.drawFill(0x000000) display.flush() display.drawFill(0xFFFFFF) display.drawText(0, 0, text, 0x000000, "PermanentMarker36") if speed == 'fast': display.flush(display.FLAG_LUT_FASTEST) else: display.flush()
def lineCentered(pos_y, line, font, color): if font: width = display.getTextWidth(line, font) else: width = display.getTextWidth(line) pos_x = int((display.width() - width) / 2) if font: display.drawText(pos_x, pos_y, line, color, font) else: display.drawText(pos_x, pos_y, line, color)
def draw_co2_label(rect, co2): x, y, w, h = rect clear_rect(rect) co2_label = 'CO2: %d' % co2 co2_label_w = display.getTextWidth(co2_label, 'permanentmarker22') co2_label_h = display.getTextHeight(co2_label, 'permanentmarker22') display.drawText(x + w // 2 - co2_label_w // 2, y + h // 2 - co2_label_h // 2, co2_label, 0x000000, 'permanentmarker22')
def showLoadingScreen(app=""): hourglass = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x005\x00\x00\x00Z\x01\x00\x00\x00\x000?#R\x00\x00\x00jIDAT(\xcf\xad\xd2A\x12\x80 \x08\x05Po\xc0\x95\xbd\xc1\xbf.\xbb\x1f\x91\x8d5\x90:\x15.\xde\x02\xc6\x01\xb4\x94Y\xd0B\x07NB\xbdN\x7f\x10@\xea\x99W\xcdmy!XS\xb9\xcbje2P\x05\x95\xa9t\xed\x12\xf9$\xec\\\xee\x0bZ\x1f\xf4~\xd0\xfa\xba\x0b\x9b\x03}\x9e`\xdf'\x1e\\\xdb\xe3\xea{\x1c\x11m\xf9\xd7\xffm\xfc\xef6\x03^\xc2\x1c\x0eD=\xf5\x00\x00\x00\x00IEND\xaeB`\x82" try: display.drawFill(0xFFFFFF) text = "Loading...\n\n{}".format(app) display.drawText(91, (display.height()-display.getTextHeight(text, "ocra16"))//2, text, 0x000000, "ocra16") display.drawPng(19,19,hourglass) display.flush(display.FLAG_LUT_FASTEST) except: pass
def drawApp(app, position, amount): global extended_menu, appList oneFourthWidth = display.width() // 4 display.drawFill(0x000000) display.drawRect(0, 0, display.width() // (2 if extended_menu else 1), 10, True, 0xFFFFFF) display.drawText(2, 0, "LAUNCHER", 0x000000, "org18") positionText = "{}/{}".format(position + 1, amount) if app["path"].startswith("/sd"): positionText = "SD " + positionText positionWidth = display.getTextWidth(positionText, "org18") display.drawText( display.width() // (2 if extended_menu else 1) - positionWidth - 2, 0, positionText, 0x000000, "org18") titleWidth = display.getTextWidth(app["name"], "7x5") display.drawText( (oneFourthWidth * (3 if extended_menu else 2) - titleWidth // 2), display.height() - 10, app["name"], 0xFFFFFF, "7x5") try: icon_data = None if app["icon"]: if not app["icon"].startswith(b"\x89PNG"): with open(app["path"] + "/" + app["icon"], "rb") as icon_file: icon_data = icon_file.read() else: icon_data = app["icon"] if not icon_data: display.drawPng(oneFourthWidth * (3 if extended_menu else 2) - 16, display.height() // 2 - 16, default_icon) else: info = display.pngInfo(icon_data) if info[0] == 32 and info[1] == 32: display.drawPng( oneFourthWidth * (3 if extended_menu else 2) - 16, display.height() // 2 - 16, icon_data) else: drawMessageBox("Invalid icon size\nExpected 32x32!") except BaseException as e: sys.print_exception(e) drawMessageBox("Icon parsing error!") if not extended_menu: if not position < 1: display.drawText(0, display.height() // 2 - 12, "<", 0xFFFFFF, "roboto_regular18") if not position >= (amount - 1): display.drawText(display.width() - 10, display.height() // 2 - 12, ">", 0xFFFFFF, "roboto_regular18") if appList: appList.draw() display.flush(display.FLAG_LUT_FASTEST)
def string(x,y,text,font,color): if font == "Roboto_pixelade13": font = "roboto_regular12" if font == "fixed_10x20": font = "roboto_regular18" if not color: color = 0 if font: display.drawText(x, y, text, color, font) else: display.drawText(x, y, text, color)
def draw_message_label(pos, label): if not label: return center_x, center_y = pos padding = 4 label_w, label_h = display.getTextWidth( label), display.getTextHeight(label) + 4 area_x, area_y = center_x - label_w // 2 - padding, center_y - label_h // 2 - padding display.drawRect(area_x, area_y, label_w + padding * 2, label_h + padding * 2, True, 0) display.drawText(area_x + padding, area_y + padding, label, 0xffffff)
def sub_cb(self, topic, msg, retain, dup): """Handle an incoming message from the MQTT server, format and display it.""" message = msg.decode('ascii') topic = topic.decode('ascii') # channelname/username, and add colon username = topic.split("/")[1] + ':' print(username) print(message) self.clear() display.drawText(0, 8, username, 0xFFFFFF, "7x5") display.drawText(0, 16, message, 0xFFFFFF, "7x5") # TODO: wrap/scroll? display.flush()
def drawMessageBox(text): global extended_menu oneFourthWidth = display.width() // 4 width = display.getTextWidth(text, "org18") height = display.getTextHeight(text, "org18") display.drawRect( (oneFourthWidth * (3 if extended_menu else 2) - width - 4) // 2, (display.height() - height - 4) // 2, width + 2, height + 2, True, 0xFFFFFF) display.drawText( (oneFourthWidth * (3 if extended_menu else 2) - width) // 2, (display.height() - height) // 2 - 2, text, 0x000000, "org18")
def _draw_text_input_sequence(startx, chars, colour, reverse=False): length = len(chars) step = 10 curx = startx if reverse: for i in range(length - 1, -1, -1): display.drawText(curx, 0, chars[i], colour) curx -= step else: for i in range(length): display.drawText(curx, 0, chars[i], colour) curx += step
def drawApp(app, position, amount): drawTitle() positionText = "{}/{}".format(position+1, amount) if app["path"].startswith("/sd"): positionText = "SD "+positionText positionWidth = display.getTextWidth(positionText, "org18") display.drawText(display.width()-positionWidth-2, 0, positionText, 0x000000, "org18") titleWidth = display.getTextWidth(app["name"], "7x5") display.drawText((display.width()-titleWidth)//2,display.height()-10, app["name"], 0xFFFFFF, "7x5") try: icon_data = None if app["icon"]: if not app["icon"].startswith(b"\x89PNG"): with open(app["path"]+"/"+app["icon"], "rb") as icon_file: icon_data = icon_file.read() else: icon_data = app["icon"] if not icon_data: display.drawPng(48,15,default_icon) else: info = display.pngInfo(icon_data) if info[0] == 32 and info[1] == 32: display.drawPng(48,15,icon_data) else: drawMessageBox("Invalid icon size\nExpected 32x32!") except BaseException as e: sys.print_exception(e) drawMessageBox("Icon parsing error!") if not position < 1: display.drawText(0, display.height()//2-12, "<", 0xFFFFFF, "roboto_regular18") if not position >= (amount-1): display.drawText(display.width()-10, display.height()//2-12, ">", 0xFFFFFF, "roboto_regular18") display.flush()
def nickname(y = 5, font = "Roboto_Regular18", color = 0x000000, unusedParameter=None): nick = machine.nvs_getstr("owner", "name") if not nick: return y lines = lineSplit(nick, display.width(), font) for i in range(len(lines)): line = lines[len(lines)-i-1] pos_x = int((display.width()-display.getTextWidth(line, font)) / 2) lineHeight = display.getTextHeight(line, font) if font: display.drawText(pos_x, y+lineHeight*(len(lines)-i-1), line, color, font) else: display.drawText(pos_x, y+lineHeight*(len(lines)-i-1), line, color) return len(lines) * lineHeight
def drawTask(onSleep=False): global gui_redraw, cfg_nickname, gui_apps, gui_app_current, ota_available if gui_redraw or onSleep: gui_redraw = False display.drawFill(COLOR_BG) currHeight = 0 noLine = False if gui_app_current < 0: if cfg_logo: #Print logo app_height = display.height()-16-currHeight logoHeight = drawLogo(currHeight, app_height, True) if logoHeight > 0: noLine = True if logoHeight < 1: #Logo enabled but failed to display title = "BADGE.TEAM" subtitle = "PLATFORM" logoHeight = display.getTextHeight(title, "permanentmarker22")+display.getTextHeight(subtitle, "fairlight12") display.drawText((display.width()-display.getTextWidth(title, "permanentmarker22"))//2, currHeight + (app_height - logoHeight)//2,title, COLOR_FG, "permanentmarker22") currHeight += display.getTextHeight(title, "permanentmarker22") display.drawText((display.width()-display.getTextWidth(subtitle, "fairlight12"))//2, currHeight + (app_height - logoHeight)//2,subtitle, COLOR_FG, "fairlight12") currHeight += display.getTextHeight(subtitle, "fairlight12") else: noLine = True display.drawPng(0,0,LOGO) else: display_app(currHeight) if onSleep: info = 'Sleeping...' #elif not rtc.isSet(): # info = "RTC not available" elif ota_available: info = "Update available!" #elif wifi_status_curr: # info = "WiFi connected" else: info = ""#'Press START' if not noLine: display.drawLine(0, display.height()-16, display.width(), display.height()-16, COLOR_FG) easydraw.disp_string_right_bottom(0, info) if len(gui_apps) > 0: drawPageIndicator(len(gui_apps), gui_app_current) if cfg_greyscale: display.flush(display.FLAG_LUT_GREYSCALE) else: display.flush(display.FLAG_LUT_NORMAL) return 1000
def skippabletext(text, color=(255, 255, 255), pos=None, width=-1): buttons.attach(buttons.BTN_A, _abort_scroll) buttons.attach(buttons.BTN_B, _abort_scroll) display.drawText(0, 0, text) delay_loop = 50 global abort abort = False while (not abort) and (delay_loop >= 0): time.sleep(0.1) delay_loop -= 1 buttons.clear_button_mapping()
def start(app, status=False): if status: import term, easydraw, display if app == "" or app == "launcher": term.header(True, "Loading menu...") else: term.header(True, "Loading application " + app + "...") try: display.drawFill(0x000000) import mascot display.drawPng(64, 0, mascot.snek) display.drawText(0, 28, "LOADING APP...", 0xFFFFFF, "org18") display.drawText(0, 52, app, 0xFFFFFF, "org18") display.flush() except: easydraw.messageCentered("Loading...", False, "/media/busy.png") machine.RTC().write_string(app) reboot()
def send_message(self, pressed=True): """Blocking call. Prompt for a message via serial input, send the message to MQTT server""" if pressed: if self.client.is_conn_issue(): self.client.reconnect() term.clear() self.clear() topic = "{}/{}".format(self.channel, NICKNAME) display.drawText(0, 8, "transmitting...", 0xFFFFFF, "7x5") display.flush() # prompt is a blocking call, waits here for the message message = term.prompt("message:", 0, 1) if len(message) > 0: self.client.publish(topic, message) self.client.send_queue() print("\nmessage sent") display.drawText(0, 16, "message sent", 0xFFFFFF, "7x5") # wait and clear utime.sleep_ms(500) self.clear()
def uninstall(path): print("Uninstall", path) flist = os.listdir(path) print("files", flist) for i in range(len(flist)): f = flist[i] display.drawFill(0x000000) display.drawRect(0,0,display.width(), 10, True, 0xFFFFFF) display.drawText(2, 0, "UNINSTALL", 0x000000, "org18") drawMessageBox("Removing file...\n{}".format(f)) display.flush() os.remove(path+"/"+f) display.drawFill(0x000000) display.drawRect(0,0,display.width(), 10, True, 0xFFFFFF) display.drawText(2, 0, "UNINSTALL", 0x000000, "org18") drawMessageBox("Removing folder...") display.flush() os.rmdir(path) display.drawFill(0x000000) display.drawRect(0,0,display.width(), 10, True, 0xFFFFFF) display.drawText(2, 0, "UNINSTALL", 0x000000, "org18") drawMessageBox("App removed!") display.flush() time.sleep(2) showMenu()
def start(app, status=False): if status: appName = app if app == "" or app.startswith("dashboard."): term.header(True, "Loading...") appName = "" else: term.header(True, "Loading application " + app + "...") #easydraw.messageCentered("Loading '"+app+"'...", False, "/media/busy.png") try: #info = display.pngInfo("/media/busy.png") display.drawFill() #display.drawPng((display.width()-info[0])//2, (display.height()-info[1])//2, "/media/busy.png") import mascot display.drawPng(64, 0, mascot.snek) display.drawText(0, 28, "LOADING APP...", 0, "org18") display.drawText(0, 52, appName, 0, "org18") display.flush() except: easydraw.messageCentered("Loading...", False, "/media/busy.png") machine.RTC().write_string(app) reboot()
def levelDraw(self): # populate screen with grass tiles for i in range(-floor(TILES_WIDE/2),ceil(TILES_WIDE/2)): for j in range(-floor(TILES_TALL/2),ceil(TILES_TALL/2)): drawTile('grass',i,j) # populate screen with rocks #while len(self.obstacles) < 8: # for i in range(8): for animal in self.animalist: exists = self.checkAnimals(animal) if(exists == True): drawTile(animal.name, animal.xPos - self.player.xPos, animal.yPos-self.player.yPos) else: pass# don't draw animal if no longer exists #draw player tile drawTile("player",0,0) #display player stats on map playerStatString = "Muscle: " + str(self.player.muscle) + "kg\nFat: " + str(self.player.fat) + "kg." drawText(playerStatString, SCREEN_WIDTH*.90, 32, SCREEN_WIDTH*.25, 12)
def battleDraw(self): drawImage(self.battle_animal.name, 320,240,200,200) drawText(self.battleMessage, SCREEN_WIDTH/2, SCREEN_HEIGHT/4, SCREEN_WIDTH - 20, 18)