def build_widgets(self): readme_files = glob(os.path.join(app.config['spell-dir'], 'README.*')) if len(readme_files) == 0: self.readme_w = Text("No README found for bundle.") else: readme_file = readme_files[0] if len(readme_files) != 1: utils.warning("Unexpected: {} files matching README.*" "- using {}".format(len(readme_files), readme_file)) with open(readme_file) as rf: rlines = [Text(l) for l in rf.readlines()] self.readme_w = BoxAdapter(ListBox(rlines), self.initial_height) ws = [Text("About {}:".format(app.config['spell'])), Padding.right_50(Color.button_primary( PlainButton("Continue", self.do_continue), focus_map='button_primary focus')), Padding.center(HR()), Padding.center(self.readme_w, left=2), Padding.center(HR()), Padding.center(Text("Use arrow keys to scroll text " "and TAB to select the button."))] self.pile = Pile(ws) return Padding.center_90(Filler(self.pile, valign="top"))
def _build_widget(self, **kwargs): total_items = [] for _item in self.radio_items.keys(): desc = AttrWrap( Text(" {}".format( self.radio_items[_item][1])), 'input', 'input focus') total_items.append( AttrWrap(self.radio_items[_item][0], 'input', 'input focus')) total_items.append(AttrWrap(desc, 'input')) total_items.append(Divider('-')) self.input_lbox = ListBox(SimpleListWalker(total_items[:-1])) self.add_buttons() self.container_box_adapter = BoxAdapter(self.input_lbox, len(total_items)) self.container_lbox = ListBox( [self.container_box_adapter, Divider(), self.btn_pile]) return LineBox( BoxAdapter(self.container_lbox, height=len(total_items) + 3), title=self.title)
def build_widgets(self): readme_files = glob(os.path.join(self.spell_dir, 'README.*')) if len(readme_files) == 0: self.readme_w = Text("No README found for bundle.") else: readme_file = readme_files[0] if len(readme_files) != 1: utils.warning("Unexpected: {} files matching README.*" "- using {}".format(len(readme_files), readme_file)) with open(readme_file) as rf: rlines = [Text(l) for l in rf.readlines()] self.readme_w = BoxAdapter(ListBox(rlines), self.initial_height) ws = [ Text("About {}:".format(self.spell_name)), Padding.right_50( Color.button_primary(PlainButton("Continue", self.do_continue), focus_map='button_primary focus')), Padding.center(HR()), Padding.center(self.readme_w, left=2), Padding.center(HR()), Padding.center( Text("Use arrow keys to scroll text " "and TAB to select the button.")) ] self.pile = Pile(ws) return Padding.center_90(Filler(self.pile, valign="top"))
def __init__(self, height, directory=".", file="", attr=(None, None), show_hidden=False): """ height -- height of the directory list and the file list directory, file -- default selection attr -- (inner selectable widgets, selected widgets) show_hidden -- If True, hidden files are shown by default. """ self.directory = abspath(directory) self.file = "" self.attr = attr self.height = height self.show_hidden = show_hidden # Create dummy widgets for directory and file display: self.dir_widget = AttrWrap( BoxAdapter(ListBox([self._blank]), self.height), self.attr[0]) self.file_widget = AttrWrap( BoxAdapter(ListBox([self._blank]), self.height), self.attr[0]) columns = Columns([self.dir_widget, self.file_widget], 1) # Selection widget: self.select_widget = AttrWrap(Edit("", ""), self.attr[0], self.attr[1]) # Buttons and checkbox: button_widgets = [ AttrWrap(Button(button, self._action), attr[0], attr[1]) for button in ["OK", "Cancel"] ] button_grid = GridFlow(button_widgets, 12, 2, 1, 'center') button_cols = Columns([ CheckBox(self.SHOW_HIDDEN_TEXT, self.show_hidden, False, self._toggle_hidden), button_grid ]) self.outer_widget = Pile([ columns, self._blank, Text(self.SELECTION_TEXT), self.select_widget, self._blank, button_cols ]) self.update_widgets() WidgetWrap.__init__(self, self.outer_widget)
def __init__(self, msg=None, height=10): if not msg: msg = "Processing." listbox = ListBox([Text(msg)]) box_adapter = BoxAdapter(listbox, height=height) linebox = LineBox(box_adapter, title="Info") super().__init__(AttrWrap(linebox, 'dialog'))
def __init__(self, num_rows=20, w=(14, 14, 18, 16, 16, 16, 20)): """ @method __init__ Initializes the widget """ self.m_process_list = ProcessList(w) self.prev_sort_item = None self.w_status = HeaderButton('Status', 'status', self.handle_click) self.w_pid = HeaderButton('PID', 'pid', self.handle_click) self.w_name = HeaderButton('Name', 'name', self.handle_click) self.w_cpu = HeaderButton('CPU %', 'cpu_perc', self.handle_click) self.w_mem = HeaderButton('MEM %', 'mem_perc', self.handle_click) self.w_up = HeaderButton('Uptime', 'uptime', self.handle_click) self.w_pname = HeaderButton('Process', 'pname', self.handle_click) self.w_cpu.activate() self.prev_sort_item = self.w_cpu self.header_buttons = h = [ self.w_status, self.w_pid, self.w_name, self.w_cpu, self.w_mem, self.w_up, self.w_pname ] m_header = AttrMap( Columns([('fixed', w[i], h[i]) for i in range(0, len(h))]), 'invert') m_lb = ListBox( SimpleListWalker( [m_header, BoxAdapter(self.m_process_list, num_rows)])) super(ProcessTable, self).__init__(m_lb, None) self.update()
def __init__(self, name, number): WidgetWrap.__init__( self, BoxAdapter(Filler(BaseClipButton(str(number).rjust(3), name), top=1, bottom=1), height=3))
def _build_footer(self): def _pack(btn): return ('fixed', len(btn.label) + 4, btn) buttons = [] buttons.append(('fixed', 2, Text(""))) buttons.append(_pack(self.button('QUIT', app.ui.quit))) if self.show_back_button: buttons.append(_pack(self.button('BACK', self.prev_screen))) buttons.append(('weight', 2, Text(""))) buttons.extend([_pack(btn) for btn in self.build_buttons()]) buttons.append(('fixed', 2, Text(""))) self.button_row = Columns(buttons, 2) self.footer_msg = Text(self.footer) footer_widget = Columns([ Text(''), ('pack', self.footer_msg), Text(''), ]) footer_widget = Padding.center_90(self.footer_msg) if self.footer_height != 'auto': footer_widget = BoxAdapter(Filler(footer_widget, valign='bottom'), self.footer_height) footer = Pile([ Padding.center_90(HR()), Color.body(footer_widget), Padding.line_break(""), Color.frame_footer( Pile([ Padding.line_break(""), self.button_row, ])), ]) return footer
def _process_tree(self): top = self.docker_container.top().response logger.debug(top) if top: self.walker.append(RowWidget([SelectableText("")])) self.walker.append(RowWidget([SelectableText("Process Tree", maps=get_map("main_list_white"))])) self.walker.append(BoxAdapter(ProcessTree(top), len(top)))
def _create_text(self): self.text = [] for line in self.HELP_TEXT: self._insert_line(line) return LineBox(BoxAdapter( ScrollableListBox(self.text), height=20), title='Help \u21C5 Scroll (ESC) Close')
def _build_model_inputs(self): sl = [] for lang in self.model.get_menu(): sl.append( Color.menu_button(menu_btn(label=lang, on_press=self.confirm), focus_map="menu_button focus")) return BoxAdapter(SimpleList(sl), height=len(sl))
def _build_model_inputs(self): sl = [] for ipath, sig in self.model.get_menu(): log.debug("Building inputs: {}".format(ipath)) sl.append( menu_btn(label=ipath, on_press=self.confirm, user_arg=sig)) return BoxAdapter(SimpleList(sl), height=len(sl))
def __init__(self, parent, ssids): self.parent = parent button = cancel_btn(_("Cancel"), on_press=self.do_cancel) ssid_list = [menu_btn(label=ssid, on_press=self.do_network) for ssid in ssids] p = Pile([BoxAdapter(ListBox(ssid_list), height=10), Padding.fixed_10(button)]) box = LineBox(p, title="Select a network") super().__init__(box)
def _build_widget(self, **kwargs): total_items = [] for _item in self.input_items.keys(): total_items.append( AttrWrap(self.input_items[_item], 'input', 'input focus')) self.input_lbox = ListBox(SimpleListWalker(total_items)) # Add buttons self.add_buttons() self.container_box_adapter = BoxAdapter(self.input_lbox, len(total_items)) self.container_lbox = ListBox( [self.container_box_adapter, Divider(), self.btn_pile]) return LineBox(BoxAdapter(self.container_lbox, height=len(total_items) + 1 + len(self.btn_pile.contents)), title=self.title)
def _build_widget(self, **kwargs): # Charm selections num_of_items, charm_sel = self._insert_charm_selections() # Control buttons buttons = self._insert_buttons() return LineBox(BoxAdapter(ListBox([charm_sel, Divider(), buttons]), height=num_of_items + 2), title="Add unit")
def _build_model_inputs(self): log.debug('FileSystemView: building model inputs') col_1 = [] col_2 = [] avail_disks = self.model.get_available_disk_names() if len(avail_disks) == 0: return Pile([Color.info_minor(Text("No available disks."))]) for dname in avail_disks: disk = self.model.get_disk_info(dname) device = self.model.get_disk(dname) btn = menu_btn(label=disk.name, on_press=self.show_disk_partition_view) col_1.append(Color.menu_button(btn, focus_map='menu_button focus')) disk_sz = _humanize_size(disk.size) log.debug('device partitions: {}'.format(len(device.partitions))) # if we've consumed some of the device, show # the remaining space and percentage of the whole if len(device.partitions) > 0: free, percent = self._get_percent_free(device) disk_sz = "{} ({}%) free".format(free, percent) col_2.append(Text(disk_sz)) for partname in device.available_partitions: part = device.get_partition(partname) btn = menu_btn(label=partname, on_press=self.show_disk_partition_view) col_1.append( Color.menu_button(btn, focus_map='menu_button focus')) col_2.append(Text(_humanize_size(part.size))) col_1 = BoxAdapter(SimpleList(col_1), height=len(col_1)) col_2 = BoxAdapter(SimpleList(col_2, is_selectable=False), height=len(col_2)) return Columns([(16, col_1), col_2], 2)
def build_menuable_items(self): """ Builds a list of bundles available to install """ bundles = self.common['config']['bundles'] cols = [] for bundle in bundles: cols.append( Columns( [("weight", 0.2, Color.body(menu_btn(label=bundle['name'], on_press=self.done), focus_map="button_primary focus")), ("weight", 0.3, Text(bundle['summary'], align="left"))], dividechars=1)) cols.append(Padding.line_break("")) return BoxAdapter(SimpleList(cols), height=len(cols) + 2)
def _insert_charm_selections(self): first_index = 0 bgroup = [] for i, charm_class in enumerate(self.charms): charm = charm_class if charm.name() and not first_index: first_index = i r = RadioButton(bgroup, charm.name()) r.text_label = charm.name() self.boxes.append(r) # Add input widget for specifying NumUnits self.count_editor = IntEdit("Number of units to add: ", 1) self.boxes.append(self.count_editor) wrapped_boxes = self._wrap_focus(self.boxes) items = ListBox(SimpleListWalker(wrapped_boxes)) items.set_focus(first_index) return (len(self.boxes), BoxAdapter(items, len(self.boxes)))
def _build_footer(self): footer_pile = Pile([ Padding.center_90(HR()), Color.body( BoxAdapter( Filler(Columns([ Text(''), ('pack', self.message), Text(''), ]), valign='bottom'), 7)), Padding.line_break(""), Color.frame_footer( Columns([('fixed', 2, Text("")), ('fixed', 13, self._build_buttons())])), ]) self.update_message() return footer_pile
def _build_model_inputs(self): partitioned_disks = [] for mnt, size, fstype, path in self.disk_obj.get_fs_table(): mnt = Text(mnt) size = Text("{}".format(_humanize_size(size))) fstype = Text(fstype) if fstype else '-' path = Text(path) if path else '-' partition_column = Columns([(15, path), size, fstype, mnt], 4) partitioned_disks.append(partition_column) free_space = _humanize_size(self.disk_obj.freespace) partitioned_disks.append( Columns([(15, Text("FREE SPACE")), Text(free_space), Text(""), Text("")], 4)) return BoxAdapter(SimpleList(partitioned_disks, is_selectable=False), height=len(partitioned_disks))
def main(): # optional param # rows p = ProcessTable() r = ResourceManager() # height is num_cpus rows + mem row + swap row + empty row r_height = len(r.cpu_meters) + 3 frame = Frame(p, header=BoxAdapter(r, r_height), footer=Footer()) def exit(key): if key in ('q', 'Q'): raise ExitMainLoop() def refresh(loop, data): p.update() r.update() loop.set_alarm_in(2, refresh) mainloop = MainLoop(frame, palette, pop_ups=True, unhandled_input=exit) mainloop.set_alarm_in(1, refresh) mainloop.run()
def create_interface(): m_map = Padding(LineBox(minimap, tlcorner='', tline='', lline='', trcorner='', blcorner='', rline='│', bline='', brcorner=''), align="center", width=35) _help = Text(("help", "Карта - m, тетрадь - c,\nНачать зарисовку - q\n" + "сделать отметку - CTRL+arrow_key"), align="center") #column = Columns([description, Pile([m_map, _help]), BoxAdapter( column = Columns([ description, m_map, BoxAdapter(Filler(location_text, valign=("relative", 20)), 20) ]) return Filler(Padding(column, align="center", width=120), valign="middle")
def exploreFieldSet(field_set, args, options={}): charset = getTerminalCharset() ui = urwid.curses_display.Screen() ui.register_palette(( ('focus', 'white', 'dark blue'), ('sep', 'white', 'dark red'), ('input', 'black', 'light gray'), )) msgs = [[], [], 0] hachoir_log.use_print = False def logger(level, prefix, text, ctxt): if ctxt is not None: c = [] if hasattr(ctxt, "_logger"): c[:0] = [ctxt._logger()] if issubclass(ctxt.__class__, Field): ctxt = ctxt["/"] name = logger.objects.get(ctxt) if name: c[:0] = [name] if c: text = "[%s] %s" % ('|'.join(c), text) if not isinstance(text, str): text = str(text, charset) msgs[0].append((level, prefix, text)) logger.objects = WeakKeyDictionary() hachoir_log.on_new_message = logger preload_fields = 1 + max(0, args.preload) log_count = [0, 0, 0] sep = Separator("log: %%u/%%u/%%u | %s " % "F1: help") sep.set_info(*tuple(log_count)) body = Tabbed(sep) help = ('help', ListBox([Text(getHelpMessage())])) logger.objects[field_set] = logger.objects[ field_set.stream] = name = 'root' body.append((name, TreeBox(charset, Node(field_set, None), preload_fields, args.path, options))) log = BoxAdapter(ListBox(msgs[1]), 0) log.selectable = lambda: False wrapped_sep = AttrWrap(sep, 'sep') footer = Pile([('flow', wrapped_sep), log]) # awful way to allow the user to hide the log widget log.render = lambda size, focus=False: BoxAdapter.render( log, size[:1], focus) footer.render = lambda arg, focus=False: Pile.render( footer, (arg[0], sep.rows(arg) + log.height), focus) top = Frame(body, None, footer) def input_enter(w): footer.widget_list[0] = w footer.set_focus(0) top.set_focus('footer') def input_leave(): footer.widget_list[0] = wrapped_sep footer.set_focus(0) top.set_focus('body') input = Input(input_enter, input_leave) def run(): msg = _resize = retry = 0 events = ("window resize", ) profile_display = args.profile_display while True: for e in events: try: if e == "window resize": size = ui.get_cols_rows() resize = log.height else: e = top.keypress(size, e) if e is None: pass elif e in ('f1', '?'): try: body.select(body.tabs.index(help)) except ValueError: body.append(help) resize = log.height elif e in ('esc', 'ctrl w'): body.close() if body.original_widget is None: return resize = log.height elif e == '+': if log.height: resize = log.height - 1 elif e == '-': resize = log.height + 1 elif e == 'q': return # except AssertionError: # hachoir_log.error(getBacktrace()) except NewTab_Stream as e: stream = e.field.getSubIStream() logger.objects[stream] = e = "%u/%s" % ( body.active, e.field.absolute_address) parser = guessParser(stream) if not parser: hachoir_log.error("No parser found for %s" % stream.source) else: logger.objects[parser] = e body.append((e, TreeBox(charset, Node(parser, None), preload_fields, None, options))) resize = log.height except NeedInput as e: input.do(*e.args) if profile_display: events = events[1:] break while True: if msgs[0]: for level, prefix, text in msgs[0]: log_count[level] += 1 txt = Text("[%u]%s %s" % (msg, prefix, text)) msg += 1 msgs[1].append(txt) _resize += txt.rows(size[:1]) if log.height < _resize and (resize is None or resize < _resize): resize = _resize try: log.set_focus(len(msgs[1]) - 1) except IndexError: pass sep.set_info(*tuple(log_count)) msgs[0] = [] if resize is not None: body.height = size[1] - sep.rows(size[:1]) - resize if body.height <= 0: resize += body.height - 1 body.height = 1 log.height = resize resize = None canvas = top.render(size, focus=True) if not msgs[0]: _resize = retry = 0 break assert not retry retry += 1 ui.draw_screen(size, canvas) msgs[2] = len(msgs[1]) if profile_display and events: continue while True: events = ui.get_input() if events: break try: ui.run_wrapper(run) except Exception: pending = [msg.get_text()[0] for msg in msgs[1][msgs[2]:]] + \ ["[*]%s %s" % (prefix, text) for level, prefix, text in msgs[0]] if pending: print("\nPending messages:\n" + '\n'.join(pending)) raise
def _resources(self): self.view_widgets.append(RowWidget([SelectableText("")])) self.view_widgets.append( RowWidget([ SelectableText("Resource Usage", maps=get_map("main_list_white")) ])) cpu_g = ContainerInfoGraph("graph_lines_cpu_tips", "graph_lines_cpu") mem_g = ContainerInfoGraph("graph_lines_mem_tips", "graph_lines_mem") blk_r_g = ContainerInfoGraph("graph_lines_blkio_r_tips", "graph_lines_blkio_r") blk_w_g = ContainerInfoGraph("graph_lines_blkio_w_tips", "graph_lines_blkio_w") net_r_g = ContainerInfoGraph("graph_lines_net_r_tips", "graph_lines_net_r") net_w_g = ContainerInfoGraph("graph_lines_net_w_tips", "graph_lines_net_w") cpu_label = ColorText("CPU ", "graph_lines_cpu_legend") cpu_value = ColorText("0.0 %", "graph_lines_cpu_legend") mem_label = ColorText("Memory ", "graph_lines_mem_legend") mem_value = ColorText("0.0 %", "graph_lines_mem_legend") blk_r_label = ColorText("I/O Read ", "graph_lines_blkio_r_legend") blk_r_value = ColorText("0 B", "graph_lines_blkio_r_legend") blk_w_label = ColorText("I/O Write ", "graph_lines_blkio_w_legend") blk_w_value = ColorText("0 B", "graph_lines_blkio_w_legend") net_r_label = ColorText("Net Rx ", "graph_lines_net_r_legend") net_r_value = ColorText("0 B", "graph_lines_net_r_legend") net_w_label = ColorText("Net Tx ", "graph_lines_net_w_legend") net_w_value = ColorText("0 B", "graph_lines_net_w_legend") self.view_widgets.append( urwid.Columns([ BoxAdapter(cpu_g, 12), BoxAdapter(mem_g, 12), ("weight", 0.5, BoxAdapter(blk_r_g, 12)), ("weight", 0.5, BoxAdapter(blk_w_g, 12)), ("weight", 0.5, BoxAdapter(net_r_g, 12)), ("weight", 0.5, BoxAdapter(net_w_g, 12)), BoxAdapter( UnselectableListBox( urwid.SimpleFocusListWalker([ UnselectableRowWidget([(12, cpu_label), cpu_value]), UnselectableRowWidget([(12, mem_label), mem_value]), UnselectableRowWidget([(12, blk_r_label), blk_r_value]), UnselectableRowWidget([(12, blk_w_label), blk_w_value]), UnselectableRowWidget([(12, net_r_label), net_r_value]), UnselectableRowWidget([(12, net_w_label), net_w_value]), ])), 12), ])) self.view_widgets.append(RowWidget([SelectableText("")])) @log_traceback def realtime_updates(): g = self.docker_container.stats().response while True: try: update = next(g) except Exception as ex: if "Timeout" in ex.__class__.__name__: logger.info("timeout when reading stats: %r", ex) g = self.docker_container.stats().response continue logger.error("error while getting stats: %r", ex) self.ui.notify_message("Error while getting stats: %s" % ex, level="error") break if self.stop.is_set(): break logger.debug(update) cpu_percent = update["cpu_percent"] cpu_value.text = "%.2f %%" % cpu_percent cpu_g.rotate_value(int(cpu_percent), max_val=100) mem_percent = update["mem_percent"] mem_current = humanize_bytes(update["mem_current"]) mem_value.text = "%.2f %% (%s)" % (mem_percent, mem_current) mem_g.rotate_value(int(mem_percent), max_val=100) blk_read = update["blk_read"] blk_write = update["blk_write"] blk_r_value.text = humanize_bytes(blk_read) blk_w_value.text = humanize_bytes(blk_write) r_max_val = blk_r_g.rotate_value(blk_read, adaptive_max=True) w_max_val = blk_w_g.rotate_value(blk_write, adaptive_max=True) blk_r_g.set_max(max((r_max_val, w_max_val))) blk_w_g.set_max(max((r_max_val, w_max_val))) net_read = update["net_rx"] net_write = update["net_tx"] net_r_value.text = humanize_bytes(net_read) net_w_value.text = humanize_bytes(net_write) r_max_val = net_r_g.rotate_value(net_read, adaptive_max=True) w_max_val = net_w_g.rotate_value(net_write, adaptive_max=True) net_r_g.set_max(max((r_max_val, w_max_val))) net_w_g.set_max(max((r_max_val, w_max_val))) self.thread = threading.Thread(target=realtime_updates, daemon=True) self.thread.start()
class BundleReadmeView(WidgetWrap): def __init__(self, metadata_controller, done_callback, initial_height): self.metadata_controller = metadata_controller self.done_callback = done_callback self.initial_height = initial_height w = self.build_widgets() super().__init__(w) self.pile.focus_position = 1 def selectable(self): return True def keypress(self, size, key): if key == 'tab': cur = self.pile.focus_position self.pile.focus_position = 3 if cur == 1 else 1 else: return super(BundleReadmeView, self).keypress(size, key) def build_widgets(self): readme_files = glob(os.path.join(app.config['spell-dir'], 'README.*')) if len(readme_files) == 0: self.readme_w = Text("No README found for bundle.") else: readme_file = readme_files[0] if len(readme_files) != 1: utils.warning("Unexpected: {} files matching README.*" "- using {}".format(len(readme_files), readme_file)) with open(readme_file) as rf: rlines = [Text(l) for l in rf.readlines()] self.readme_w = BoxAdapter(ListBox(rlines), self.initial_height) ws = [Text("About {}:".format(app.config['spell'])), Padding.right_50(Color.button_primary( PlainButton("Continue", self.do_continue), focus_map='button_primary focus')), Padding.center(HR()), Padding.center(self.readme_w, left=2), Padding.center(HR()), Padding.center(Text("Use arrow keys to scroll text " "and TAB to select the button."))] self.pile = Pile(ws) return Padding.center_90(Filler(self.pile, valign="top")) def handle_readme_updated(self, readme_text_f): EventLoop.loop.event_loop._loop.call_soon_threadsafe( self._update_readme_on_main_thread, readme_text_f) def _update_readme_on_main_thread(self, readme_text_f): self.readme_w.set_text(readme_text_f.result().splitlines()) self._invalidate() def do_continue(self, arg): self.done_callback()
def set_step_banner(self, msg): if self.progress: del self.progress[:] self.progress.append(BoxAdapter(AttrMap(SolidFill('#'), 'fill'), 3))
def exploreFieldSet(field_set, args, options={}): charset = getTerminalCharset() ui = urwid.curses_display.Screen() ui.register_palette(( ('focus', 'white', 'dark blue'), ('sep', 'white', 'dark red'), ('input', 'black', 'light gray'), )) msgs = [[],[],0] hachoir_log.use_print = False def logger(level, prefix, text, ctxt): if ctxt is not None: c = [] if hasattr(ctxt, "_logger"): c[:0] = [ ctxt._logger() ] if issubclass(ctxt.__class__, Field): ctxt = ctxt["/"] name = logger.objects.get(ctxt) if name: c[:0] = [ name ] if c: text = "[%s] %s" % ('|'.join(c), text) if not isinstance(text, unicode): text = unicode(text, charset) msgs[0].append((level, prefix, text)) logger.objects = WeakKeyDictionary() hachoir_log.on_new_message = logger preload_fields = 1 + max(0, args.preload) log_count = [ 0, 0, 0 ] sep = Separator("log: %%u/%%u/%%u | %s " % _("F1: help")) sep.set_info(*tuple(log_count)) body = Tabbed(sep) help = ('help', ListBox([ Text(getHelpMessage()) ])) logger.objects[field_set] = logger.objects[field_set.stream] = name = u'root' body.append((name, TreeBox(charset, Node(field_set, None), preload_fields, args.path, options))) log = BoxAdapter(ListBox(msgs[1]), 0) log.selectable = lambda: False wrapped_sep = AttrWrap(sep, 'sep') footer = Pile([ ('flow', wrapped_sep), log ]) # awful way to allow the user to hide the log widget log.render = lambda size, focus=False: BoxAdapter.render(log, size[:1], focus) footer.render = lambda (maxcol,), focus=False: Pile.render(footer, (maxcol, sep.rows((maxcol,))+log.height), focus) top = Frame(body, None, footer) def input_enter(w): footer.widget_list[0] = w footer.set_focus(0) top.set_focus('footer') def input_leave(): footer.widget_list[0] = wrapped_sep footer.set_focus(0) top.set_focus('body') input = Input(input_enter, input_leave) def run(): msg = _resize = retry = 0 events = ( "window resize", ) profile_display = args.profile_display while True: for e in events: try: if e == "window resize": size = ui.get_cols_rows() resize = log.height else: e = top.keypress(size, e) if e is None: pass elif e in ('f1', '?'): try: body.select(body.tabs.index(help)) except ValueError: body.append(help) resize = log.height elif e in ('esc', 'ctrl w'): body.close() if body.box_widget is None: return resize = log.height elif e == '+': if log.height: resize = log.height - 1 elif e == '-': resize = log.height + 1 elif e == 'q': return #except AssertionError: # hachoir_log.error(getBacktrace()) except NewTab_Stream, e: stream = e.field.getSubIStream() logger.objects[stream] = e = "%u/%s" % (body.active, e.field.absolute_address) parser = guessParser(stream) if not parser: hachoir_log.error(_("No parser found for %s") % stream.source) else: logger.objects[parser] = e body.append((e, TreeBox(charset, Node(parser, None), preload_fields, None, options))) resize = log.height except NeedInput, e: input.do(*e.args) if profile_display: events = events[1:] break while True: if msgs[0]: for level, prefix, text in msgs[0]: log_count[level] += 1 txt = Text("[%u]%s %s" % (msg, prefix, text)) msg += 1 msgs[1].append(txt) _resize += txt.rows(size[:1]) if log.height < _resize and (resize is None or resize < _resize): resize = _resize log.set_focus(len(msgs[1])-1) sep.set_info(*tuple(log_count)) msgs[0] = [] if resize is not None: body.height = size[1] - sep.rows(size[:1]) - resize if body.height <= 0: resize += body.height - 1 body.height = 1 log.height = resize resize = None canvas = top.render(size, focus=True) if not msgs[0]: _resize = retry = 0 break assert not retry retry += 1 ui.draw_screen(size, canvas) msgs[2] = len(msgs[1]) if profile_display and events: continue while True: events = ui.get_input() if events: break
class BundleReadmeView(WidgetWrap): def __init__(self, metadata_controller, spell_name, spell_dir, done_callback, initial_height): self.metadata_controller = metadata_controller self.spell_name = spell_name self.spell_dir = spell_dir self.done_callback = done_callback self.initial_height = initial_height w = self.build_widgets() super().__init__(w) self.pile.focus_position = 1 def selectable(self): return True def keypress(self, size, key): if key == 'tab': cur = self.pile.focus_position self.pile.focus_position = 3 if cur == 1 else 1 else: return super(BundleReadmeView, self).keypress(size, key) def build_widgets(self): readme_files = glob(os.path.join(self.spell_dir, 'README.*')) if len(readme_files) == 0: self.readme_w = Text("No README found for bundle.") else: readme_file = readme_files[0] if len(readme_files) != 1: utils.warning("Unexpected: {} files matching README.*" "- using {}".format(len(readme_files), readme_file)) with open(readme_file) as rf: rlines = [Text(l) for l in rf.readlines()] self.readme_w = BoxAdapter(ListBox(rlines), self.initial_height) ws = [ Text("About {}:".format(self.spell_name)), Padding.right_50( Color.button_primary(PlainButton("Continue", self.do_continue), focus_map='button_primary focus')), Padding.center(HR()), Padding.center(self.readme_w, left=2), Padding.center(HR()), Padding.center( Text("Use arrow keys to scroll text " "and TAB to select the button.")) ] self.pile = Pile(ws) return Padding.center_90(Filler(self.pile, valign="top")) def handle_readme_updated(self, readme_text_f): EventLoop.loop.event_loop._loop.call_soon_threadsafe( self._update_readme_on_main_thread, readme_text_f) def _update_readme_on_main_thread(self, readme_text_f): self.readme_w.set_text(readme_text_f.result().splitlines()) self._invalidate() def do_continue(self, arg): self.done_callback()