def _define_screen(self): self._palette = [("title", "yellow", "dark cyan"), ("keys", "dark blue", "light gray"), ("message", "light cyan", "dark green"), ("linenr", "light blue", "dark cyan"), ("input", "light gray", "black"), ("input2", "dark red", "light gray"), ("focus", "black", "light gray", "bold"), ("dialog", "black", "light gray", "bold"), ("file", "light green", "dark blue"), ("errortxt", "dark red", "dark blue"), ("selectedfile", "yellow", "dark blue"), ("selectedfocus", "yellow", "light gray", "bold"), ("dir", "light gray", "dark blue"), ("fileedit", "light green", "dark red"), ('edit', 'yellow', 'dark blue'), ('body', 'default', 'default'), ('foot', 'dark cyan', 'dark blue', 'bold'), ('shadow', 'white', 'black'), ('border', 'black', 'dark blue'), ('error', 'black', 'dark red'), ('FxKey', 'light cyan', 'dark blue', 'underline')] #self.divider = urwid.Divider("-") self.left_header = LeftHeader() self.right_header = RightHeader() self.details = DetailsWidget(self, "result") #self.menu = MenuWidget(self, "footer") self.network = None #self.nodes_walker = NodesWalker(self, self.network) self.listbox_header = NodeItem() self.listbox = NodesBox(self, "body") self.menu = MenuWidget(self, "value") self.nodes = [] self.status_bar = StatusBar() self.header = urwid.Pile([ #self.divider, urwid.Columns( [ ('weight', 2, urwid.AttrWrap(self.left_header, 'reverse')), #('fixed', 1, urwid.Divider("|")), ('weight', 2, urwid.AttrWrap(self.right_header, 'reverse')) ], dividechars=2, min_width=8), DIVIDER, self.listbox_header.get_header() ]) # self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), # #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) #self.sub_frame = urwid.Filler(urwid.Frame( \ # urwid.AttrWrap( # self.details, 'sub_frame_body'), \ # header=self.details.header_widget(),\ # footer=self.details.footer_widget(), \ # focus_part="body"), height=9) #self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) # self.footer = urwid.Pile([ # DIVIDER, # self.footer_columns, # DIVIDER, # urwid.AttrWrap(self.status_bar, 'reverse'), # #self.divider, # #urwid.AttrWrap(urwid.Text(" > "), 'footer') # ]) self.footer = urwid.Pile([ DIVIDER, urwid.AttrWrap(self.status_bar, 'reverse'), #self.divider, #urwid.AttrWrap(urwid.Text(" > "), 'footer') ]) self.framefocus = 'body' # self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'), \ # header=self.header,\ # footer=self.footer, \ # focus_part=self.framefocus) self.frame = FrameApp(urwid.AttrWrap(self.listbox, 'body'), \ header=self.header,\ command=(self.menu,1),\ result=(self.details,5),\ # value=self.menu,\ # footer=self.footer, \ log = self.log, \ focus_part=self.framefocus, status_bar=self.footer_display, menu_f=self.footer_display, ) self.frame.set_menu_f(f1="Help", f5="Refresh") self.loop = urwid.MainLoop(self.frame, \ self._palette, \ unhandled_input=self._unhandled_input)
def _define_screen(self): self._palette = [("title", "yellow", "dark cyan"), ("keys", "dark blue", "light gray"), ("message", "light cyan", "dark green"), ("linenr", "light blue", "dark cyan"), ("input", "light gray", "black"), ("input2", "dark red", "light gray"), ("focus", "black", "light gray", "bold"), ("dialog", "black", "light gray", "bold"), ("file", "light green", "dark blue"), ("errortxt", "dark red", "dark blue"), ("selectedfile", "yellow", "dark blue"), ("selectedfocus", "yellow", "light gray", "bold"), ("dir", "light gray", "dark blue"), ("fileedit", "light green", "dark red"), ('edit', 'yellow', 'dark blue'), ('body','default', 'default'), ('foot','dark cyan', 'dark blue', 'bold'), ('shadow','white','black'), ('border','black','dark blue'), ('error','black','dark red'), ('FxKey','light cyan', 'dark blue', 'underline')] #self.divider = urwid.Divider("-") self.left_header = LeftHeader() self.right_header = RightHeader() self.details = DetailsWidget(self, "result") #self.menu = MenuWidget(self, "footer") self.network = None #self.nodes_walker = NodesWalker(self, self.network) self.listbox_header = NodeItem() self.listbox = NodesBox(self, "body") self.menu = MenuWidget(self, "value") self.nodes = [] self.status_bar = StatusBar() self.header = urwid.Pile([ #self.divider, urwid.Columns([ ('weight', 2, urwid.AttrWrap(self.left_header, 'reverse')), #('fixed', 1, urwid.Divider("|")), ('weight', 2, urwid.AttrWrap(self.right_header, 'reverse')) ], dividechars=2, min_width=8), DIVIDER, self.listbox_header.get_header() ]) # self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), # #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) #self.sub_frame = urwid.Filler(urwid.Frame( \ # urwid.AttrWrap( # self.details, 'sub_frame_body'), \ # header=self.details.header_widget(),\ # footer=self.details.footer_widget(), \ # focus_part="body"), height=9) #self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) # self.footer = urwid.Pile([ # DIVIDER, # self.footer_columns, # DIVIDER, # urwid.AttrWrap(self.status_bar, 'reverse'), # #self.divider, # #urwid.AttrWrap(urwid.Text(" > "), 'footer') # ]) self.footer = urwid.Pile([ DIVIDER, urwid.AttrWrap(self.status_bar, 'reverse'), #self.divider, #urwid.AttrWrap(urwid.Text(" > "), 'footer') ]) self.framefocus = 'body' # self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'), \ # header=self.header,\ # footer=self.footer, \ # focus_part=self.framefocus) self.frame = FrameApp(urwid.AttrWrap(self.listbox, 'body'), \ header=self.header,\ command=(self.menu,1),\ result=(self.details,5),\ # value=self.menu,\ # footer=self.footer, \ log = self.log, \ focus_part=self.framefocus, status_bar=self.footer_display, menu_f=self.footer_display, ) self.frame.set_menu_f(f1="Help",f5="Refresh") self.loop = urwid.MainLoop(self.frame, \ self._palette, \ unhandled_input=self._unhandled_input)
class MainWindow(Screen): def __init__(self, device=None, footer=False, name=None): Screen.__init__(self) self.device = device self.footer_display = footer self._define_log() self._define_screen() self._connect_louie() self._start_network() def _define_log(self): hdlr = logging.FileHandler('/tmp/urwidcmd.log') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') hdlr.setFormatter(formatter) self.log = logging.getLogger('ozwman') self.log.addHandler(hdlr) self.log.setLevel(logging.DEBUG) self.log.info("=" * 15 + " start " + "=" * 15) def _define_screen(self): self._palette = [("title", "yellow", "dark cyan"), ("keys", "dark blue", "light gray"), ("message", "light cyan", "dark green"), ("linenr", "light blue", "dark cyan"), ("input", "light gray", "black"), ("input2", "dark red", "light gray"), ("focus", "black", "light gray", "bold"), ("dialog", "black", "light gray", "bold"), ("file", "light green", "dark blue"), ("errortxt", "dark red", "dark blue"), ("selectedfile", "yellow", "dark blue"), ("selectedfocus", "yellow", "light gray", "bold"), ("dir", "light gray", "dark blue"), ("fileedit", "light green", "dark red"), ('edit', 'yellow', 'dark blue'), ('body', 'default', 'default'), ('foot', 'dark cyan', 'dark blue', 'bold'), ('shadow', 'white', 'black'), ('border', 'black', 'dark blue'), ('error', 'black', 'dark red'), ('FxKey', 'light cyan', 'dark blue', 'underline')] #self.divider = urwid.Divider("-") self.left_header = LeftHeader() self.right_header = RightHeader() self.details = DetailsWidget(self, "result") #self.menu = MenuWidget(self, "footer") self.network = None #self.nodes_walker = NodesWalker(self, self.network) self.listbox_header = NodeItem() self.listbox = NodesBox(self, "body") self.menu = MenuWidget(self, "value") self.nodes = [] self.status_bar = StatusBar() self.header = urwid.Pile([ #self.divider, urwid.Columns( [ ('weight', 2, urwid.AttrWrap(self.left_header, 'reverse')), #('fixed', 1, urwid.Divider("|")), ('weight', 2, urwid.AttrWrap(self.right_header, 'reverse')) ], dividechars=2, min_width=8), DIVIDER, self.listbox_header.get_header() ]) # self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), # #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) #self.sub_frame = urwid.Filler(urwid.Frame( \ # urwid.AttrWrap( # self.details, 'sub_frame_body'), \ # header=self.details.header_widget(),\ # footer=self.details.footer_widget(), \ # focus_part="body"), height=9) #self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) # self.footer = urwid.Pile([ # DIVIDER, # self.footer_columns, # DIVIDER, # urwid.AttrWrap(self.status_bar, 'reverse'), # #self.divider, # #urwid.AttrWrap(urwid.Text(" > "), 'footer') # ]) self.footer = urwid.Pile([ DIVIDER, urwid.AttrWrap(self.status_bar, 'reverse'), #self.divider, #urwid.AttrWrap(urwid.Text(" > "), 'footer') ]) self.framefocus = 'body' # self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'), \ # header=self.header,\ # footer=self.footer, \ # focus_part=self.framefocus) self.frame = FrameApp(urwid.AttrWrap(self.listbox, 'body'), \ header=self.header,\ command=(self.menu,1),\ result=(self.details,5),\ # value=self.menu,\ # footer=self.footer, \ log = self.log, \ focus_part=self.framefocus, status_bar=self.footer_display, menu_f=self.footer_display, ) self.frame.set_menu_f(f1="Help", f5="Refresh") self.loop = urwid.MainLoop(self.frame, \ self._palette, \ unhandled_input=self._unhandled_input) def refresh_nodes(self): self.listbox.body.read_nodes(self.network) self.update_node(self.listbox.walker.get_nodeid()) def update_node(self, nodeid): if nodeid != None: self.details.update( \ nodeid=nodeid, \ name=self.network.nodes[nodeid].name, \ location=self.network.nodes[nodeid].location, \ manufacturer=self.network.nodes[nodeid].manufacturer_name, \ product=self.network.nodes[nodeid].product_name, \ neighbors=self.network.nodes[nodeid].neighbors, \ version=self.network.nodes[nodeid].version, \ signal=self.network.nodes[nodeid].max_baud_rate, \ ) self.log.info('Update node id=%d, product name=%s.' % \ (nodeid, self.network.nodes[nodeid].product_name)) def handle_main_key(self, key): if key == 'f5': self.refresh_nodes() else: self.log.info('unhandled: %s' % repr(key)) def _unhandled_input(self, key): if key == 'esc': self.network.write_config() raise urwid.ExitMainLoop() else: self.log.info('unhandled: %s' % repr(key)) def _start_network(self): #Define some manager options self.options = ZWaveOption(self.device, \ config_path="../openzwave/config", \ user_path=".", cmd_line="") self.options.set_log_file("OZW_Log.log") self.options.set_append_log_file(False) self.options.set_console_output(False) self.options.set_save_log_level('Debug') self.options.set_logging(True) self.options.lock() self.network = ZWaveNetwork(self.options, self.log) self.frame.set_status_bar('Start Network') def _connect_louie(self): dispatcher.connect(self._louie_driver_ready, ZWaveNetwork.SIGNAL_DRIVER_READY) dispatcher.connect(self._louie_network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY) #dispatcher.connect(self._notifyNetworkFailed, ZWaveNetwork.SIGNAL_NETWORK_FAILED) #dispatcher.connect(self._notifyNodeReady, ZWaveNetwork.SIGNAL_NODE_READY) #dispatcher.connect(self._notifyValueChanged, ZWaveNetwork.SIGNAL_VALUE_CHANGED) #dispatcher.connect(self._notifyNodeAdded, ZWaveNetwork.SIGNAL_NODE_ADDED) def _louie_driver_ready(self, network, controller): self.log.info('OpenZWave driver is ready : homeid %0.8x - %d nodes were found.' % \ (network.home_id, network.nodes_count)) self.network = network self.left_header.update_controller("%s on %s" % \ (network.controller.node.product_name, self.device)) self.left_header.update_homeid(network.home_id_str) self.left_header.update_nodes(network.nodes_count, 0) self.right_header.update(network.controller.library_description, \ network.controller.ozw_library_version, \ network.controller.python_library_version) self.frame.set_status_bar('OpenZWave driver is ready') self.loop.draw_screen() def _louie_network_ready(self, network): self.log.info('ZWave network is ready : %d nodes were found.' % network.nodes_count) self.log.info('Controller name : %s' % network.controller.node.product_name) self.network = network self.left_header.update_controller("%s on %s" % \ (network.controller.node.product_name, self.device)) self.left_header.update_nodes(network.nodes_count, 0) #self.set_nodes() self.frame.set_status_bar('ZWave network is ready') self.loop.draw_screen() #self._connect_louie_node() def _connect_louie_node(self): dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_EVENT) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_ADDED) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_NAMING) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_NEW) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_PROTOCOL_INFO) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_READY) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_REMOVED) def _louie_node_update(self, network, node): self.log.info('Node event %s' % node) self.network = network #self.set_nodes() self.frame.set_status_bar('Node event') self.refresh_nodes() self.loop.draw_screen() def _wrap(self, widget, attr_map): return urwid.AttrMap(widget, attr_map) def rawWrite(self, text): """ Add a line of text to our listbox. """ self.walker.append(urwid.Text(text)) self.walker.set_focus(len(self.walker.contents)) def update_screen(self, size): canvas = self.frame.render(size, focus=True) self.draw_screen(size, canvas)
class MainWindow(Screen): def __init__(self, device=None, footer=False, name=None): Screen.__init__(self) self.device = device self.footer_display = footer self._define_log() self._define_screen() self._connect_louie() self._start_network() def _define_log(self): hdlr = logging.FileHandler('/tmp/urwidcmd.log') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') hdlr.setFormatter(formatter) self.log = logging.getLogger('ozwman') self.log.addHandler(hdlr) self.log.setLevel(logging.DEBUG) self.log.info("="*15 + " start " + "="*15) def _define_screen(self): self._palette = [("title", "yellow", "dark cyan"), ("keys", "dark blue", "light gray"), ("message", "light cyan", "dark green"), ("linenr", "light blue", "dark cyan"), ("input", "light gray", "black"), ("input2", "dark red", "light gray"), ("focus", "black", "light gray", "bold"), ("dialog", "black", "light gray", "bold"), ("file", "light green", "dark blue"), ("errortxt", "dark red", "dark blue"), ("selectedfile", "yellow", "dark blue"), ("selectedfocus", "yellow", "light gray", "bold"), ("dir", "light gray", "dark blue"), ("fileedit", "light green", "dark red"), ('edit', 'yellow', 'dark blue'), ('body','default', 'default'), ('foot','dark cyan', 'dark blue', 'bold'), ('shadow','white','black'), ('border','black','dark blue'), ('error','black','dark red'), ('FxKey','light cyan', 'dark blue', 'underline')] #self.divider = urwid.Divider("-") self.left_header = LeftHeader() self.right_header = RightHeader() self.details = DetailsWidget(self, "result") #self.menu = MenuWidget(self, "footer") self.network = None #self.nodes_walker = NodesWalker(self, self.network) self.listbox_header = NodeItem() self.listbox = NodesBox(self, "body") self.menu = MenuWidget(self, "value") self.nodes = [] self.status_bar = StatusBar() self.header = urwid.Pile([ #self.divider, urwid.Columns([ ('weight', 2, urwid.AttrWrap(self.left_header, 'reverse')), #('fixed', 1, urwid.Divider("|")), ('weight', 2, urwid.AttrWrap(self.right_header, 'reverse')) ], dividechars=2, min_width=8), DIVIDER, self.listbox_header.get_header() ]) # self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), # #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) #self.sub_frame = urwid.Filler(urwid.Frame( \ # urwid.AttrWrap( # self.details, 'sub_frame_body'), \ # header=self.details.header_widget(),\ # footer=self.details.footer_widget(), \ # focus_part="body"), height=9) #self.footer_columns = urwid.Columns([ # ('weight', 1, urwid.AttrWrap(self.menu, 'reverse')), #('fixed', 1, urwid.Divider("|")), # ('weight', 3,urwid.AttrWrap(self.details, 'reverse')) # ], dividechars=2, min_width=8) # self.footer = urwid.Pile([ # DIVIDER, # self.footer_columns, # DIVIDER, # urwid.AttrWrap(self.status_bar, 'reverse'), # #self.divider, # #urwid.AttrWrap(urwid.Text(" > "), 'footer') # ]) self.footer = urwid.Pile([ DIVIDER, urwid.AttrWrap(self.status_bar, 'reverse'), #self.divider, #urwid.AttrWrap(urwid.Text(" > "), 'footer') ]) self.framefocus = 'body' # self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'), \ # header=self.header,\ # footer=self.footer, \ # focus_part=self.framefocus) self.frame = FrameApp(urwid.AttrWrap(self.listbox, 'body'), \ header=self.header,\ command=(self.menu,1),\ result=(self.details,5),\ # value=self.menu,\ # footer=self.footer, \ log = self.log, \ focus_part=self.framefocus, status_bar=self.footer_display, menu_f=self.footer_display, ) self.frame.set_menu_f(f1="Help",f5="Refresh") self.loop = urwid.MainLoop(self.frame, \ self._palette, \ unhandled_input=self._unhandled_input) def refresh_nodes(self): self.listbox.body.read_nodes(self.network) self.update_node(self.listbox.walker.get_nodeid()) def update_node(self, nodeid): if nodeid != None : self.details.update( \ nodeid=nodeid, \ name=self.network.nodes[nodeid].name, \ location=self.network.nodes[nodeid].location, \ manufacturer=self.network.nodes[nodeid].manufacturer_name, \ product=self.network.nodes[nodeid].product_name, \ neighbors=self.network.nodes[nodeid].neighbors, \ version=self.network.nodes[nodeid].version, \ signal=self.network.nodes[nodeid].max_baud_rate, \ ) self.log.info('Update node id=%d, product name=%s.' % \ (nodeid, self.network.nodes[nodeid].product_name)) def handle_main_key(self, key): if key == 'f5': self.refresh_nodes() else: self.log.info('unhandled: %s' % repr(key)) def _unhandled_input(self, key): if key == 'esc': self.network.write_config() raise urwid.ExitMainLoop() else: self.log.info('unhandled: %s' % repr(key)) def _start_network(self): #Define some manager options self.options = ZWaveOption(self.device, \ config_path="../openzwave/config", \ user_path=".", cmd_line="") self.options.set_log_file("OZW_Log.log") self.options.set_append_log_file(False) self.options.set_console_output(False) self.options.set_save_log_level('Debug') self.options.set_logging(True) self.options.lock() self.network = ZWaveNetwork(self.options, self.log) self.frame.set_status_bar('Start Network') def _connect_louie(self): dispatcher.connect(self._louie_driver_ready, ZWaveNetwork.SIGNAL_DRIVER_READY) dispatcher.connect(self._louie_network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY) #dispatcher.connect(self._notifyNetworkFailed, ZWaveNetwork.SIGNAL_NETWORK_FAILED) #dispatcher.connect(self._notifyNodeReady, ZWaveNetwork.SIGNAL_NODE_READY) #dispatcher.connect(self._notifyValueChanged, ZWaveNetwork.SIGNAL_VALUE_CHANGED) #dispatcher.connect(self._notifyNodeAdded, ZWaveNetwork.SIGNAL_NODE_ADDED) def _louie_driver_ready(self, network, controller): self.log.info('OpenZWave driver is ready : homeid %0.8x - %d nodes were found.' % \ (network.home_id, network.nodes_count)) self.network = network self.left_header.update_controller("%s on %s" % \ (network.controller.node.product_name, self.device)) self.left_header.update_homeid(network.home_id_str) self.left_header.update_nodes(network.nodes_count,0) self.right_header.update(network.controller.library_description, \ network.controller.ozw_library_version, \ network.controller.python_library_version) self.frame.set_status_bar('OpenZWave driver is ready') self.loop.draw_screen() def _louie_network_ready(self, network): self.log.info('ZWave network is ready : %d nodes were found.' % network.nodes_count) self.log.info('Controller name : %s' % network.controller.node.product_name) self.network = network self.left_header.update_controller("%s on %s" % \ (network.controller.node.product_name, self.device)) self.left_header.update_nodes(network.nodes_count,0) #self.set_nodes() self.frame.set_status_bar('ZWave network is ready') self.loop.draw_screen() #self._connect_louie_node() def _connect_louie_node(self): dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_EVENT) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_ADDED) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_NAMING) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_NEW) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_PROTOCOL_INFO) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_READY) dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE_REMOVED) def _louie_node_update(self, network, node): self.log.info('Node event %s' % node) self.network = network #self.set_nodes() self.frame.set_status_bar('Node event') self.refresh_nodes() self.loop.draw_screen() def _wrap(self, widget, attr_map): return urwid.AttrMap(widget, attr_map) def rawWrite(self, text): """ Add a line of text to our listbox. """ self.walker.append(urwid.Text(text)) self.walker.set_focus(len(self.walker.contents)) def update_screen(self, size): canvas = self.frame.render(size, focus=True) self.draw_screen(size, canvas)