diff options
author | Toshio Kuratomi <a.badger@gmail.com> | 2017-01-21 13:33:35 -0800 |
---|---|---|
committer | Toshio Kuratomi <a.badger@gmail.com> | 2018-01-03 10:23:58 -0800 |
commit | 7ce9d0d1c3205c771ef799f02add867f37326041 (patch) | |
tree | 611de83a87daa500e5d8d94dcbbcc98e3c6d7d37 | |
parent | 2920475c0068d40cadd31d58650d9cfd7a1c2394 (diff) | |
download | urwid-7ce9d0d1c3205c771ef799f02add867f37326041.tar.gz |
Additional listbox functionality
* Add title_align as a new keyword argument to construct a ListBox. It
allows justifying a ListBox to the left or right in addition to
centering it. This can be useful for constructing columns out of
ListBoxes.
* Implement borderless sides. If a ListBox is created with lines or
corners set to the empty string then do not create a border element
for them. This allows adjoining list boxes to share a single border,
or two ListBoxes to seamlessly merge into one another.
Fixes #211
-rwxr-xr-x | urwid/graphics.py | 93 |
1 files changed, 67 insertions, 26 deletions
diff --git a/urwid/graphics.py b/urwid/graphics.py index cb852b0..3d2046b 100755 --- a/urwid/graphics.py +++ b/urwid/graphics.py @@ -96,7 +96,7 @@ class BigText(Widget): class LineBox(WidgetDecoration, WidgetWrap): - def __init__(self, original_widget, title="", + def __init__(self, original_widget, title="", title_align="center", tlcorner=u'┌', tline=u'─', lline=u'│', trcorner=u'┐', blcorner=u'└', rline=u'│', bline=u'─', brcorner=u'┘'): @@ -106,6 +106,9 @@ class LineBox(WidgetDecoration, WidgetWrap): 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 @@ -116,37 +119,73 @@ class LineBox(WidgetDecoration, WidgetWrap): 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. """ - tline, bline = Divider(tline), Divider(bline) - lline, rline = SolidFill(lline), SolidFill(rline) + 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') + 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) + + 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) @@ -158,6 +197,8 @@ class LineBox(WidgetDecoration, WidgetWrap): 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() |