def __init__(self): # self.caption = AttrMap( # Text( # ('caption', self.caption_text), align='center' # ), # 'blackongrey' # ) self.caption = Text(('caption', self.caption_text), align='center') self.inputbox_a = Padding(AttrMap( Edit(multiline=False, mask=self.mask), 'inputfield'), align='center', width=24) self.divider = Padding(Divider(' '), align='center') self.inputbox_b = Padding(AttrMap( Edit(multiline=False, mask=self.mask), 'inputfield'), align='center', width=24) self.innerbox = AttrMap( LineBox(Pile([self.inputbox_a, self.divider, self.inputbox_b])), 'blackongrey') # scratchpad = Text('<enter>') self.button = Button('OK', on_press=self._ok_button) self.button_wrap = Padding(AttrMap(self.button, 'button.normal', 'button.focus'), align='center', width=15)
def _construct_spacer(self, pos, acc): """ build a spacer that occupies the horizontally indented space between pos's parent and the root node. It will return a list of tuples to be fed into a Columns widget. """ parent = self._walker.parent_position(pos) if parent is not None: grandparent = self._walker.parent_position(parent) if self._indent > 0 and grandparent is not None: parent_sib = self._walker.next_sibling_position(parent) draw_vbar = parent_sib is not None and self._arrow_vbar_char is not None space_width = self._indent - 1 * ( draw_vbar) - self._childbar_offset if space_width > 0: void = AttrMap(urwid.SolidFill(' '), self._arrow_att) acc.insert(0, ((space_width, void))) if draw_vbar: barw = urwid.SolidFill(self._arrow_vbar_char) bar = AttrMap(barw, self._arrow_vbar_att or self._arrow_att) acc.insert(0, ((1, bar))) return self._construct_spacer(parent, acc) else: return acc
def __init__(self): self.screen = Screen() self.screen.set_input_timeouts(max_wait=0) self.steps = GridFlow([], 20, 2, 1, 'left') self.progress = SimpleFocusListWalker([]) self.log = SimpleFocusListWalker([]) self.widget = AttrMap( LineBox(Pile([ ('fixed', 6, AttrMap(Filler(self.steps), 'default')), ('fixed', 1, Filler(Divider('\u2500'))), ('fixed', 3, ListBox(self.progress)), AttrMap(LineBox(ListBox(self.log), title='Message log'), 'default') ]), title='Indico 1.2 -> 2.0 migration'), 'global_frame') self.screen.register_palette( [('green', 'light green', ''), ('white', 'white', ''), ('red', 'dark red', ''), ('yellow', 'yellow', ''), ('progress_empty', 'black', 'light gray'), ('progress_progress', 'light cyan', 'light gray'), ('progress_done', 'black', 'light cyan'), ('box', 'white', 'dark gray'), ('step_done', 'light green', ''), ('step_working', 'dark gray', ''), ('global_frame', 'light cyan', ''), ('fill', 'light cyan', 'dark cyan'), ('done', 'white', 'dark green'), ('eta', 'yellow', 'dark gray')] + generate_urwid_palette(PALETTE))
def _build_widget(self, header_text, text, favorite=False): """Return the wrapped widget.""" box_around_status = configuration.styles.get('box_around_status', True) divider = configuration.styles.get('status_divider', False) header = AttrMap(Text(header_text), 'header') sanitized_text = ([sanitize(t) for t in text] if isinstance(text, list) else sanitize(text)) body = Padding(AttrMap(Text(sanitized_text), 'body'), left=1, right=1) border_attr = 'line' if favorite: border_attr = 'favorited' if box_around_status: # draw a box around the status # focusing the first item both dividers are highlighted # on focus widget = AttrMap(BoxDecoration(body, title=header_text), border_attr, 'focus') elif divider: # use a divider # we focus the divider to change colors when this # widget is focused styles = configuration.styles status_divider = styles.get('status_divider_char', '·') divider = AttrMap(Divider(status_divider), border_attr, 'focus') widget = Pile([header, body, divider], focus_item=2) else: widget = Pile([header, body], focus_item=1) return widget
def __init__(self, list_data=None): self.is_editing = False self.tasks = [] self.name = None self.group = None self.id = None if list_data: # Parse the data. self.parse_data(list_data) else: # Must be a new list self.name = 'untitled' self.group = 'none' self.id = uuid.uuid4().hex # AttrSpecs self.attr_spec = AttrSpec('', '') self.focus_nav = AttrSpec('h12', '') self.focus_ins = AttrSpec('h160', '') # Build widget stack self.title = TitleBar(self.name) self.group_foot = GroupFoot(self.group) self.body = urwid.SimpleFocusListWalker(self.tasks) self.list_box = ListBox(self.body) self.list_frame = Frame(self.list_box, header=self.title, footer=self.group_foot) self.line_box = LineBox(self.list_frame) self.line_attr = AttrMap(self.line_box, self.attr_spec, self.focus_nav) super().__init__(self.line_attr)
def __init__(self, edit_text, strike=False, new=False): self.strikethrough = strike self.new_expan = new # Spacing strings self.leading_space = ' ' self.leading_char = '- ' self.leading_STRIKE = 'x ' # Default color specs self.text_attr = AttrSpec('h6', '') self.text_STRIKE = AttrSpec('h6, strikethrough', '') self.focus_attr = AttrSpec('h6, bold', '') self.focus_STRIKE = AttrSpec('h6, bold, strikethrough', '') if not self.strikethrough: caption = self.leading_space + self.leading_char attr = self.text_attr attr_focus = self.focus_attr else: caption = self.leading_space + self.leading_STRIKE attr = self.text_STRIKE attr_focus = self.focus_STRIKE self.edit = Edit(caption, edit_text, wrap='clip') self.map = AttrMap(self.edit, attr_map=attr, focus_map=attr_focus) self.fill = Filler(self.map) super().__init__(self.map)
def update_action_buttons(self): all_actions = [(AssignmentType.BareMetal, 'Add as Bare Metal', self.select_baremetal), (AssignmentType.LXD, 'Add as LXD', self.select_lxd), (AssignmentType.KVM, 'Add as KVM', self.select_kvm)] sc = self.display_controller.selected_service if sc: allowed_set = set(sc.allowed_assignment_types) allowed_types = set([atype for atype, _, _ in all_actions]) allowed_types = allowed_types.intersection(allowed_set) else: allowed_types = set() # + 1 for the cancel button: if len(self.action_buttons) == len(allowed_types) + 1: return self.action_buttons = [ AttrMap(PlainButton(label, on_press=func), 'button_secondary', 'button_secondary focus') for atype, label, func in all_actions if atype in allowed_types ] self.action_buttons.append( AttrMap(PlainButton("Cancel", on_press=self.do_cancel), 'button_secondary', 'button_secondary focus')) opts = self.action_button_cols.options() self.action_button_cols.contents = [(b, opts) for b in self.action_buttons]
def __init__(self, identifier, title, unit, symbol='%', rows=3): self._identifier = identifier self._title = title self._unit = unit self._symbol = symbol self.title = Text('{} ({})'.format(title, unit), align='left') self.label = Text('', align='right') middle = ceil(rows / 2) - 1 self.bars = [ OptionalTextProgressBar( '{} normal'.format(identifier), '{} complete'.format(identifier), satt='{} smooth'.format(identifier), has_text=(middle == r), ) for r in range(rows) ] super().__init__( Pile([ ('pack', Columns([ AttrMap(self.title, '{} title'.format(identifier)), AttrMap(self.label, '{} label'.format(identifier)), ], dividechars=1)), ] + [('pack', bar) for bar in self.bars]))
def build_widgets(self): self.deploy_view = DeployView(self.display_controller, self.placement_controller, self.placement_view) def not_conflicted_p(cc): state, _, _ = self.placement_controller.get_charm_state(cc) return state != CharmState.CONFLICTED actions = [(not_conflicted_p, "Choose Machine", self.placement_view.do_show_machine_chooser)] subordinate_actions = [(not_conflicted_p, "Add", self.do_place_subordinate)] self.required_services_list = ServicesList(self.placement_controller, actions, subordinate_actions, ignore_assigned=True, ignore_deployed=True, show_type='required', show_constraints=True, title="Required Services") self.additional_services_list = ServicesList(self.placement_controller, actions, subordinate_actions, show_type='non-required', show_constraints=True, title="Additional " "Services") autoplace_func = self.placement_view.do_autoplace self.autoplace_button = AttrMap( Button("Auto-place Remaining Services", on_press=autoplace_func), 'button_secondary', 'button_secondary focus') clear_all_func = self.placement_view.do_clear_all self.clear_all_button = AttrMap( Button("Clear all Placements", on_press=clear_all_func), 'button_secondary', 'button_secondary focus') self.required_services_pile = Pile( [self.required_services_list, Divider()]) self.additional_services_pile = Pile( [self.additional_services_list, Divider()]) self.top_buttons = [] self.top_button_grid = GridFlow(self.top_buttons, 36, 1, 0, 'center') pl = [ Text(('subheading', "Services"), align='center'), Divider(), self.top_button_grid, Divider(), self.deploy_view, Divider(), self.required_services_pile, Divider(), self.additional_services_pile ] self.main_pile = Pile(pl) return self.main_pile
def set_success(self): if self.progress: del self.progress[:] self.progress.append( AttrMap(Text('Migration finished!', align='center'), 'done')) self.progress.append( AttrMap(Text('Please press any key...', align='center'), 'done')) self.redraw() self.wait_for_input()
def start(config): """Start the application and handle user input. Blocks until the application exits.""" def item_chosen(button, server): global choice choice = server response = Text( [u'Connecting to: ', server.connection_string(), u'\n']) done = Button(u'Ok') urwid.connect_signal(done, 'click', exit_program) main.original_widget = Filler( Pile([response, AttrMap(done, None, focus_map='reversed')])) def exit_program(button): raise urwid.ExitMainLoop() def unhandled(key): vim_map = {'h': 'left', 'j': 'down', 'k': 'up', 'l': 'right'} if key in vim_map.keys(): list_box.keypress((0, 1), vim_map[key]) elif key in ['left', 'right']: pass elif key in ['esc', 'q']: raise ExitMainLoop() body = [urwid.Text(u'\nServers'), Divider(u'-')] for server in config.get_servers(): button = Button(server.name) urwid.connect_signal(button, 'click', item_chosen, server) body.append(AttrMap(button, None, focus_map='reversed')) list_box = ListBox(urwid.SimpleFocusListWalker(body)) main = Padding(list_box, left=2, right=2) overlay = Overlay(main, SolidFill(u'\N{MEDIUM SHADE}'), align='center', width=('relative', 60), valign='middle', height=('relative', 60), min_width=20, min_height=9) header = AttrMap(Text(u' ssh-menu'), 'header') footer = AttrMap(Text(u'this is the footer'), 'footer') frame = Frame(overlay, header=header, footer=footer) urwid.MainLoop(urwid.AttrMap(frame, 'body'), palette=palette, unhandled_input=unhandled).run() return choice
def main(): background = AttrMap(SolidFill(' '), 'basic') pwdialog = PasswordDialog().compose() box = AttrMap(LineBox(pwdialog), 'blackongrey') window = Overlay(box, background, 'center', 30, 'middle', 10) mainloop = MainLoop(window, unhandled_input=callback, palette=simple_colours) mainloop.run()
def build_widgets(self): self.services_column = ServicesColumn(self.display_controller, self.placement_controller, self) self.machines_column = MachinesColumn(self.display_controller, self.placement_controller, self) self.relations_column = RelationsColumn(self.display_controller, self.placement_controller, self, self.metadata_controller) self.charmstore_column = CharmstoreColumn(self.display_controller, self.placement_controller, self, self.metadata_controller) self.options_column = OptionsColumn(self.display_controller, self.placement_controller, self, self.metadata_controller) self.machines_header = self.get_machines_header(self.machines_column) self.relations_header = self.get_relations_header() self.services_header = self.get_services_header() self.charmstore_header = self.get_charmstore_header( self.charmstore_column) self.options_header = self.get_options_header(self.options_column) cs = [self.services_header, self.charmstore_header] self.header_columns = Columns(cs, dividechars=2) self.columns = Columns([self.services_column, self.machines_column], dividechars=2) self.deploy_button = MenuSelectButton("\nCommit\n", on_press=self.do_deploy) self.deploy_button_label = Text("Some charms use default") self.placement_edit_body_pile = Pile([self.columns]) self.placement_edit_body = Filler(Padding( self.placement_edit_body_pile, align='center', width=('relative', 95)), valign='top') self.bundle_graph_text = Text("No graph to display yet.") self.bundle_graph_widget = Padding(self.bundle_graph_text, 'center', 'pack') b = AttrMap(self.deploy_button, 'frame_header', 'button_primary focus') self.footer_grid = GridFlow( [self.deploy_button_label, Padding(b, width=28, align='center')], 28, 1, 1, 'right') f = AttrMap(self.footer_grid, 'frame_footer', 'frame_footer') self.frame = Frame(header=Pile([self.header_columns, HR()]), body=self.placement_edit_body, footer=f) return self.frame
def update_default(self): title_markup, info_markup = self.get_markup() self.button.set_label(title_markup + ["\n"] + info_markup) if self.state == ServiceWidgetState.SELECTED: b = AttrMap(self.button, 'deploy_highlight_start', 'button_secondary focus') else: b = AttrMap(self.button, 'text', 'button_secondary focus') self.pile.contents = [(b, self.pile.options()), (Divider(), self.pile.options())]
def __init__(self, cap, choices): WidgetWrap.__init__( self, MenuButton([cap, "\N{HORIZONTAL ELLIPSIS}"], self.open_menu)) line = urwid.Divider('\N{LOWER ONE QUARTER BLOCK}') listbox = urwid.ListBox( urwid.SimpleFocusListWalker([ AttrMap(Text(['\n ', cap]), 'heading'), AttrMap(line, 'line'), urwid.Divider() ] + choices + [urwid.Divider()])) self.menu = AttrMap(listbox, 'options')
def update_buttons(self): buttons = [(AttrMap(Button("Cancel", self.handle_cancel), 'button_primary', 'button_primary focus'), self.button_grid.options())] n_assigned = len(self.pc.assigned_services) if n_assigned > 0 and self.pc.can_deploy(): b = AttrMap(Button("Deploy", self.handle_deploy), 'button_primary', 'button_primary focus') else: b = AttrMap(SelectableIcon("(Deploy)"), 'disabled_button', 'disabled_button_focus') buttons.append((b, self.button_grid.options())) self.button_grid.contents = buttons
def __init__(self, tui): self.tui = tui self.header_str = "Q:quit q:previous L:log" self.header = Text(self.header_str) self.body = Pile([]) self.footer = Text("No messages") self.footerpile = Pile([self.footer]) self.frame = Frame(self.body, AttrMap(self.header, 'status'), AttrMap(self.footerpile, 'status'), 'body') urwid.WidgetWrap.__init__(self, self.frame) self.hotkeys = {} ## key:func self.add_hotkey(':', self.start_prompt, 'cmd') self.add_hotkey('u', self.sync, 'sync')
def make_action_menu_row(cells, menu, attr_map='menu_button', focus_map='menu_button focus', cursor_x=2): row = TableRow(cells) if not isinstance(attr_map, dict): attr_map = {None: attr_map} if not isinstance(focus_map, dict): focus_map = {None: focus_map} am = AttrMap(CursorOverride(row, cursor_x=cursor_x), attr_map, focus_map) connect_signal(menu, 'open', lambda menu: am.set_attr_map(focus_map)) connect_signal(menu, 'close', lambda menu: am.set_attr_map(attr_map)) return am
def __init__(self, status, configuration): self.status = status self.configuration = configuration text = status.text status_content = Padding(AttrMap(Text(text), 'body'), left=1, right=1) header = self._create_header(status) box = BoxDecoration(status_content, title=header) if not is_DM(status) and status.is_favorite: widget = AttrMap(box, 'favorited', 'focus') else: widget = AttrMap(box, 'line', 'focus') self.__super.__init__(widget)
def update_unselected(self): markup = self.info_markup() self.button.set_label(markup) self.pile.contents = [(AttrMap(self.button, 'text', 'button_secondary focus'), self.pile.options()), (Divider(), self.pile.options())]
def build_widgets(self): instructions = Text("Remove services from {}".format( self.machine.hostname)) self.machine_widget = MachineWidget(self.machine, self.controller, show_hardware=True) def show_remove_p(cc): md = self.controller.get_assignments(cc) for atype, ms in md.items(): hostnames = [m.hostname for m in ms] if self.machine.hostname in hostnames: return True return False actions = [(show_remove_p, 'Remove', self.do_remove)] self.services_list = ServicesList(self.controller, actions, actions, machine=self.machine) close_button = AttrMap(Button('X', on_press=self.close_pressed), 'button_secondary', 'button_secondary focus') p = Pile([ GridFlow([close_button], 5, 1, 0, 'right'), instructions, Divider(), self.machine_widget, Divider(), self.services_list ]) return LineBox(p, title="Remove Services")
def build_unselected_widgets(self): cdict = juju.constraints_to_dict(self.md.get('constraints', '')) label = str(self.juju_machine_id) self.juju_machine_id_button = SecondaryButton(label, self.show_pin_chooser) self.juju_machine_id_label = Text(label) self.cores_field = IntEdit('', str(cdict.get('cores', ''))) connect_signal(self.cores_field, 'change', self.handle_cores_changed) memval = cdict.get('mem', '') if memval != '': memval = self._format_constraint(memval) / 1024 self.mem_field = Edit('', str(memval)) connect_signal(self.mem_field, 'change', self.handle_mem_changed) diskval = cdict.get('root-disk', '') if diskval != '': diskval = self._format_constraint(diskval) / 1024 self.disk_field = Edit('', str(diskval)) connect_signal(self.disk_field, 'change', self.handle_disk_changed) if self.show_pin: machine_id_w = self.juju_machine_id_button else: machine_id_w = self.juju_machine_id_label cols = [machine_id_w] for field in (self.cores_field, self.mem_field, self.disk_field): cols.append(AttrMap(field, 'string_input', 'string_input_focus')) cols.append(Text("placeholder")) self.unselected_columns = Columns(cols, dividechars=2) self.update_assignments() return self.unselected_columns
def get_widget(self): if isinstance(self.value, str): return AttrMap(Edit('', self.value), 'editable') elif isinstance(self.value, bool): return CheckBox('', self.value) else: return Text("Unknown field for {}".format(str(type(self.value))))
def create_pop_up(self): line_box = LineBox( Filler(Text(self._text, align='center')), title=self._title, ) return AttrMap(line_box, 'popup')
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 menu(): hello = Text( "Приветствую! Для продолжения настройте параметры лабиринта.\n" + "Если карта лабиринта будет некорректно отображаться, " + "попробуйте уменьшить значение ширины или развернуть окно.") height_enter = IntEdit("Высота лабиринта: ", 30) width_enter = IntEdit("Ширина лабиринта: ", 45) done = Button("Готово") done_pad = Padding(done, align="center", width=10) back = AttrMap(SolidFill("\u25E6"), "blueprint") pile = Pile( [hello, Divider("\u2500"), height_enter, width_enter, done_pad]) menu = Filler(LineBox(pile)) main_widget = Overlay(menu, back, align="center", width=35, height=12, valign="middle") loop = MainLoop(main_widget, palette) connect_signal(done, 'click', start_game) loop.run() return MazeGame(height_enter.value(), width_enter.value())
def build_widgets(self, title_widgets): if title_widgets is None: title_widgets = [Text("Machines", align='center')] self.filter_edit_box = FilterBox(self.handle_filter_change) header_widgets = title_widgets + [Divider()] if self.show_filter_box: header_widgets += [self.filter_edit_box, Divider()] labels = ["ID", "Cores", "Memory (GiB)", "Storage (GiB)"] if self.show_assignments: labels += ["Assignments", ""] else: labels += [""] header_label_col = Columns([Text(m) for m in labels], dividechars=2) header_widgets.append(header_label_col) self.header_padding = len(header_widgets) self.add_new_button = AttrMap( PlainButton("Add New Machine", on_press=self.do_add_machine), 'button_secondary', 'button_secondary focus') self.add_new_cols = Columns( [Text(s) for s in [' ', ' ', ' ', ' ', ' ']] + [self.add_new_button], dividechars=2) self.machine_pile = Pile(header_widgets + self.machine_widgets + [self.add_new_cols]) return self.machine_pile
def _construct_arrow_tip(self, pos): cols = [] overall_width = self._icon_offset if self._icon_offset > 0: # how often do we repeat the hbar_char until width icon_offset is reached hbar_char_count = len(self._arrow_hbar_char) / self._icon_offset barw = Text(self._arrow_hbar_char * hbar_char_count) bar = AttrMap(barw, self._arrow_hbar_att or self._arrow_att) cols.insert(1, (self._icon_offset, bar)) # add icon only for non-leafs if self._walker.first_child_position(pos) is not None: iwidth, icon = self._construct_collapse_icon(pos) if icon is not None: cols.insert(0, (iwidth, icon)) overall_width += iwidth # get arrow tip awidth, tip = ArrowTreeListWalker._construct_arrow_tip(self, pos) if tip is not None: cols.append((awidth, tip)) overall_width += awidth return overall_width, Columns(cols)
def __init__(self, title, message): yes_button = FixedButton('Yes') no_button = FixedButton('No') connect_signal(yes_button, 'click', lambda btn: self._emit('yes')) connect_signal(no_button, 'click', lambda btn: self._emit('no')) super().__init__( LineBox( Pile([ ('pack', Text(message)), Filler(Columns([ ('pack', AttrMap(yes_button, 'button', 'inv_button')), ('pack', AttrMap(no_button, 'button', 'inv_button')), ], dividechars=2), valign='bottom') ]), title))
def get_machines_header(self, machines_column): b = PlainButton("Open in Browser", on_press=self.browse_maas) self.open_maas_button = AttrMap(b, 'button_secondary', 'button_secondary focus') self.maastitle = Text("Connected to MAAS") maastitle_widgets = Padding(Columns( [self.maastitle, (22, self.open_maas_button)]), align='center', width='pack', left=2, right=2) f = machines_column.machines_list.handle_filter_change self.filter_edit_box = FilterBox(f) pl = [ Divider(), Text(('body', "Ready Machines {}".format( MetaScroll().get_text()[0])), align='center'), Divider(), maastitle_widgets, Divider(), self.filter_edit_box ] self.machines_header_pile = Pile(pl) return self.machines_header_pile