def __init__(self, original_widget, title="", tlcorner=u'┌', tline=u'─', lline=u'│', trcorner=u'┐', blcorner=u'└', rline=u'│', bline=u'─', brcorner=u'┘'): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner """ tline, bline = Divider(tline), Divider(bline) lline, rline = SolidFill(lline), SolidFill(rline) tlcorner, trcorner = Text(tlcorner), Text(trcorner) blcorner, brcorner = Text(blcorner), Text(brcorner) self.title_widget = Text(self.format_title(title)) self.tline_widget = Columns([ tline, ('flow', self.title_widget), tline, ]) top = Columns([('fixed', 1, tlcorner), self.tline_widget, ('fixed', 1, trcorner)]) middle = Columns([ ('fixed', 1, lline), original_widget, ('fixed', 1, rline), ], box_columns=[0, 2], focus_column=1) bottom = Columns([('fixed', 1, blcorner), bline, ('fixed', 1, brcorner)]) pile = Pile([('flow', top), middle, ('flow', bottom)], focus_item=1) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile)
def __init__(self, label, on_press=None, user_data=None): """ label -- markup for button label on_press, user_data -- shorthand for connect_signal() function call for a single callback Signals supported: 'click' Register signal handler with: connect_signal(button, 'click', callback [,user_data]) where callback is callback(button [,user_data]) Unregister signal handlers with: disconnect_signal(button, 'click', callback [,user_data]) >>> Button(u"Ok") <Button selectable widget 'Ok'> >>> b = Button("Cancel") >>> b.render((15,), focus=True).text # ... = b in Python 3 [...'< Cancel >'] """ self._label = SelectableIcon("", 0) cols = Columns([('fixed', 1, self.button_left), self._label, ('fixed', 1, self.button_right)], dividechars=1) self.__super.__init__(cols) # The old way of listening for a change was to pass the callback # in to the constructor. Just convert it to the new way: if on_press: connect_signal(self, 'click', on_press, user_data) self.set_label(label)
def __init__( self, original_widget, title="", tlcorner=None, tline=None, lline=None, trcorner=None, blcorner=None, rline=None, bline=None, brcorner=None, ): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner """ self.title_widget = Text(self.format_title(title)) def use_attr(a, t): if a is not None: t = AttrWrap(t, a) return t else: return t self.tline_widget = Columns([Divider(self.ACS_HLINE), ("flow", self.title_widget), Divider(self.ACS_HLINE)]) tline = use_attr(tline, self.tline_widget) bline = use_attr(bline, Divider(self.ACS_HLINE)) lline = use_attr(lline, SolidFill(self.ACS_VLINE)) rline = use_attr(rline, SolidFill(self.ACS_VLINE)) tlcorner = use_attr(tlcorner, Text(self.ACS_ULCORNER)) trcorner = use_attr(trcorner, Text(self.ACS_URCORNER)) blcorner = use_attr(blcorner, Text(self.ACS_LLCORNER)) brcorner = use_attr(brcorner, Text(self.ACS_LRCORNER)) top = Columns([("fixed", 1, tlcorner), tline, ("fixed", 1, trcorner)]) middle = Columns( [("fixed", 1, lline), original_widget, ("fixed", 1, rline)], box_columns=[0, 2], focus_column=1 ) bottom = Columns([("fixed", 1, blcorner), bline, ("fixed", 1, brcorner)]) pile = Pile([("flow", top), middle, ("flow", bottom)], focus_item=1) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile)
def __init__(self, original_widget, title="", tlcorner=u'┌', tline=u'─', lline=u'│', trcorner=u'┐', blcorner=u'└', rline=u'│', bline=u'─', brcorner=u'┘'): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner """ tline, bline = Divider(tline), Divider(bline) lline, rline = SolidFill(lline), SolidFill(rline) tlcorner, trcorner = Text(tlcorner), Text(trcorner) blcorner, brcorner = Text(blcorner), Text(brcorner) self.title_widget = Text(self.format_title(title)) self.tline_widget = Columns([ tline, ('flow', self.title_widget), tline, ]) top = Columns([ ('fixed', 1, tlcorner), self.tline_widget, ('fixed', 1, trcorner) ]) middle = Columns([ ('fixed', 1, lline), original_widget, ('fixed', 1, rline), ], box_columns=[0, 2], focus_column=1) bottom = Columns([ ('fixed', 1, blcorner), bline, ('fixed', 1, brcorner) ]) pile = Pile([('flow', top), middle, ('flow', bottom)], focus_item=1) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile)
def __init__(self, label, on_press=None, user_data=None, delimiters=True): self._label = Text(label, align='center') if delimiters: cols = Columns([('fixed', 1, Text("<")), self._label, ('fixed', 1, Text(">"))], dividechars=1) else: cols = self._label self.__super.__init__(cols) if on_press: connect_signal(self, 'click', on_press, user_data)
def set_state(self, state, do_callback=True): """ Set the CheckBox state. state -- True, False or "mixed" do_callback -- False to suppress signal from this change >>> changes = [] >>> def callback_a(cb, state, user_data): ... changes.append("A %r %r" % (state, user_data)) >>> def callback_b(cb, state): ... changes.append("B %r" % state) >>> cb = CheckBox('tests', False, False) >>> key1 = connect_signal(cb, 'change', callback_a, "user_a") >>> key2 = connect_signal(cb, 'change', callback_b) >>> cb.set_state(True) # both callbacks will be triggered >>> cb.state True >>> disconnect_signal(cb, 'change', callback_a, "user_a") >>> cb.state = False >>> cb.state False >>> cb.set_state(True) >>> cb.state True >>> cb.set_state(False, False) # don't send signal >>> changes ["A True 'user_a'", 'B True', 'B False', 'B True'] """ if self._state == state: return if state not in self.states: raise CheckBoxError("%s Invalid state: %s" % (repr(self), repr(state))) # self._state is None is a special case when the CheckBox # has just been created old_state = self._state if do_callback and old_state is not None: self._emit('change', state) self._state = state # rebuild the display widget with the new state self._w = Columns([('fixed', self.reserve_columns, self.states[state]), self._label]) self._w.focus_col = 0 if do_callback and old_state is not None: self._emit('postchange', old_state)
class LineBox(WidgetDecoration, WidgetWrap): def __init__(self, original_widget, title="", title_align="center", title_attr=None, tlcorner=u'┌', tline=u'─', lline=u'│', trcorner=u'┐', blcorner=u'└', rline=u'│', bline=u'─', brcorner=u'┘'): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. Use `title_attr` to apply a specific attribute to the title text. Use `title_align` to align the title to the 'left', 'right', or 'center'. The default is 'center'. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner If empty string is specified for one of the lines/corners, then no character will be output there. This allows for seamless use of adjoining LineBoxes. """ if tline: tline = Divider(tline) if bline: bline = Divider(bline) if lline: lline = SolidFill(lline) if rline: rline = SolidFill(rline) tlcorner, trcorner = Text(tlcorner), Text(trcorner) blcorner, brcorner = Text(blcorner), Text(brcorner) if not tline and title: raise ValueError('Cannot have a title when tline is empty string') if title_attr: self.title_widget = Text((title_attr, self.format_title(title))) else: self.title_widget = Text(self.format_title(title)) if tline: if title_align not in ('left', 'center', 'right'): raise ValueError('title_align must be one of "left", "right", or "center"') if title_align == 'left': tline_widgets = [('flow', self.title_widget), tline] else: tline_widgets = [tline, ('flow', self.title_widget)] if title_align == 'center': tline_widgets.append(tline) self.tline_widget = Columns(tline_widgets) top = Columns([ ('fixed', 1, tlcorner), self.tline_widget, ('fixed', 1, trcorner) ]) else: self.tline_widget = None top = None middle_widgets = [] if lline: middle_widgets.append(('fixed', 1, lline)) else: # Note: We need to define a fixed first widget (even if it's 0 width) so that the other # widgets have something to anchor onto middle_widgets.append(('fixed', 0, SolidFill(u""))) middle_widgets.append(original_widget) focus_col = len(middle_widgets) - 1 if rline: middle_widgets.append(('fixed', 1, rline)) middle = Columns(middle_widgets, box_columns=[0, 2], focus_column=focus_col) if bline: bottom = Columns([ ('fixed', 1, blcorner), bline, ('fixed', 1, brcorner) ]) else: bottom = None pile_widgets = [] if top: pile_widgets.append(('flow', top)) pile_widgets.append(middle) focus_pos = len(pile_widgets) - 1 if bottom: pile_widgets.append(('flow', bottom)) pile = Pile(pile_widgets, focus_item=focus_pos) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile) def format_title(self, text): if len(text) > 0: return " %s " % text else: return "" def set_title(self, text): if not self.title_widget: raise ValueError('Cannot set title when tline is unset') self.title_widget.set_text(self.format_title(text)) self.tline_widget._invalidate()
def __init__(self, original_widget, title="", title_align="center", tlcorner='┌', tline='─', lline='│', trcorner='┐', blcorner='└', rline='│', bline='─', brcorner='┘'): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. Use `title_align` to align the title to the 'left', 'right', or 'center'. The default is 'center'. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner .. note:: This differs from the vanilla urwid LineBox by discarding the a line if the middle of the line is set to either None or the empty string. """ if tline: tline = Divider(tline) if bline: bline = Divider(bline) if lline: lline = SolidFill(lline) if rline: rline = SolidFill(rline) tlcorner, trcorner = Text(tlcorner), Text(trcorner) blcorner, brcorner = Text(blcorner), Text(brcorner) if not tline and title: raise ValueError('Cannot have a title when tline is unset') self.title_widget = Text(self.format_title(title)) if tline: if title_align not in ('left', 'center', 'right'): raise ValueError( 'title_align must be one of "left", "right", or "center"') if title_align == 'left': tline_widgets = [('flow', self.title_widget), tline] else: tline_widgets = [tline, ('flow', self.title_widget)] if title_align == 'center': tline_widgets.append(tline) self.tline_widget = Columns(tline_widgets) top = Columns([('fixed', 1, tlcorner), self.tline_widget, ('fixed', 1, trcorner)]) else: self.tline_widget = None top = None middle_widgets = [] if lline: middle_widgets.append(('fixed', 1, lline)) middle_widgets.append(original_widget) focus_col = len(middle_widgets) - 1 if rline: middle_widgets.append(('fixed', 1, rline)) middle = Columns(middle_widgets, box_columns=[0, 2], focus_column=focus_col) if bline: bottom = Columns([('fixed', 1, blcorner), bline, ('fixed', 1, brcorner)]) else: bottom = None pile_widgets = [] if top: pile_widgets.append(('flow', top)) pile_widgets.append(middle) focus_pos = len(pile_widgets) - 1 if bottom: pile_widgets.append(('flow', bottom)) pile = Pile(pile_widgets, focus_item=focus_pos) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile)
class LineBox(WidgetDecoration, WidgetWrap): def __init__( self, original_widget, title="", tlcorner=u"┌", tline=u"─", lline=u"│", trcorner=u"┐", blcorner=u"└", rline=u"│", bline=u"─", brcorner=u"┘", ): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner """ tline, bline = Divider(tline), Divider(bline) lline, rline = SolidFill(lline), SolidFill(rline) tlcorner, trcorner = Text(tlcorner), Text(trcorner) blcorner, brcorner = Text(blcorner), Text(brcorner) self.title_widget = Text(self.format_title(title)) self.tline_widget = Columns([tline, ("flow", self.title_widget), tline]) top = Columns([("fixed", 1, tlcorner), self.tline_widget, ("fixed", 1, trcorner)]) middle = Columns( [("fixed", 1, lline), original_widget, ("fixed", 1, rline)], box_columns=[0, 2], focus_column=1 ) bottom = Columns([("fixed", 1, blcorner), bline, ("fixed", 1, brcorner)]) pile = Pile([("flow", top), middle, ("flow", bottom)], focus_item=1) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile) def format_title(self, text): if len(text) > 0: return " %s " % text else: return "" def set_title(self, text): self.title_widget.set_text(self.format_title(text)) self.tline_widget._invalidate()
class LineBox(WidgetDecoration, WidgetWrap): ACS_HLINE = u'─' ACS_VLINE = u'│' ACS_ULCORNER = u'┌' ACS_URCORNER = u'┐' ACS_LLCORNER = u'└' ACS_LRCORNER = u'┘' def __init__(self, original_widget, title="", tlcorner=None, tline=None, lline=None, trcorner=None, blcorner=None, rline=None, bline=None, brcorner=None): """ Draw a line around original_widget. Use 'title' to set an initial title text with will be centered on top of the box. You can also override the widgets used for the lines/corners: tline: top line bline: bottom line lline: left line rline: right line tlcorner: top left corner trcorner: top right corner blcorner: bottom left corner brcorner: bottom right corner """ self.title_widget = Text(self.format_title(title)) def use_attr(a, t): if a is not None: t = AttrWrap(t, a) return t else: return t self.tline_widget = Columns([ Divider(self.ACS_HLINE), ('flow', self.title_widget), Divider(self.ACS_HLINE), ]) tline = use_attr(tline, self.tline_widget) bline = use_attr(bline, Divider(self.ACS_HLINE)) lline = use_attr(lline, SolidFill(self.ACS_VLINE)) rline = use_attr(rline, SolidFill(self.ACS_VLINE)) tlcorner = use_attr(tlcorner, Text(self.ACS_ULCORNER)) trcorner = use_attr(trcorner, Text(self.ACS_URCORNER)) blcorner = use_attr(blcorner, Text(self.ACS_LLCORNER)) brcorner = use_attr(brcorner, Text(self.ACS_LRCORNER)) top = Columns([('fixed', 1, tlcorner), tline, ('fixed', 1, trcorner)]) middle = Columns([('fixed', 1, lline), original_widget, ('fixed', 1, rline)], box_columns=[0, 2], focus_column=1) bottom = Columns([('fixed', 1, blcorner), bline, ('fixed', 1, brcorner)]) pile = Pile([('flow', top), middle, ('flow', bottom)], focus_item=1) WidgetDecoration.__init__(self, original_widget) WidgetWrap.__init__(self, pile) def format_title(self, text): if len(text) > 0: return " %s " % text else: return "" def set_title(self, text): self.title_widget.set_text(self.format_title(text)) self.tline_widget._invalidate()