summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Ward <ian@excess.org>2011-12-27 16:28:48 -0500
committerIan Ward <ian@excess.org>2011-12-27 16:28:48 -0500
commit437386ec13ddea014ce8f54f42d19c65fd5a807e (patch)
treec9112c47af2ade502661433a1cf33baea783d237
parentea3e111f102de61fb1f4a16f10a6bbacdd9d0cf8 (diff)
downloadurwid-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-xurwid/container.py24
-rwxr-xr-xurwid/decoration.py3
-rwxr-xr-xurwid/graphics.py26
-rw-r--r--urwid/listbox.py5
-rw-r--r--urwid/vterm.py6
-rw-r--r--urwid/widget.py78
-rwxr-xr-xurwid/wimp.py42
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)