summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Ward <ian@excess.org>2011-12-29 23:18:12 -0500
committerIan Ward <ian@excess.org>2011-12-29 23:18:12 -0500
commit3d845102b76574d7b8171eaddc343030d5e36d84 (patch)
tree2f00cb69c0dd2599383f860e4aa2ef8f2898814e
parentef1d9cf775492f2ec41334d4dc67861132912908 (diff)
downloadurwid-3d845102b76574d7b8171eaddc343030d5e36d84.tar.gz
Pile, Columns: use 'given' instead of 'fixed' to avoid confusion w/fixed widgets
--HG-- branch : feature-containers
-rwxr-xr-xurwid/container.py135
-rwxr-xr-xurwid/tests.py19
2 files changed, 96 insertions, 58 deletions
diff --git a/urwid/container.py b/urwid/container.py
index 3c7c888..76d9894 100755
--- a/urwid/container.py
+++ b/urwid/container.py
@@ -22,7 +22,8 @@
from itertools import chain, repeat
from urwid.util import is_mouse_press
-from urwid.widget import Widget, Divider, FLOW, FIXED, PACK, BOX, WidgetWrap
+from urwid.widget import (Widget, Divider, FLOW, FIXED, PACK, BOX, WidgetWrap,
+ GIVEN)
from urwid.decoration import (Padding, Filler, calculate_padding,
calculate_filler, decompose_align_width, decompose_valign_height)
from urwid.monitored_list import MonitoredList, MonitoredFocusList
@@ -193,7 +194,7 @@ class GridFlow(WidgetWrap):
if position < 0 or position >= len(self.contents):
raise IndexError
except (TypeError, IndexError):
- raise IndexError, "No child widget at position %s" % (position,)
+ raise IndexError, "No GridFlow child widget at position %s" % (position,)
self.contents.focus = position
focus_position = property(_get_focus_position, _set_focus_position,
doc="index of child widget in focus or None when GridFlow is empty")
@@ -241,7 +242,7 @@ class GridFlow(WidgetWrap):
pad = Padding(c, self.align)
p.contents.append((pad, Pile.options()))
- c.contents.append((w, Columns.options('fixed', width)))
+ c.contents.append((w, Columns.options(GIVEN, width)))
if i == self.focus_position:
c.focus_position = len(c.contents) - 1
p.focus_position = len(p.contents) - 1
@@ -780,14 +781,19 @@ class Pile(Widget):
selectable widget will be chosen.
widget_list may also contain tuples such as:
- ('flow', widget) always treat widget as a flow widget
- ('fixed', height, widget) give this box widget a fixed height
+ (given_height, widget) always treat widget as a box widget and
+ give it given_height rows, where given_height is an int
+ ('flow', widget) always treat widget as a flow widget, allowing
+ it to calculate its own height by calling its rows() method
('weight', weight, widget) if the pile is treated as a box
widget then treat widget as a box widget with a
height based on its relative weight value, otherwise
- treat widget as a flow widget
+ treat the same as ('flow', widget).
- widgets not in a tuple are the same as ('weight', 1, widget)
+ Widgets not in a tuple are the same as ('weight', 1, widget)
+
+ For backwards compatibility ('fixed', given_height, widget) is
+ accepted as an alternate form of (given_height, widget).
If the Pile is treated as a box widget there must be at least
one 'weight' tuple in widget_list.
@@ -806,7 +812,13 @@ class Pile(Widget):
elif w[0] == FLOW:
f, w = w
self.contents.append((w, (FLOW, None)))
- elif w[0] in (FIXED, WEIGHT):
+ elif len(w) == 2:
+ height, w = w
+ self.contents.append((w, (GIVEN, height)))
+ elif w[0] == FIXED: # backwards compatibility
+ _ignore, height, w = w
+ self.contents.append((w, (GIVEN, height)))
+ elif w[0] == WEIGHT:
f, height, w = w
self.contents.append((w, (f, height)))
else:
@@ -824,7 +836,7 @@ class Pile(Widget):
for item in new_items:
try:
w, (t, n) = item
- if t not in (FLOW, FIXED, WEIGHT):
+ if t not in (FLOW, GIVEN, WEIGHT):
raise ValueError
except (TypeError, ValueError):
raise PileError("added content invalid: %r" % (item,))
@@ -838,7 +850,7 @@ class Pile(Widget):
def _set_widget_list(self, widgets):
focus_position = self.focus_position
self.contents = [
- (new, t) for (new, (w, t)) in zip(widgets,
+ (new, options) for (new, (w, options)) in zip(widgets,
# need to grow contents list if widgets is longer
chain(self.contents, repeat((None, (WEIGHT, 1)))))]
if focus_position < len(widgets):
@@ -850,7 +862,10 @@ class Pile(Widget):
""")
def _get_item_types(self):
- ml = MonitoredList(t for w, t in self.contents)
+ ml = MonitoredList(
+ # return the old item type names
+ ({GIVEN: FIXED}.get(f, f), height)
+ for w, (f, height) in self.contents)
def user_modified():
self._set_item_types(ml)
ml.set_modified_callback(user_modified)
@@ -858,7 +873,9 @@ class Pile(Widget):
def _set_item_types(self, item_types):
focus_position = self.focus_position
self.contents = [
- (w, new) for (new, (w, t)) in zip(item_types, self.contents)]
+ (w, ({FIXED: GIVEN}.get(new_t, new_t), new_height))
+ for ((new_t, new_height), (w, options))
+ in zip(item_types, self.contents)]
if focus_position < len(item_types):
self.focus_position = focus_position
item_types = property(_get_item_types, _set_item_types, doc="""
@@ -877,7 +894,7 @@ class Pile(Widget):
options currently may be one of:
('flow', None) -- Always treat widget as a flow widget, i.e. let it
calculate the number of rows it will display.
- ('fixed', n) -- Always treat widget as a box widget with a fixed
+ ('given', n) -- Always treat widget as a box widget with a given
height of n rows.
('weight', w) -- If the Pile itself is treated as a box widget then
the value w will be used as a relative weight for assigning rows
@@ -901,13 +918,13 @@ class Pile(Widget):
"""
Return a new options tuple for use in a Pile's .contents list.
- height_calc -- 'flow', 'fixed' or 'weight'
+ height_calc -- 'flow', 'given' or 'weight'
height_amount -- None for 'flow', a number of rows for 'fixed'
or a weight value for 'weight'
"""
if height_calc == FLOW:
return (FLOW, None)
- if height_calc not in (FIXED, WEIGHT):
+ if height_calc not in (GIVEN, WEIGHT):
raise PileError('invalid height_calc: %r' % (height_calc,))
return (height_calc, height_amount)
@@ -969,8 +986,11 @@ class Pile(Widget):
position -- index of child widget to be made focus
"""
- if not self.contents:
- raise IndexError("Can't set focus position on an empty Pile")
+ try:
+ if position < 0 or position >= len(self.contents):
+ raise IndexError
+ except (TypeError, IndexError):
+ raise IndexError, "No Pile child widget at position %s" % (position,)
self.contents.focus = position
focus_position = property(_get_focus_position, _set_focus_position,
doc="index of child widget in focus or None when Pile is empty")
@@ -988,7 +1008,7 @@ class Pile(Widget):
"""
maxcol = size[0]
w, (f, height) = self.contents[i]
- if f == FIXED:
+ if f == GIVEN:
return (maxcol, height)
elif f == WEIGHT and len(size) == 2:
if not item_rows:
@@ -1012,7 +1032,7 @@ class Pile(Widget):
if remaining is None:
# pile is a flow widget
for w, (f, height) in self.contents:
- if f == FIXED:
+ if f == GIVEN:
l.append(height)
else:
l.append(w.rows((maxcol,),
@@ -1027,7 +1047,7 @@ class Pile(Widget):
rows = w.rows((maxcol,), focus=focus and self.focus_item == w)
l.append(rows)
remaining -= rows
- elif f == FIXED:
+ elif f == GIVEN:
l.append(height)
remaining -= height
else:
@@ -1061,7 +1081,7 @@ class Pile(Widget):
for i, (w, (f, height)) in enumerate(self.contents):
item_focus = self.focus_item == w
canv = None
- if f == FIXED:
+ if f == GIVEN:
canv = w.render((maxcol, height), focus=focus and item_focus)
elif f == FLOW or len(size)==1:
canv = w.render((maxcol,), focus=focus and item_focus)
@@ -1094,8 +1114,8 @@ class Pile(Widget):
w, (f, height) = self.contents[i]
item_rows = None
maxcol = size[0]
- if f == FIXED or (f == WEIGHT and len(size) == 2):
- if f == FIXED:
+ if f == GIVEN or (f == WEIGHT and len(size) == 2):
+ if f == GIVEN:
maxrow = height
else:
if item_rows is None:
@@ -1249,19 +1269,26 @@ class Columns(Widget):
focus_column -- index into widget_list of column in focus,
if None the first selectable widget will be chosen.
min_width -- minimum width for each column which is not
- designated as flow widget in widget_list.
+ calling widget.pack() in widget_list.
box_columns -- a list of column indexes containing box widgets
whose maxrow is set to the maximum of the rows
required by columns not listed in box_columns.
widget_list may also contain tuples such as:
- ('pack', widget) call pack() to calculate the width
- ('fixed', width, widget) give this column a fixed width
- ('weight', weight, widget) give this column a relative weight
+ (given_width, widget) make this column given_width screen columns
+ wide, where given_width is an int
+ ('pack', widget) call widget.pack() to calculate the width of
+ this column
+ ('weight', weight, widget) give this column a relative weight to
+ calculate its width from the screen columns remaining
+
+ Widgets not in a tuple are the same as ('weight', 1, widget)
- widgets not in a tuple are the same as ('weight', 1, widget)
+ For backwards compatibility ('fixed', given_width, widget) and
+ ('flow', widget) are accepted as an alternate forms of
+ (given_width, widget) and ('pack', widget) respectively.
- Is the Columns widget is treated as a box widget then all children
+ If the Columns widget is treated as a box widget then all children
are treated as box widgets, and box_columns is ignored.
If the Columns widget is treated as a flow widget then the rows
@@ -1284,9 +1311,16 @@ class Columns(Widget):
self.contents.append((w, (WEIGHT, 1, i in box_columns)))
elif w[0] in (FLOW, PACK): # 'pack' used to be called 'flow'
f = PACK
- w = w[1]
+ _ignored, w = w
self.contents.append((w, (f, None, i in box_columns)))
- elif w[0] in (FIXED, WEIGHT):
+ elif len(w) == 2:
+ width, w = w
+ self.contents.append((w, (GIVEN, width, i in box_columns)))
+ elif w[0] == FIXED: # backwards compatibility
+ f = GIVEN
+ _ignored, width, w = w
+ self.contents.append((w, (GIVEN, width, i in box_columns)))
+ elif w[0] == WEIGHT:
f, width, w = w
self.contents.append((w, (f, width, i in box_columns)))
else:
@@ -1310,7 +1344,7 @@ class Columns(Widget):
for item in new_items:
try:
w, (t, n, b) = item
- if t not in (PACK, FIXED, WEIGHT):
+ if t not in (PACK, GIVEN, WEIGHT):
raise ValueError
except (TypeError, ValueError):
raise ColumnsError("added content invalid %r" % (item,))
@@ -1324,7 +1358,7 @@ class Columns(Widget):
def _set_widget_list(self, widgets):
focus_position = self.focus_position
self.contents = [
- (new, t) for (new, (w, t)) in zip(widgets,
+ (new, options) for (new, (w, options)) in zip(widgets,
# need to grow contents list if widgets is longer
chain(self.contents, repeat((None, (WEIGHT, 1, False)))))]
if focus_position < len(widgets):
@@ -1336,24 +1370,25 @@ class Columns(Widget):
""")
def _get_column_types(self):
- ml = MonitoredList(t[:2] for w, t in self.contents)
+ ml = MonitoredList(
+ # return the old column type names
+ ({GIVEN: FIXED, PACK: FLOW}.get(t, t), n)
+ for w, (t, n, b) in self.contents)
def user_modified():
self._set_column_types(ml)
ml.set_modified_callback(user_modified)
return ml
def _set_column_types(self, column_types):
focus_position = self.focus_position
- contents = []
- for (new, (w, (t, n, b))) in zip(column_types, self.contents):
- if new[0] == FLOW:
- new = (PACK, ) + new[1:]
- contents.append((w, new + (b,)))
- self.contents = contents
+ self.contents = [
+ (w, ({FIXED: GIVEN, FLOW: PACK}.get(new_t, new_t), new_n, b))
+ for ((new_t, new_n), (w, (t, n, b)))
+ in zip(column_types, self.contents)]
if focus_position < len(column_types):
self.focus_position = focus_position
column_types = property(_get_column_types, _set_column_types, doc="""
- A list of the partial options values for widgets in this Pile, for
- backwards compatibility only. You should use the new standard
+ A list of the old partial options values for widgets in this Pile,
+ for backwards compatibility only. You should use the new standard
container property .contents to modify Pile contents.
""")
@@ -1406,7 +1441,7 @@ class Columns(Widget):
width_amount, box_widget), where width_calc is one of:
'pack' -- Call the widget's pack() method to determine how wide
this column should be. width_amount is ignored.
- 'fixed' -- Make column exactly width_amount screen-columns wide.
+ 'given' -- Make column exactly width_amount screen-columns wide.
'weight' -- Allocate the remaining space to this column by using
width_amount as a weight value.
@@ -1427,15 +1462,15 @@ class Columns(Widget):
"""
Return a new options tuple for use in a Pile's .contents list.
- width_calc -- 'pack', 'fixed' or 'weight'
- width_amount -- None for 'pack', a number of rows for 'fixed'
- or a weight value for 'weight'
+ width_calc -- 'pack', 'given' or 'weight'
+ width_amount -- None for 'pack', a number of screen columns
+ for 'given' or a weight value for 'weight'
box_widget -- True to treat as box widget when Columns is
treated as a flow widget
"""
if width_calc == PACK:
width_amount = None
- if width_calc not in (PACK, FIXED, WEIGHT):
+ if width_calc not in (PACK, GIVEN, WEIGHT):
raise ColumnsError('invalid width_calc: %r' % (width_calc,))
return (width_calc, width_amount, box_widget)
@@ -1504,7 +1539,7 @@ class Columns(Widget):
if position < 0 or position >= len(self.contents):
raise IndexError
except (TypeError, IndexError):
- raise IndexError, "No child widget at position %s" % (position,)
+ raise IndexError, "No Columns child widget at position %s" % (position,)
self.contents.focus = position
focus_position = property(_get_focus_position, _set_focus_position,
doc="index of child widget in focus or None when Columns is empty")
@@ -1532,7 +1567,7 @@ class Columns(Widget):
shared = maxcol + self.dividechars
for i, (w, (t, width, b)) in enumerate(self.contents):
- if t == FIXED:
+ if t == GIVEN:
static_w = width
elif t == PACK:
# FIXME: should be able to pack with a different
@@ -1546,7 +1581,7 @@ class Columns(Widget):
widths.append(static_w)
shared -= static_w + self.dividechars
- if t not in (FIXED, PACK):
+ if t not in (GIVEN, PACK):
weighted.append((width, i))
if shared:
diff --git a/urwid/tests.py b/urwid/tests.py
index afc7c1c..6ff384f 100755
--- a/urwid/tests.py
+++ b/urwid/tests.py
@@ -2358,7 +2358,7 @@ class CommonContainerTest(unittest.TestCase):
None))
self.assertRaises(IndexError, lambda: setattr(p, 'focus_position', 0))
p.contents = [(t1, ('flow', None)), (t2, ('flow', None)),
- (sf, ('fixed', 3)), (t3, ('flow', None))]
+ (sf, ('given', 3)), (t3, ('flow', None))]
p.focus_position = 1
del p.contents[0]
self.assertEquals(p.focus_position, 0)
@@ -2367,7 +2367,7 @@ class CommonContainerTest(unittest.TestCase):
self.assertEquals(p.focus_position, 2)
self.assertRaises(urwid.PileError, lambda: p.contents.append(t1))
self.assertRaises(urwid.PileError, lambda: p.contents.append((t1, None)))
- self.assertRaises(urwid.PileError, lambda: p.contents.append((t1, 'fixed')))
+ self.assertRaises(urwid.PileError, lambda: p.contents.append((t1, 'given')))
p = urwid.Pile([t1, t2])
self.assertEquals(p.focus, t1)
@@ -2421,18 +2421,18 @@ class CommonContainerTest(unittest.TestCase):
(t1, ('pack', None, False)),
(t2, ('weight', 1, False)),
(sf, ('weight', 2, True)),
- (t3, ('fixed', 10, False))]
+ (t3, ('given', 10, False))]
c.focus_position = 1
del c.contents[0]
self.assertEquals(c.focus_position, 0)
c.contents[0:0] = [
- (t3, ('fixed', 10, False)),
+ (t3, ('given', 10, False)),
(t2, ('weight', 1, False))]
c.contents.insert(3, (t1, ('pack', None, False)))
self.assertEquals(c.focus_position, 2)
self.assertRaises(urwid.ColumnsError, lambda: c.contents.append(t1))
self.assertRaises(urwid.ColumnsError, lambda: c.contents.append((t1, None)))
- self.assertRaises(urwid.ColumnsError, lambda: c.contents.append((t1, 'fixed')))
+ self.assertRaises(urwid.ColumnsError, lambda: c.contents.append((t1, 'given')))
c = urwid.Columns([t1, t2])
self.assertEquals(c.focus, t1)
@@ -2468,11 +2468,14 @@ class CommonContainerTest(unittest.TestCase):
('flow', None), # use the old name
('weight', 2),
('fixed', 5)]
- self.assertEquals(c.column_types, [('pack', None), ('weight', 2), ('fixed', 5)])
+ self.assertEquals(c.column_types, [
+ ('flow', None),
+ ('weight', 2),
+ ('fixed', 5)])
self.assertEquals(c.contents, [
(t2, ('pack', None, False)),
(t1, ('weight', 2, False)),
- (sf, ('fixed', 5, True))])
+ (sf, ('given', 5, True))])
self.assertEquals(c.focus_position, 1) # focus unchanged
c.widget_list = [t1]
self.assertEquals(len(c.contents), 1)
@@ -2480,7 +2483,7 @@ class CommonContainerTest(unittest.TestCase):
c.widget_list.extend([t2, t1])
self.assertEquals(len(c.contents), 3)
self.assertEquals(c.column_types, [
- ('pack', None), ('weight', 1), ('weight', 1)])
+ ('flow', None), ('weight', 1), ('weight', 1)])
c.column_types[:] = [('weight', 2)]
self.assertEquals(len(c.contents), 1)