def _build_lvm_configuration(self): log.debug('lvm: _build_lvm_config') items = [ Text("LVM VOLUMEGROUP CONFIGURATION"), Columns([("weight", 0.2, Text("VolumeGroup Name", align="right")), ("weight", 0.3, Color.string_input(self.volgroup, focus_map="string_input focus"))], dividechars=4), ] return Pile(items)
def __gui_menus(self, s, f): for aj1 in ActivityJournal.at_date(s, self._date): options = [(None, 'None')] + [(aj2, fmt_nearby(aj2, nb)) for aj2, nb in nearby_any_time(s, aj1)] menu = ArrowMenu(label('%s v ' % aj1.name), dict(options)) connect_signal(menu, 'click', self.__show_gui, aj1) button = SquareButton('All Similar') connect_signal(button, 'click', self.__show_similar, aj1) yield Columns([f(menu), f(Padding(Fixed(button, 13), width='clip'))]) button = SquareButton('Health') connect_signal(button, 'click', self.__show_health, self._date) yield f(Padding(Fixed(button, 8), width='clip'))
def __init__(self, edit_changed_cb, label="", info_text=""): self.label = Text(label) self.info_text = Text(info_text) self.editbox = Edit(caption=('text', "Filter: ")) connect_signal(self.editbox, 'change', edit_changed_cb) w = Pile([ Columns([AttrMap(self.editbox, 'filter', 'filter_focus')]) # self.info_text # -- WORKAROUND for issue #194 ]) super().__init__(w)
def _build_node_columns(self, unit, charm_class): """ builds columns of node status """ node_cols = [] status_txt = "[{}] ".format(unit.agent_state) # unit.agent_state may be "pending" despite errors elsewhere, # so we check for error_info first. # if the agent_state is "error", _detect_errors returns that. error_info = self._detect_errors(unit, charm_class) if error_info: status = ("error_icon", "\N{TETRAGRAM FOR FAILURE} ") if unit.agent_state != "error": status_txt = "[{} (error)] ".format(unit.agent_state) elif unit.agent_state == "pending": pending_status = [("pending_icon", "\N{CIRCLED BULLET} "), ("pending_icon", "\N{CIRCLED WHITE BULLET} "), ("pending_icon_on", "\N{FISHEYE} ")] status = random.choice(pending_status) elif unit.agent_state == "installed": status = ("pending_icon", "\N{HOURGLASS} ") elif unit.agent_state == "started": status = ("success_icon", "\u2713 ") elif unit.agent_state == "stopped": status = ("error_icon", "\N{BLACK FLAG} ") elif unit.agent_state == "down": status = ("error_icon", "\N{DOWNWARDS BLACK ARROW} ") else: # shouldn't get here status = "? " node_cols.append(('pack', Text([status, status_txt]))) if unit.public_address: node_cols.append( ('pack', Text("{0:<12}".format(unit.public_address)))) elif error_info: node_cols.append(('pack', Text("{:<12}".format("Error")))) else: node_cols.append(('pack', Text("{:<12}".format("IP Pending")))) if error_info: node_cols.append(('pack', Text(" | {}".format(error_info)))) else: hw_text = Text([" | "] + self._get_hardware_info(unit)) if 'glance-simplestreams-sync' in unit.unit_name: status_oneline = get_sync_status().replace("\n", " - ") sync_text = Text(' ' + status_oneline) node_cols.append(Pile([hw_text, sync_text])) else: node_cols.append(hw_text) return Columns(node_cols)
def build_widget(self): return [ Text("Select primary/external network, " "and datastore for this deployment:"), HR(), Columns([(29, Text('Primary Network', align="right")), Color.string_input(self.vsphere_config['primary-network'], focus_map='string_input focus')], dividechars=1), HR(), Columns( [(29, Text('External Network (optional)', align="right")), Color.string_input(self.vsphere_config['external-network'], focus_map='string_input focus')], dividechars=1), HR(), Columns([(29, Text('Datastore', align="right")), Color.string_input(self.vsphere_config['datastore'], focus_map='string_input focus')], dividechars=1) ]
def __init__(self, prompt, content, done_signal_handler): if content: content += ' ' self.editor = Edit( u'%s (twice enter key to validate or esc) \n>> ' % prompt, content) widgets = [self.editor] w = AttrMap(Columns(widgets), 'editor') connect_signal(self, 'done', done_signal_handler) self.__super.__init__(w)
def _build_node_waiting(self): """ creates a loading screen if nodes do not exist yet """ text = [Padding.line_break(""), self.message, Padding.line_break("")] _boxes = [] _boxes.append(('weight', 1, Text(''))) for i in self.loading_boxes: _boxes.append(('pack', i)) _boxes.append(('weight', 1, Text(''))) _boxes = Columns(_boxes) return Filler(Pile(text + [_boxes]), valign="middle")
def _build_raid_configuration(self): log.debug('raid: _build_raid_config') items = [ Text("RAID CONFIGURATION"), Columns([("weight", 0.2, Text("RAID Level", align="right")), ("weight", 0.3, Color.string_input(Pile(self.raid_level.group), focus_map="string_input focus"))], dividechars=4), Columns([("weight", 0.2, Text("Hot spares", align="right")), ("weight", 0.3, Color.string_input(self.hot_spares, focus_map="string_input focus"))], dividechars=4), Columns([("weight", 0.2, Text("Chunk size", align="right")), ("weight", 0.3, Color.string_input(self.chunk_size, focus_map="string_input focus"))], dividechars=4) ] return Pile(items)
def build_widget(self): self.choices.append(HR()) for addon in sorted(app.addons.values(), key=attrgetter('name')): self.choices.append( CheckBoxValued(addon.friendly_name, value=addon.name)) self.choices.append(Padding.line_break("")) self.choices.append( Columns([('fixed', 3, Text('')), Text(addon.description)], dividechars=5)) self.choices.append(HR()) return self.choices
def summary_columns(log, s, f, date, schedule, names, format_name=lambda n: n): def fill(columns, width): while width < PAGE_WIDTH: columns.append(Text('')) width += 1 def field_columns(name): journals = StatisticJournal.at_interval(s, date, schedule, SummaryCalculator, name, SummaryCalculator) for named, journal in enumerate(journals): summary, period, name = SummaryCalculator.parse_name( journal.statistic_name.name) if not named: yield Text([format_name(name)]), 1 display = SummaryField(log, journal, summary=summary) yield (WEIGHT, display.width, f(display.widget())), display.width, # layout algo here tweaked for subjective appearance columns, width = [], 0 for name in names: if width % 2 and width < PAGE_WIDTH: columns.append(Text('')) width += 1 lookahead = sum(x[1] for x in field_columns(name)) if width and width + lookahead > PAGE_WIDTH: fill(columns, width) yield Columns(columns) columns, width = [], 0 for next_column, next_width in field_columns(name): if width + next_width > PAGE_WIDTH: fill(columns, width) yield Columns(columns) columns, width = [], 0 columns.append(next_column) width += next_width if columns: fill(columns, width) yield Columns(columns)
def _build_form_fields(self): """ Generates widgets for additional input fields. """ form_fields = [] self.fields = [] for i in self.model.additional_input: label = i['label'] key = i['key'] if i['type'] not in self.INPUT_TYPES: self.app.log.error('Invalid input type "{}" in step {}; ' 'should be one of: {}'.format( i['type'], self.model.title, ', '.join(self.INPUT_TYPES.keys()))) field = None else: input_type = self.INPUT_TYPES[i['type']] value = self.app.steps_data[self.model.name][key] if issubclass(input_type, RadioList): select_w = input_type([choice for choice in i['choices']]) select_w.select_option(i['default']) field = StepField(key, label, select_w, i['type']) else: field = StepField(key, label, input_type(default=value), i['type']) self.fields.append(field) column_input = [('weight', 0.5, Padding.left(field.label_widget, left=5))] if field: column_input.append( ('weight', 1, Color.string_input(field.input, focus_map='string_input focus'))) form_fields.extend([ Padding.line_break(""), Columns(column_input, dividechars=3), ]) self.button = SubmitButton(label="Next", on_press=self.submit) self.requires_input = self.sudo_input or self.fields form_fields.extend([ Padding.line_break(""), self.button if self.requires_input else Text(""), HR(), ]) if self.requires_input: self.complete.clear() else: self.complete.set() return form_fields
def build_widgets(self): self.description_w = Text("Description Loading…") self.readme_w = Text("README Loading…") self.scale_edit = IntegerEditor(default=self.service.num_units) connect_signal(self.scale_edit._edit, 'change', self.handle_scale_changed) self.skip_rest_button = PlainButton( "Deploy all {} Remaining Applications with Bundle Defaults".format( self.n_remaining), self.do_skip_rest) col = Columns([(6, Text('Units:', align='right')), (15, Color.string_input(self.scale_edit, focus_map='string_input focus'))], dividechars=1) if self.n_remaining == 0: buttons = [ Padding.right_50( Color.button_primary(PlainButton("Deploy and Continue", self.do_deploy), focus_map='button_primary focus')) ] else: buttons = [ Padding.right_50( Color.button_primary(PlainButton( "Deploy and Configure Next Application", self.do_deploy), focus_map='button_primary focus')), Padding.right_50( Color.button_secondary(self.skip_rest_button, focus_map='button_secondary focus')) ] ws = [ Text("{} of {}: {}".format(self.idx + 1, self.n_total, self.service.service_name.upper())), Padding.center(HR()), Padding.center(self.description_w, left=2), Padding.line_break(""), Padding.center(self.readme_w, left=2), Padding.center(HR()) ] if not self.service.subordinate: ws.append(Padding.left(col, left=1)) ws.append(Padding.line_break("")) ws += buttons self.pile = Pile(ws) return Padding.center_90(Filler(self.pile, valign="top"))
def __init__(self, edit_changed_cb): self.label = Text("") self.info_text = Text("") self.editbox = Edit() connect_signal(self.editbox, 'change', edit_changed_cb) w = Pile([Columns([('pack', self.label), AttrMap(self.editbox, 'filter', 'filter_focus')]) # self.info_text # -- WORKAROUND for issue #194 ]) super().__init__(w)
def _build_iface_inputs(self): col1 = [ Columns([("weight", 0.2, Text("Subnet")), ("weight", 0.3, Color.string_input(self.subnet_input, focus_map="string_input focus")), ("weight", 0.5, Text("CIDR e.g. 192.168.9.0/24"))], dividechars=2), Columns([("weight", 0.2, Text("Address")), ("weight", 0.3, Color.string_input(self.address_input, focus_map="string_input focus")), ("weight", 0.5, Text(""))], dividechars=2), Columns([("weight", 0.2, Text("Gateway")), ("weight", 0.3, Color.string_input(self.gateway_input, focus_map="string_input focus")), ("weight", 0.5, Text(""))], dividechars=2) ] return Pile(col1)
def __init__(self, transport=None): self.transport = transport or self.transport WidgetWrap.__init__( self, AttrMap( Columns([ ('weight', 1, PlayButton(self.transport)), ('weight', 1, RewindButton(self.transport)), ('weight', 3, Text('')), ('weight', 1, MetronomeWidget(self.transport)), ('weight', 1, TempoWidget(self.transport)), ('weight', 1, Text('Quant 1 bar')), ], 1), 'footer'))
def build_widget(self): rows = [ Text("Select a network bridge and storage pool " "for this deployment:"), HR(), Columns([ ('weight', 0.5, Text('network bridge', align="right")), Color.string_input( self.lxd_config['network'], focus_map='string_input focus') ], dividechars=1), HR(), Columns([ ('weight', 0.5, Text('storage pool', align="right")), Color.string_input( self.lxd_config['storage-pool'], focus_map='string_input focus') ], dividechars=1), ] self.pile = Pile(rows) return self.pile
def build_results(self): rows = [] rows.append( Columns([ ('weight', 0.1, Text('Application')), ('weight', 0.4, Text('Result')) ], dividechars=5 ) ) rows.append(HR()) rows.append(Padding.line_break("")) for k, v in self.results.items(): rows.append( Columns( [ ('weight', 0.1, Text(k)), ('weight', 0.4, Text(v)) ], dividechars=5 ) ) self.app.log.debug(rows) return rows
def __init__(self): self.data = DataPoint(0) self._start_time = None self.percentiles = PercentilesList(DataPoint.CUMULATIVE) self.avg_times = AvgTimesList(DataPoint.CUMULATIVE) self.rcodes = RCodesList(DataPoint.CUMULATIVE) self.labels_pile = LabelsPile(DataPoint.CUMULATIVE) original_widget = Pile([ Columns([self.avg_times, self.percentiles, self.rcodes], dividechars=1), self.labels_pile ]) padded = Padding(original_widget, align=CENTER) super(CumulativeStats, self).__init__(padded, " Cumulative Stats ")
def build_fields(self): """ Generates widgets for additional input fields. """ pile_opts = self.step_pile.options() self.fields = [] for i in self.model.additional_input: label = i['label'] key = i['key'] if i['type'] not in self.INPUT_TYPES: self.app.log.error('Invalid input type "{}" in step {}; ' 'should be one of: {}'.format( i['type'], self.model.title, ', '.join(self.INPUT_TYPES.keys()))) field = None else: input_type = self.INPUT_TYPES[i['type']] value = self.app.steps_data[self.model.name][key] if input_type == SelectorHorizontal: select_w = input_type([choice for choice in i['choices']]) select_w.set_default(i['default'], True) field = StepField(key, label, select_w, i['type']) else: field = StepField(key, label, input_type(default=value), i['type']) self.fields.append(field) column_input = [('weight', 0.5, Padding.left(field.label_widget, left=5))] if field: column_input.append( ('weight', 1, Color.string_input(field.input, focus_map='string_input focus'))) self.step_pile.contents.extend([ (Padding.line_break(""), pile_opts), (Columns(column_input, dividechars=3), pile_opts), ]) self.button = submit_btn(label="Next", on_press=self.submit) self.step_pile.contents.extend([ (Padding.line_break(""), pile_opts), (Text(""), pile_opts), (HR(), pile_opts), ]) if self.sudo_input or self.fields: self.show_button() self.step_pile.focus_position = 4 else: self.complete.set()
def __init__(self, opts, default=None): """ :param list opts: list of options to display """ self.opts = opts self.group = [] self.default = default if self.default is True and 'Yes' in opts: self.default = 'Yes' elif self.default is False and 'No' in opts: self.default = 'No' super().__init__(Columns(self._add_options())) if self.default is not None: self.set_default(self.default, True)
def build_widget(self): total_items = [] if self.header: total_items.extend([ Text(self.header), HR(), ]) for field in self.schema.fields(): label = field.key if field.label is not None: label = field.label col = Columns([('weight', 0.5, Text(label, align='right')), Color.string_input(field.widget, focus_map='string_input focus')], dividechars=1) total_items.append(col) total_items.append( Columns([('weight', 0.5, Text("")), Color.error_major(field.error)], dividechars=1)) total_items.append(Padding.line_break("")) return total_items
def _layout(self): self._wallpaper_count = Text(str(len(self._wpctrl.wallpapers))) self._info = Text("", wrap='clip') self._head = Columns([('pack', self._wallpaper_count), (10, Text("Wallpapers")), self._info], dividechars=1) header = Pile([self._head, AttrMap(Divider("─"), 'divider')]) self._screens = [ScreenWidget(screen, self._scrctrl) for screen in self._scrctrl.screens] body = ListBoxWithTabSupport(self._screens) self._root = Frame(header=header, body=body)
def _build_buttons(self): return Columns([ ('fixed', 2, Text("")), ('fixed', 13, Color.menu_button(menu_btn(on_press=self.cancel, label="\n QUIT\n"), focus_map='button_primary focus')), Text(""), ('fixed', 13, Color.menu_button(menu_btn(on_press=self.login, label="\n LOGIN\n"), focus_map='button_primary focus')), ('fixed', 2, Text("")), ])
def build_widgets(self, maxlen): num_str = "{}".format(self.application.num_units) col_pad = 6 self.unit_w = Text('', align='right') self.update_units() cws = [ (maxlen + col_pad, Text(self.application.name)), (10 + len(num_str), self.unit_w), ('weight', 1, Text(" ")), # placeholder for instance type (20, SecondaryButton("Configure", self._cb('config'))), ] self.columns = Columns(cws, dividechars=1) return self.columns
def render(self): """ Renders columns with proper spacing """ items = [('fixed', 2, self.get('icon')), self.get('display_name'), ('fixed', 10, self.get('agent_state')), ('fixed', 12, self.get('public_address')), ('fixed', 9, self.get('machine')), ('fixed', 10, self.get('container')), ('fixed', 7, self.get('arch')), ('fixed', 6, self.get('cpu_cores')), ('fixed', 7, self.get('mem')), ('fixed', 7, self.get('storage'))] return Columns(items)
def schedule_tables(branch): def fmt_rows(branch, ncols, max_cols=4): row = [branch[0]] for b in branch[1:]: # extra case to handle up/down arrow in fitness row.append( create_value_no_measures(b, None, None) if isinstance(b, dict ) else b) if len(row) == max_cols: yield row row = [Text('')] if len(row) > 1: while len(row) < max_cols: row.append(Text('')) yield row if is_row(branch): return branch # will be processed below if isinstance(branch, list) and len(branch) > 1 and any( is_row(b) for b in branch[1:]): ncols = max(len(b) for b in branch[1:] if is_row(b)) all_rows, table = [], [] for b in branch[1:]: if is_row(b): for row in fmt_rows(b, ncols): table.append(row) else: if table: all_rows.append(Columns([Pile(col) for col in zip(*table)])) table = [] all_rows.append(b) if table: all_rows.append(Columns([Pile(col) for col in zip(*table)])) return Pile([branch[0], Indent(Pile(all_rows))]) else: return default_after(branch)
def _gen_credentials(self): total_items = [Text( "Enter your {} credentials:".format(app.current_cloud.upper()))] total_items += [HR()] for field in self.schema.fields(): label = field.key if field.label is not None: label = field.label col = Columns( [ ('weight', 0.5, Text(label, align='right')), Color.string_input( field.widget, focus_map='string_input focus') ], dividechars=1 ) total_items.append(col) total_items.append( Columns( [ ('weight', 0.5, Text("")), Color.error_major(field.error) ], dividechars=1 ) ) total_items.append(Padding.line_break("")) if len(self.regions) > 0: total_items.append( Columns( [ ('weight', 0.5, Text("Select a Cloud Region", align='right')), self.regions_w ], dividechars=1 )) return total_items
def main(): task_list_box = TaskListBox() refresh = partial(on_tasks_refresh, task_list_box) with just_start(write_status, refresh, client_notify) as action_runner: task_list_box.action_handler = ActionHandler(action_runner, FocusedTask(task_list_box)) task_list_box = LineBox(task_list_box, title='Tasks') status_box = LineBox(Filler(status, valign=TOP), title='App Status') columns = Columns([('weight', 1.3, task_list_box), ('weight', 1, status_box)]) MainLoop( TopWidget(columns, footer=pomodoro_status_box), palette=( ('error', *get_error_colors()), ) ).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.columns = Columns([self.services_column, self.machines_column]) self.main_pile = Pile([ Divider(), Text(('subheading', "Machine Placement"), align='center'), Divider(), Padding(self.columns, align='center', width=('relative', 95)) ]) return Filler(self.main_pile, valign='top')
def _build_footer(self): no = menu_btn(on_press=self.cancel, label="\n NO\n") yes = menu_btn(on_press=self.submit, label="\n YES\n") self.buttons = Columns([ ('fixed', 2, Text("")), ('fixed', 11, Color.menu_button(no, focus_map='button_primary focus')), Text(""), ('fixed', 11, Color.menu_button(yes, focus_map='button_primary focus')), ('fixed', 2, Text("")) ]) self.footer = Pile([Padding.line_break(""), self.buttons]) return Color.frame_footer(self.footer)