diff options
author | Ian Ward <ian@excess.org> | 2011-12-27 16:28:48 -0500 |
---|---|---|
committer | Ian Ward <ian@excess.org> | 2011-12-27 16:28:48 -0500 |
commit | 437386ec13ddea014ce8f54f42d19c65fd5a807e (patch) | |
tree | c9112c47af2ade502661433a1cf33baea783d237 | |
parent | ea3e111f102de61fb1f4a16f10a6bbacdd9d0cf8 (diff) | |
download | urwid-437386ec13ddea014ce8f54f42d19c65fd5a807e.tar.gz |
document deprecation of {Flow,Fixed,Box}Widget as base classes and add missing _sizing and sizing() definitions
--HG--
branch : feature-containers
-rwxr-xr-x | urwid/container.py | 24 | ||||
-rwxr-xr-x | urwid/decoration.py | 3 | ||||
-rwxr-xr-x | urwid/graphics.py | 26 | ||||
-rw-r--r-- | urwid/listbox.py | 5 | ||||
-rw-r--r-- | urwid/vterm.py | 6 | ||||
-rw-r--r-- | urwid/widget.py | 78 | ||||
-rwxr-xr-x | urwid/wimp.py | 42 |
7 files changed, 123 insertions, 61 deletions
diff --git a/urwid/container.py b/urwid/container.py index b9ebc89..33ff331 100755 --- a/urwid/container.py +++ b/urwid/container.py @@ -22,8 +22,7 @@ from itertools import chain, repeat from urwid.util import is_mouse_press -from urwid.widget import (Widget, BoxWidget, FlowWidget, Divider, FLOW, FIXED, - PACK) +from urwid.widget import Widget, Divider, FLOW, FIXED, PACK, BOX from urwid.decoration import (Padding, Filler, calculate_padding, calculate_filler, decompose_align_width, decompose_valign_height) from urwid.monitored_list import MonitoredList, MonitoredFocusList @@ -35,7 +34,8 @@ from urwid.canvas import (CompositeCanvas, CanvasOverlay, CanvasCombine, WEIGHT = 'weight' -class GridFlow(FlowWidget): +class GridFlow(Widget): + _sizing = frozenset([FLOW]) def selectable(self): """Return True if the cell in focus is selectable.""" @@ -269,7 +269,10 @@ class GridFlow(FlowWidget): class OverlayError(Exception): pass -class Overlay(BoxWidget): +class Overlay(Widget): + _selectable = True + _sizing = frozenset([BOX]) + def __init__(self, top_w, bottom_w, align, width, valign, height, min_width=None, min_height=None ): """ @@ -468,7 +471,10 @@ class Overlay(BoxWidget): event, button, col-left, row-top, focus ) -class Frame(BoxWidget): +class Frame(Widget): + _selectable = True + _sizing = frozenset([BOX]) + def __init__(self, body, header=None, footer=None, focus_part='body'): """ body -- a box widget for the body of the frame @@ -710,7 +716,9 @@ class Frame(BoxWidget): class PileError(Exception): pass -class Pile(Widget): # either FlowWidget or BoxWidget +class Pile(Widget): + _sizing = frozenset([FLOW, BOX]) + def __init__(self, widget_list, focus_item=None): """ widget_list -- iterable of widgets @@ -1170,7 +1178,9 @@ class ColumnsError(Exception): pass -class Columns(Widget): # either FlowWidget or BoxWidget +class Columns(Widget): + _sizing = frozenset([FLOW, BOX]) + def __init__(self, widget_list, dividechars=0, focus_column=None, min_width=1, box_columns=None): """ diff --git a/urwid/decoration.py b/urwid/decoration.py index b585bd6..01bf01c 100755 --- a/urwid/decoration.py +++ b/urwid/decoration.py @@ -104,8 +104,7 @@ class AttrMapError(WidgetError): class AttrMap(delegate_to_widget_mixin('_original_widget'), WidgetDecoration): """ - AttrMap is a decoration that maps one set of attributes to another for - a FlowWidget or BoxWidget + AttrMap is a decoration that maps one set of attributes to another """ def __init__(self, w, attr_map, focus_map=None): """ diff --git a/urwid/graphics.py b/urwid/graphics.py index 07fc1a8..c42d223 100755 --- a/urwid/graphics.py +++ b/urwid/graphics.py @@ -23,14 +23,16 @@ from urwid.util import decompose_tagmarkup, get_encoding_mode from urwid.canvas import CompositeCanvas, CanvasJoin, TextCanvas, \ CanvasCombine, SolidCanvas -from urwid.widget import WidgetMeta, BoxWidget, FlowWidget, FixedWidget, \ +from urwid.widget import WidgetMeta, Widget, BOX, FIXED, FLOW, \ nocache_widget_render, nocache_widget_render_instance, fixed_size, \ WidgetWrap, Divider, SolidFill, Text, CENTER, CLIP from urwid.container import Pile, Columns from urwid.display_common import AttrSpec from urwid.decoration import WidgetDecoration, AttrWrap -class BigText(FixedWidget): +class BigText(Widget): + _sizing = frozenset([FIXED]) + def __init__(self, markup, font): """ markup -- same as Text widget markup @@ -187,8 +189,11 @@ def nocache_bargraph_get_data(self, get_data_fn): class BarGraphError(Exception): pass -class BarGraph(BoxWidget): +class BarGraph(Widget): __metaclass__ = BarGraphMeta + + _sizing = frozenset([BOX]) + ignore_focus = True eighths = u' ▁▂▃▄▅▆▇' @@ -707,11 +712,12 @@ def calculate_bargraph_display( bardata, top, bar_widths, maxrow ): if y_count: rowsets.append((y_count, last)) - return rowsets - -class GraphVScale(BoxWidget): + +class GraphVScale(Widget): + _sizing = frozenset([BOX]) + def __init__(self, labels, top): """ GraphVScale( [(label1 position, label1 markup),...], top ) @@ -785,7 +791,9 @@ def scale_bar_values( bar, top, maxrow ): return [maxrow - int(float(v) * maxrow / top + 0.5) for v in bar] -class ProgressBar( FlowWidget ): +class ProgressBar(Widget): + _sizing = frozenset([FLOW]) + eighths = u' ▏▎▍▌▋▊▉' text_align = CENTER @@ -867,7 +875,9 @@ class ProgressBar( FlowWidget ): (self.normal,maxcol-ccol)]] return c -class PythonLogo(FixedWidget): +class PythonLogo(Widget): + _sizing = frozenset([FIXED]) + def __init__(self): """ Create canvas containing an ASCII version of the Python diff --git a/urwid/listbox.py b/urwid/listbox.py index ae30eb1..024b789 100644 --- a/urwid/listbox.py +++ b/urwid/listbox.py @@ -21,7 +21,7 @@ from urwid.util import is_mouse_press from urwid.canvas import SolidCanvas, CanvasCombine -from urwid.widget import BoxWidget, nocache_widget_render_instance +from urwid.widget import Widget, nocache_widget_render_instance, BOX from urwid.decoration import calculate_filler, decompose_valign_height from urwid import signals from urwid.signals import connect_signal @@ -167,7 +167,8 @@ class SimpleListWalker(MonitoredList, ListWalker): class ListBoxError(Exception): pass -class ListBox(BoxWidget): +class ListBox(Widget): + _sizing = frozenset([BOX]) def __init__(self, body): """ diff --git a/urwid/vterm.py b/urwid/vterm.py index d832be6..d246dd7 100644 --- a/urwid/vterm.py +++ b/urwid/vterm.py @@ -37,7 +37,7 @@ import traceback from urwid import util from urwid.escape import DEC_SPECIAL_CHARS, ALT_DEC_SPECIAL_CHARS from urwid.canvas import Canvas -from urwid.widget import BoxWidget +from urwid.widget import Widget, BOX from urwid.display_common import AttrSpec, RealTerminal, _BASIC_COLORS from urwid.compat import ord2, chr2, B, bytes @@ -1314,7 +1314,9 @@ class TermCanvas(Canvas): return [self.cols()]*self.rows() return self.content() -class Terminal(BoxWidget): +class Terminal(Widget): + _sizing = frozenset([BOX]) + signals = ['closed', 'beep', 'leds', 'title'] def __init__(self, command, env=None, main_loop=None, escape_sequence=None): diff --git a/urwid/widget.py b/urwid/widget.py index 0cb54d1..d2b7a8b 100644 --- a/urwid/widget.py +++ b/urwid/widget.py @@ -200,7 +200,7 @@ class Widget(object): """ __metaclass__ = WidgetMeta _selectable = False - _sizing = set([]) + _sizing = frozenset([FLOW, BOX, FIXED]) _command_map = command_map # default to the single shared CommandMap def _invalidate(self): @@ -212,29 +212,40 @@ class Widget(object): argument. """ signals.emit_signal(self, name, self, *args) - + def selectable(self): """ Return True if this widget should take focus. Default implementation returns the value of self._selectable. """ return self._selectable - + def sizing(self): """ Return a set including one or more of 'box', 'flow' and 'fixed'. Default implementation returns the value of - self._sizing. + self._sizing, which for the Widget base class includes all + three. + + The sizing modes returned indicate the modes that may be + supported by this widget, but is not sufficient to know + that using that sizing mode will work. Subclasses should + make an effort to remove sizing modes they know will not + work given the state of the widget, but many do not yet + do this. + + If a sizing mode is missing from the set then the widget + should fail when used in that mode. """ return self._sizing def pack(self, size, focus=False): """ - Return a 'packed' (maxcol, maxrow) for this widget. Default + Return a 'packed' (maxcol, maxrow) for this widget. Default implementation (no packing defined) returns size, and calculates maxrow if not given. """ - if size == (): + if not size: if FIXED in self.sizing(): raise NotImplementedError('Fixed widgets must override' ' Widget.pack()') @@ -269,7 +280,7 @@ class Widget(object): words = [] if self.selectable(): words = ["selectable"] + words - if self.sizing(): + if self.sizing() and self.sizing() != frozenset([FLOW, BOX, FIXED]): sizing_modes = list(self.sizing()) sizing_modes.sort() words.append("/".join(sizing_modes)) @@ -277,15 +288,21 @@ class Widget(object): def _repr_attrs(self): return {} - + class FlowWidget(Widget): """ - base class of widgets that determine their rows from the number of + Deprecated. Inherit from Widget and add: + + _sizing = frozenset(['flow']) + + at the top of your class definition instead. + + Base class of widgets that determine their rows from the number of columns available. """ - _sizing = set([FLOW]) - + _sizing = frozenset([FLOW]) + def rows(self, size, focus=False): """ All flow widgets must implement this function. @@ -301,23 +318,30 @@ class FlowWidget(Widget): class BoxWidget(Widget): """ - base class of width and height constrained widgets such as + Deprecated. Inherit from Widget and add: + + _sizing = frozenset(['box']) + _selectable = True + + at the top of your class definition instead. + + Base class of width and height constrained widgets such as the top level widget attached to the display object """ _selectable = True - _sizing = set([BOX]) - + _sizing = frozenset([BOX]) + def render(self, size, focus=False): """ All widgets must implement this function. """ raise NotImplementedError() - + def fixed_size(size): """ raise ValueError if size != (). - + Used by FixedWidgets to test size parameter. """ if size != (): @@ -326,17 +350,23 @@ def fixed_size(size): class FixedWidget(Widget): """ - base class of widgets that know their width and height and + Deprecated. Inherit from Widget and add: + + _sizing = frozenset(['fixed']) + + at the top of your class definition instead. + + Base class of widgets that know their width and height and cannot be resized """ - _sizing = set([FIXED]) - + _sizing = frozenset([FIXED]) + def render(self, size, focus=False): """ All widgets must implement this function. """ raise NotImplementedError() - + def pack(self, size=None, focus=False): """ All fixed widgets must implement this function. @@ -344,10 +374,12 @@ class FixedWidget(Widget): raise NotImplementedError() -class Divider(FlowWidget): +class Divider(Widget): """ Horizontal divider widget """ + _sizing = frozenset([FLOW]) + ignore_focus = True def __init__(self,div_char=u" ",top=0,bottom=0): @@ -446,10 +478,12 @@ class SolidFill(BoxWidget): class TextError(Exception): pass -class Text(FlowWidget): +class Text(Widget): """ a horizontally resizeable text widget """ + _sizing = frozenset([FLOW]) + ignore_focus = True _repr_content_length_max = 140 diff --git a/urwid/wimp.py b/urwid/wimp.py index 8296e67..ac60454 100755 --- a/urwid/wimp.py +++ b/urwid/wimp.py @@ -19,7 +19,8 @@ # # Urwid web site: http://excess.org/urwid/ -from urwid.widget import Text, WidgetWrap, delegate_to_widget_mixin, BOX +from urwid.widget import (Text, WidgetWrap, delegate_to_widget_mixin, BOX, + FLOW) from urwid.canvas import CompositeCanvas from urwid.signals import connect_signal from urwid.container import Columns, Overlay @@ -92,7 +93,10 @@ class CheckBoxError(Exception): pass class CheckBox(WidgetWrap): - states = { + def sizing(self): + return frozenset([FLOW]) + + states = { True: SelectableIcon("[X]"), False: SelectableIcon("[ ]"), 'mixed': SelectableIcon("[#]") } @@ -102,7 +106,7 @@ class CheckBox(WidgetWrap): # sent when the state of this widget is modified # (this variable is picked up by the MetaSignals metaclass) signals = ["change"] - + def __init__(self, label, state=False, has_mixed=False, on_state_change=None, user_data=None): """ @@ -120,12 +124,12 @@ class CheckBox(WidgetWrap): disconnect_signal(check_box, 'change', callback [,user_data]) >>> CheckBox(u"Confirm") - <CheckBox selectable widget 'Confirm' state=False> + <CheckBox selectable flow widget 'Confirm' state=False> >>> CheckBox(u"Yogourt", "mixed", True) - <CheckBox selectable widget 'Yogourt' state='mixed'> + <CheckBox selectable flow widget 'Yogourt' state='mixed'> >>> cb = CheckBox(u"Extra onions", True) >>> cb - <CheckBox selectable widget 'Extra onions' state=True> + <CheckBox selectable flow widget 'Extra onions' state=True> >>> cb.render((20,), focus=True).text # ... = b in Python 3 [...'[X] Extra onions '] """ @@ -157,10 +161,10 @@ class CheckBox(WidgetWrap): >>> cb = CheckBox(u"foo") >>> cb - <CheckBox selectable widget 'foo' state=False> + <CheckBox selectable flow widget 'foo' state=False> >>> cb.set_label(('bright_attr', u"bar")) >>> cb - <CheckBox selectable widget 'bar' state=False> + <CheckBox selectable flow widget 'bar' state=False> """ self._label.set_text(label) # no need to call self._invalidate(). WidgetWrap takes care of @@ -334,9 +338,9 @@ class RadioButton(CheckBox): >>> len(bgroup) 2 >>> b1 - <RadioButton selectable widget 'Agree' state=True> + <RadioButton selectable flow widget 'Agree' state=True> >>> b2 - <RadioButton selectable widget 'Disagree' state=False> + <RadioButton selectable flow widget 'Disagree' state=False> >>> b2.render((15,), focus=True).text # ... = b in Python 3 [...'( ) Disagree '] """ @@ -373,10 +377,10 @@ class RadioButton(CheckBox): ... radio_button.set_label(u"Think Harder!") >>> connect_signal(b3, 'change', relabel_button) >>> b3 - <RadioButton selectable widget 'Unsure' state=False> + <RadioButton selectable flow widget 'Unsure' state=False> >>> b3.set_state(True) # this will trigger the callback >>> b3 - <RadioButton selectable widget 'Think Harder!' state=True> + <RadioButton selectable flow widget 'Think Harder!' state=True> """ if self._state == state: return @@ -413,20 +417,22 @@ class RadioButton(CheckBox): """ self.set_state(True) - class Button(WidgetWrap): + def sizing(self): + return frozenset([FLOW]) + button_left = Text("<") button_right = Text(">") signals = ["click"] - + 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]) @@ -435,12 +441,12 @@ class Button(WidgetWrap): disconnect_signal(button, 'click', callback [,user_data]) >>> Button(u"Ok") - <Button selectable widget 'Ok'> + <Button selectable flow widget 'Ok'> >>> b = Button("Cancel") >>> b.render((15,), focus=True).text # ... = b in Python 3 [...'< Cancel >'] """ - self._label = SelectableIcon("", 0) + self._label = SelectableIcon("", 0) cols = Columns([ ('fixed', 1, self.button_left), self._label, @@ -469,7 +475,7 @@ class Button(WidgetWrap): >>> b = Button("Ok") >>> b.set_label(u"Yup yup") >>> b - <Button selectable widget 'Yup yup'> + <Button selectable flow widget 'Yup yup'> """ self._label.set_text(label) |