summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdocgen_reference.py156
-rwxr-xr-xdocgen_tutorial.py334
-rw-r--r--reference.html124
-rw-r--r--setup.py11
-rw-r--r--tmpl_tutorial.html8
-rw-r--r--tutorial.html125
-rw-r--r--urwid/__init__.py7
-rw-r--r--urwid/escape.py7
-rwxr-xr-xurwid/graphics.py23
-rw-r--r--urwid/util.py8
-rwxr-xr-xurwid/widget.py12
11 files changed, 523 insertions, 292 deletions
diff --git a/docgen_reference.py b/docgen_reference.py
index cf628d8..aac5100 100755
--- a/docgen_reference.py
+++ b/docgen_reference.py
@@ -30,7 +30,7 @@ import types
html_template = """<html>
<head>
-<title>Urwid Reference</title>
+<title>Urwid ((version)) Reference</title>
<style type="text/css">
h1 { text-align: center; }
h2 { margin: 40px 0 0 0; padding: 10px; background: #6d96e8;}
@@ -40,7 +40,7 @@ html_template = """<html>
</style>
<body>
<a name="top"></a>
-<h1>Urwid Reference</h1>
+<h1>Urwid ((version)) Reference</h1>
<div style="text-align: center;">
<a href="http://excess.org/urwid/">Urwid Home Page</a> /
@@ -50,10 +50,23 @@ html_template = """<html>
Reference
</div>
<br>
-%s
+%toc%
+<br>
+[<b>F</b>] = Flow Widget displayed with assigned screen columns and variable screen rows<br>
+[<b>B</b>] = Box Widget displayed with assigned screen columns and assigned screen rows<br>
+[<b>F</b>/<b>B</b>] = May behave as either Flow Widget or Box Widget<br>
+<br>
+%contents%
</body>
</html>"""
+flagd = {
+ None: "",
+ "B": "[<b>B</b>]",
+ "F": "[<b>F</b>]",
+ "FB": "[<b>F</b>/<b>B</b>]",
+}
+
class UrwidHTMLDoc( pydoc.HTMLDoc ):
def heading(self, title, fgcol, bgcol, extras=''):
@@ -246,70 +259,78 @@ def main():
doc = []
contents.append('<table width="100%"><tr><td width="33%" valign="top">')
- for obj, name in [
- (None,"User interface wrappers"),
- (urwid.raw_display.Screen, "raw_display.Screen"),
- (urwid.curses_display.Screen, "curses_display.Screen"),
- (None,"Top-level widgets"),
- (urwid.BoxWidget, "BoxWidget"),
- (urwid.Frame, "Frame"),
- (urwid.Filler, "Filler"),
- (urwid.ListBox, "ListBox"),
- (urwid.SimpleListWalker, "SimpleListWalker"),
- (None,"Decorations"),
- (urwid.WidgetWrap, "WidgetWrap"),
- (urwid.AttrWrap, "AttrWrap"),
- (urwid.Padding, "Padding"),
- (urwid.Divider, "Divider"),
- (urwid.LineBox, "LineBox"),
- (urwid.SolidFill, "SolidFill"),
- (None,"Composite widgets"),
- (urwid.Columns, "Columns"),
- (urwid.Pile, "Pile"),
- (urwid.GridFlow, "GridFlow"),
- (urwid.BoxAdapter,"BoxAdapter"),
- (urwid.Overlay,"Overlay"),
+ for obj, name, flag in [
+ (None,"User interface wrappers",None),
+ (urwid.raw_display.Screen, "raw_display.Screen",None),
+ (urwid.curses_display.Screen, "curses_display.Screen",None),
+ (urwid.web_display.Screen,"web_display.Screen",None),
+ (None,"Top-level widgets",None),
+ (urwid.Frame, "Frame", "B"),
+ (urwid.Filler, "Filler", "B"),
+ (urwid.ListBox, "ListBox", "B"),
+ (None,"Decorations", None),
+ (urwid.WidgetWrap, "WidgetWrap", "FB"),
+ (urwid.AttrWrap, "AttrWrap", "FB"),
+ (urwid.Padding, "Padding", "FB"),
+ (urwid.Divider, "Divider", "F"),
+ (urwid.LineBox, "LineBox", "FB"),
+ (urwid.SolidFill, "SolidFill", "B"),
+ (None,"Composite widgets", None),
+ (urwid.Columns, "Columns", "FB"),
+ (urwid.Pile, "Pile", "FB"),
+ (urwid.GridFlow, "GridFlow", "F"),
+ (urwid.BoxAdapter,"BoxAdapter", "F"),
+ (urwid.Overlay,"Overlay", "B"),
- (None, None),
+ (None, None, None),
- (None,"Content widgets"),
- (urwid.FlowWidget, "FlowWidget"),
- (urwid.Text, "Text"),
- (urwid.Edit, "Edit"),
- (urwid.IntEdit, "IntEdit"),
- (urwid.Button, "Button"),
- (urwid.CheckBox, "CheckBox"),
- (urwid.RadioButton, "RadioButton"),
- (None, "Graphics"),
- (urwid.BarGraph, "BarGraph"),
- (urwid.GraphVScale, "GraphVScale"),
- (urwid.ProgressBar, "ProgressBar"),
- (None,"Urwid class interfaces"),
- (WidgetInterface, "Widget interface definition"),
- (ListWalkerInterface, "List Walker interface definition"),
- (None,"Canvas painting"),
- (urwid.Canvas, "Canvas"),
- (urwid.CanvasCombine, "CanvasCombine"),
- (urwid.CanvasJoin, "CanvasJoin"),
+ (None,"Content widgets", None),
+ (urwid.Text, "Text", "F"),
+ (urwid.Edit, "Edit", "F"),
+ (urwid.IntEdit, "IntEdit", "F"),
+ (urwid.Button, "Button", "F"),
+ (urwid.CheckBox, "CheckBox", "F"),
+ (urwid.RadioButton, "RadioButton", "F"),
+ (None, "Graphics",None),
+ (urwid.BarGraph, "BarGraph","B"),
+ (urwid.GraphVScale, "GraphVScale","B"),
+ (urwid.ProgressBar, "ProgressBar","F"),
+
+ (None,"Abstract widgets & interfaces",None),
+ (WidgetInterface, "Widget interface definition",None),
+ (urwid.BoxWidget, "BoxWidget",None),
+ (urwid.FlowWidget, "FlowWidget",None),
+ (ListWalkerInterface, "List Walker interface definition",None),
+ (None,"ListBox list walkers",None),
+ (urwid.SimpleListWalker, "SimpleListWalker",None),
- (None, None),
+ (None, None, None),
- (None,"Custom formatting rules"),
- (urwid.TextLayout,"TextLayout"),
- (urwid.StandardTextLayout,"StandardTextLayout"),
- (None,"Character encoding"),
- (urwid.set_encoding,"set_encoding"),
- (urwid.get_encoding_mode,"get_encoding_mode"),
- (urwid.supports_unicode,"supports_unicode"),
- (None,"Screen capture"),
- (urwid.html_fragment.screenshot_init, "html_fragment.screenshot_init"),
- (urwid.html_fragment.screenshot_collect, "html_fragment.screenshot_collect"),
- (urwid.html_fragment.HtmlGenerator, "html_fragment.HtmlGenerator"),
- (None,"Web Application Interface"),
- (urwid.web_display.is_web_request,"web_display.is_web_request"),
- (urwid.web_display.set_preferences, "web_display.set_preferences"),
- (urwid.web_display.handle_short_request, "web_display.handle_short_request"),
- (urwid.web_display.Screen,"web_display.Screen"),
+ (None,"Canvas painting", None),
+ (urwid.Canvas, "Canvas", None),
+ (urwid.CanvasCombine, "CanvasCombine", None),
+ (urwid.CanvasJoin, "CanvasJoin", None),
+ (None,"Custom formatting rules", None),
+ (urwid.TextLayout,"TextLayout", None),
+ (urwid.StandardTextLayout,"StandardTextLayout", None),
+ (None,"Character encoding", None),
+ (urwid.set_encoding,"set_encoding", None),
+ (urwid.get_encoding_mode,"get_encoding_mode", None),
+ (urwid.supports_unicode,"supports_unicode", None),
+ (None,"Screen capture", None),
+ (urwid.html_fragment.screenshot_init,
+ "html_fragment.screenshot_init", None),
+ (urwid.html_fragment.screenshot_collect,
+ "html_fragment.screenshot_collect", None),
+ (urwid.html_fragment.HtmlGenerator,
+ "html_fragment.HtmlGenerator", None),
+ (None,"Web Application Interface", None),
+ (urwid.web_display.is_web_request,
+ "web_display.is_web_request", None),
+ (urwid.web_display.set_preferences,
+ "web_display.set_preferences", None),
+ (urwid.web_display.handle_short_request,
+ "web_display.handle_short_request", None),
]:
if name is None:
contents.append('</td><td width="33%" valign="top">')
@@ -320,14 +341,19 @@ def main():
lname = name
if type(obj) != types.ClassType: #dirty hack
doc.append('<a name="%s"></a><h3>function %s <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>' % (name,name) )
+ thtm = flagd[flag]
lname = lname.replace(" ","_")
contents.append('<div class="l2">' +
- '<a href="#%s">%s</a></div>' % (lname,name) )
+ '<a href="#%s">%s</a> %s</div>' %
+ (lname,name,thtm) )
doc.append( html.document( obj, name ) )
contents.append("</td></tr></table>")
- print html_template % ( "".join(contents) + "".join(doc) )
+ h = html_template
+ h = h.replace("%toc%", "".join(contents))
+ h = h.replace("%contents%", "".join(doc))
+ print h
if __name__ == "__main__":
main()
diff --git a/docgen_tutorial.py b/docgen_tutorial.py
index ca6fd2d..5d33e2f 100755
--- a/docgen_tutorial.py
+++ b/docgen_tutorial.py
@@ -19,13 +19,25 @@
#
# Urwid web site: http://excess.org/urwid/
+from __future__ import nested_scopes
+
import sys
+import re
import urwid.html_fragment
import urwid
+try:
+ import templayer
+except:
+ templayer = None
+
+try: True # old python?
+except: False, True = 0, 1
examples = {}
-results = {}
+
+interp_line = "#!/usr/bin/python\n\n"
+cut_comment = "# CUT HERE"
examples["min"] = ["example_min"]
def example_min():
@@ -169,7 +181,7 @@ def example_frlb():
def __init__(self):
self.items = [ self.new_question() ]
self.listbox = urwid.ListBox( self.items )
- instruct = urwid.Text("Press F1 to exit.")
+ instruct = urwid.Text("Press F8 to exit.")
header = urwid.AttrWrap( instruct, 'header' )
self.top = urwid.Frame(self.listbox, header)
@@ -177,7 +189,7 @@ def example_frlb():
self.ui = urwid.curses_display.Screen()
self.ui.register_palette([
('header', 'black', 'dark cyan', 'standout'),
- ('I say', 'dark blue', 'default', 'bold'),
+ ('I say', 'default', 'default', 'bold'),
])
self.ui.run_wrapper( self.run )
# CUT HERE
@@ -187,7 +199,7 @@ def example_frlb():
while True:
self.draw_screen( size )
keys = self.ui.get_input()
- if "f1" in keys:
+ if "f8" in keys:
break
for k in keys:
if k == "window resize":
@@ -219,7 +231,7 @@ def example_lbcont():
def __init__(self):
self.items = [ self.new_question() ]
self.listbox = urwid.ListBox( self.items )
- instruct = urwid.Text("Press F1 to exit.")
+ instruct = urwid.Text("Press F8 to exit.")
header = urwid.AttrWrap( instruct, 'header' )
self.top = urwid.Frame(self.listbox, header)
@@ -227,7 +239,7 @@ def example_lbcont():
self.ui = urwid.curses_display.Screen()
self.ui.register_palette([
('header', 'black', 'dark cyan', 'standout'),
- ('I say', 'dark blue', 'default', 'bold'),
+ ('I say', 'default', 'default', 'bold'),
])
self.ui.run_wrapper( self.run )
# CUT HERE
@@ -237,7 +249,7 @@ def example_lbcont():
while True:
self.draw_screen( size )
keys = self.ui.get_input()
- if "f1" in keys:
+ if "f8" in keys:
break
for k in keys:
if k == "window resize":
@@ -313,7 +325,7 @@ def example_lbscr():
while True:
self.draw_screen( size )
keys = self.ui.get_input()
- if "f1" in keys:
+ if "f8" in keys:
break
self.head.set_text("Pressed:")
for k in keys:
@@ -455,21 +467,47 @@ def example_wcur():
self.cursor_x = col
return True
+def read_sections(tmpl):
+ """Read section tags, section descriptions, and column breaks from
+ the Templayer template argument. Convert the section data into a
+ Python data structure called sections. Each sublist of sections
+ contains one column. Each column contains a list of (tag, desc.)
+ pairs. Return sections."""
+
+ sd = tmpl.layer("section_data")
+ col_break = "---"
+ sections = [[]]
+ for ln in sd.split("\n"):
+ if not ln: continue
+ if ln == col_break:
+ sections.append([])
+ continue
+ tag, desc = ln.split("\t",1)
+ sections[-1].append( (tag, desc) )
+ return sections
def read_example_code():
- # reverse the "examples" dictionary
- fn_names = {}
+ """By the time this function runs, the examples dictionary contains
+ a list of function names, all starting with "example_". Create a
+ second dictionary called code_blocks. Open the file containing this
+ function. For each function name in examples, read the text of that
+ function into an entry in the code_blocks dictionary. Return the
+ code_blocks dictionary."""
+
+ # invert the "examples" dictionary
+ example_fns = {}
for tag, l in examples.items():
for i, fn in zip(range(len(l)), l):
- fn_names[fn] = tag, i
+ example_fns[fn] = tag, i
# read our own source code
+ # strip trailing spaces and tabs from each line
code_blocks = {}
current_block = None
for ln in open( sys.argv[0], 'r').readlines():
ln = ln.rstrip()
if ( ln[:4] == "def " and ln[-3:] == "():" and
- fn_names.has_key( ln[4:-3] ) ):
+ example_fns.has_key( ln[4:-3] ) ):
current_block = ln[4:-3]
code_blocks[current_block] = []
continue
@@ -486,40 +524,116 @@ def read_example_code():
for name, block in code_blocks.items():
code_blocks[name] = "".join( block )
- # special handling for specific blocks
- head1, ignore, tail1 = (
- code_blocks["example_frlb"].split("# CUT HERE\n") )
- code_blocks["example_frlb"] = (
- code_blocks["example_frlb"].replace("# CUT HERE","") )
-
- head2, code_blocks["example_lbcont"], tail2 = (
- code_blocks["example_lbcont"].split("# CUT HERE\n") )
- assert head1 == head2, "frlb and lbcont have differing heads!"+`head1,head2`
- assert tail1 == tail2, "frlb and lbcont have differing tails!"
+ return code_blocks
- ignore, code_blocks["example_lbscr"], ignore = (
- code_blocks["example_lbscr"].split("# CUT HERE\n") )
+def filename(snum, inum, enum):
+ """Generate a filename to write an example to. Take the section
+ number from the table of contents, item number (subsection number),
+ and example number. Numbers start at 1. Return the filename."""
+
+ assert snum > 0, \
+ '%d.%d #%d: Section number should be greater than 0' % \
+ (snum, inum, enum)
+ assert inum > 0, \
+ '%d.%d #%d: Item number should be greater than 0' % \
+ (snum, inum, enum)
+ assert enum > 0, \
+ '%d.%d #%d: Example number should be greater than 0' % \
+ (snum, inum, enum)
+ assert enum < 28, \
+ '%d.%d #%d: Example number should be less than 28' % \
+ (snum, inum, enum)
+
+ if enum == 1: estr = ''
+ else: estr = chr(ord('a') - 2 + enum)
+
+ return "example" + str(snum) + "." + str(inum) + estr + ".py"
+
+def write_example_files(sections, blocks):
+ """The sections dictionary gives section tags in the order used by
+ the HTML output, and going through the tags in order allows us to
+ generate the same section numbers that the HTML uses. The global
+ examples dictionary maps each section tag to a list of examples used
+ in that section. And the blocks dictionary maps each example tag
+ to the text of that example.
+
+ Generate section numbers and find the examples used in each section.
+ Assume each example is ready to run -- replace the "cut here" comments
+ with blank lines, but don't remove any code. Create a file named
+ according to the section number (and an optional letter to allow for
+ multiple examples per section). Write the cleaned-up example to the
+ file."""
+
+ cut_re = '^\s*' + re.escape(cut_comment) + '\s*$'
+ cut_re_comp = re.compile(cut_re, re.MULTILINE)
+ valid_re = 'import urwid' # some examples are not runnable
+ valid_re_comp = re.compile(valid_re)
+ snum = inum = enum = 0
+
+ for col in sections:
+ for tag, ignore in col:
+ if not tag:
+ # new section -- do its first item next time
+ snum += 1
+ inum = 0
+ continue
- code_blocks["example_wcur"], code_blocks["example_wcur2"] = (
- code_blocks["example_wcur"].split("# CUT HERE\n") )
+ # new item inside a section
+ inum += 1
+ enum = 0
+ for ename in examples.get(tag, []):
+ etext = blocks[ename]
+ if not valid_re_comp.search(etext):
+ continue
+ enum += 1
+ fname = filename(snum, inum, enum)
+ f = open(fname, 'w')
+ etext = cut_re_comp.sub("", etext)
+ etext = interp_line + etext.rstrip() + "\n"
+ f.write(etext)
+ f.close()
+
+def cut_example_code(blocks):
+ """For brevity, the HTML gives excerpts from some of the examples.
+ Convert the examples from the full forms stored in this file to the
+ excerpted forms. Use "cut here" comments in the examples, and the
+ rules below, to do the conversion. Also check that the full forms
+ of certain examples contain identical code. Also strip trailing
+ spaces and tabs from the code. Return a dictionary with the
+ converted examples."""
+
+ ## do the conversions and the checks
+ head1, ignore, tail1 = (
+ blocks["example_frlb"].split(cut_comment+"\n") )
+ blocks["example_frlb"] = (
+ blocks["example_frlb"].replace(cut_comment,"") )
+
+ head2, blocks["example_lbcont"], tail2 = (
+ blocks["example_lbcont"].split(cut_comment+"\n") )
+ assert head1 == head2, "frlb and lbcont have differing heads: "+\
+ `head1, head2`
+ assert tail1 == tail2, "frlb and lbcont have differing tails: "+\
+ `tail1, tail2`
+
+ ignore, blocks["example_lbscr"], ignore = (
+ blocks["example_lbscr"].split(cut_comment+"\n") )
+
+ blocks["example_wcur"], blocks["example_wcur2"] = (
+ blocks["example_wcur"].split(cut_comment+"\n") )
examples["wcur"].append("example_wcur2")
+ # strip trailing spaces, tabs, blank lines from each block
+ # removes spaces/tabs left by splitting at cut_comment
+ for name, block in blocks.items():
+ blocks[name] = block.rstrip()
- # trim blank lines from end of each block
- for name, block in code_blocks.items():
- while block:
- i = block.rfind('\n',0,-1)
- if i == -1: break
- if block[i+1:-1].lstrip() == "":
- block = block[:i+1]
- else:
- break
- code_blocks[name] = block
-
- return code_blocks
-
+ return blocks
def generate_example_results():
+ """Create HTML "screen shots" from the example programs defined in
+ this file. Store the results in a dictionary (mapping example tag
+ to results) and return the dictionary."""
+
results = {}
init = urwid.html_fragment.screenshot_init
@@ -545,75 +659,91 @@ def generate_example_results():
example_edit()
results["edit"] = collect()[:3]
- init([(21,7)],[list("Tim t"),list("he Ench"),list("anter"),["f1"]])
+ init([(21,7)],[list("Tim t"),list("he Ench"),list("anter"),["f8"]])
example_frlb()
results["frlb"] = collect()[:4]
init([(23,13)],[list("Abe")+["enter"]+list("Bob"),["enter"]+
- list("Carl")+["enter"], list("Dave")+["enter"], ["f1"]])
+ list("Carl")+["enter"], list("Dave")+["enter"], ["f8"]])
example_lbcont()
results["lbcont"] = collect()[1:4]
init([(15,7), (20,9), (25,7), (11,13)],
[["down"],["down"],["down"],["up"],["up"]] +
- [["window resize"]]*3 + [["f1"]])
+ [["window resize"]]*3 + [["f8"]])
example_lbscr()
results["lbscr"] = collect()[:9]
return results
-def main():
- try:
- import templayer
- except ImportError, e:
- sys.stderr.write(
-"""Error importing templayer. Please download and install the Templayer
-python module available at:
-http://excess.org/templayer/
-""")
- sys.exit(1)
+def generate_body(tmpl, sections, blocks, results):
+ """Assemble most of the HTML output (the body) from the pieces
+ of text contained in all the arguments. The body contains a table
+ of contents followed by section headers and section text. Pieces of
+ section text may contain example code, and pieces of code may be
+ followed by a "screen shot" of themselves.
- tmpl = templayer.HtmlTemplate("tmpl_tutorial.html")
- out_file = tmpl.start_file()
-
- sd = tmpl.layer("section_data")
- toc = [[]]
- for ln in sd.split("\n"):
- if not ln: continue
- if ln == "---":
- toc.append([])
- continue
- tag, name = ln.split("\t",1)
- toc[-1].append( (tag, name) )
-
- code_blocks = read_example_code()
- results = generate_example_results()
+ The sections dictionary gives the column formatting for the
+ table of contents in the HTML and the description shared by the TOC
+ entry and the section header. With the addition of section numbers
+ (generated now) sections contains the information needed to write
+ the finished table of contents. We expect the template to use
+ two slots, toc_left and toc_right, which we fill with the TOC.
+ We also expect the template to define two pieces of HTML,
+ toc_section and toc_item, which give the formatting for all items
+ in the TOC.
+
+ While handling each entry in the TOC, we use the tag stored in
+ sections to assemble the corresponding part of the body. We expect
+ the template to define two pieces of HTML, section_head and
+ section_body, which give the formatting for all parts of the body
+ (colored boxes for section headers, and the formatting that applies
+ to all pieces of section text). The template also defines one slot
+ for each individual piece of section text, distinguished from the
+ others by the section tag.
+ Each individual body slot may use more slots to hold the examples
+ and results included in a piece of section text. These slots are
+ numbered. We use the section tags to look in the examples and
+ results dictionaries; the dictionary order must match the numerical
+ order used in the template. We do not use example tags as defined
+ in the global examples dictionary. The blocks and results arguments
+ describe which slots are defined; we hope the HTML text will use
+ all the slots we have defined."""
+
+ # put TOC columns into the variables used by the template
+ # assign section numbers
+ # generate HTML form of TOC entries, corresponding document parts
+ assert len(sections) == 2, 'sections has %d columns but should have 2!' % len(sections)
+
toc_slots = {'toc_left':[], 'toc_right':[]}
body = []
snum = inum = 0
- for toc_part, l in zip(['toc_left','toc_right'], toc):
+ for slot, l in zip(['toc_left','toc_right'], sections):
for tag, name in l:
if not tag:
+ # new section -- do its first item next time
snum += 1
inum = 0
t = tmpl.format('toc_section', snum=`snum`,
name=name )
- toc_slots[toc_part].append( t )
+ toc_slots[slot].append( t )
b = tmpl.format('section_head', snum=`snum`,
name=name )
body.append( b )
continue
+
+ # new item inside a section
inum += 1
t = tmpl.format('toc_item', snum=`snum`,
inum=`inum`, name=name, tag=tag)
- toc_slots[toc_part].append( t )
+ toc_slots[slot].append( t )
slots = {}
i = 0
for fn in examples.get(tag, []):
- slots['example[%d]'%i] = code_blocks[fn]
+ slots['example[%d]'%i] = blocks[fn]
i += 1
i = 0
for res in results.get(tag, []):
@@ -625,9 +755,65 @@ http://excess.org/templayer/
content = b)
body.append( b )
- bottom = out_file.open( ** toc_slots )
- bottom.write( body )
- out_file.close()
+ return (body, toc_slots)
+
+def parse_options():
+ usage = "%s [-h|-?|--help]\n%s [-H|--HTML|--html] [-s|--scripts]" % \
+ (sys.argv[0], sys.argv[0])
+ help = """%s options:
+
+-h, -?, --help Print this message to standard error and exit.
+
+-H, --HTML, --html Write the HTML documentation to standard output.
+-s, --scripts Write runnable scripts to files.""" % sys.argv[0]
+ do_html = False
+ do_scripts = False
+
+ if len(sys.argv) < 2 or len(sys.argv) > 3:
+ sys.exit(usage)
+
+ if len(sys.argv) == 2 and (sys.argv[1] in ('-h', '-?', '--help')):
+ sys.exit(help)
+
+ for arg in sys.argv[1:]:
+ if arg in ('-H', '--HTML', '--html'):
+ if do_html: sys.exit(usage)
+ else: do_html = True
+ elif arg in ('-s', '--scripts'):
+ if do_scripts: sys.exit(usage)
+ else: do_scripts = True
+ else:
+ sys.exit(usage)
+
+ return (do_html, do_scripts)
+
+def main():
+ (do_html, do_scripts) = parse_options()
+
+ if templayer is None:
+ sys.stderr.write(
+"""Error importing templayer. Please download and install the Templayer
+python module available at:
+http://excess.org/templayer/
+""")
+ sys.exit( 1 )
+
+ tmpl = templayer.HtmlTemplate( "tmpl_tutorial.html" )
+ sections = read_sections( tmpl )
+ code_blocks = read_example_code()
+
+ if do_scripts:
+ write_example_files( sections, code_blocks )
+
+ if do_html:
+ code_blocks = cut_example_code( code_blocks )
+ results = generate_example_results()
+ out_file = tmpl.start_file()
+ (body, toc_slots) = generate_body( tmpl, sections,
+ code_blocks, results )
+ bottom = out_file.open( ** toc_slots )
+ bottom.write( body )
+ out_file.close()
if __name__=="__main__":
main()
diff --git a/reference.html b/reference.html
index 50e2eb1..2121bb8 100644
--- a/reference.html
+++ b/reference.html
@@ -1,6 +1,6 @@
<html>
<head>
-<title>Urwid Reference</title>
+<title>Urwid 0.9.6 Reference</title>
<style type="text/css">
h1 { text-align: center; }
h2 { margin: 40px 0 0 0; padding: 10px; background: #6d96e8;}
@@ -10,7 +10,7 @@
</style>
<body>
<a name="top"></a>
-<h1>Urwid Reference</h1>
+<h1>Urwid 0.9.6 Reference</h1>
<div style="text-align: center;">
<a href="http://excess.org/urwid/">Urwid Home Page</a> /
@@ -20,7 +20,13 @@
Reference
</div>
<br>
-<table width="100%"><tr><td width="33%" valign="top"><div class="l1">User interface wrappers</div><div class="l2"><a href="#raw_display.Screen">raw_display.Screen</a></div><div class="l2"><a href="#curses_display.Screen">curses_display.Screen</a></div><div class="l1">Top-level widgets</div><div class="l2"><a href="#BoxWidget">BoxWidget</a></div><div class="l2"><a href="#Frame">Frame</a></div><div class="l2"><a href="#Filler">Filler</a></div><div class="l2"><a href="#ListBox">ListBox</a></div><div class="l2"><a href="#SimpleListWalker">SimpleListWalker</a></div><div class="l1">Decorations</div><div class="l2"><a href="#WidgetWrap">WidgetWrap</a></div><div class="l2"><a href="#AttrWrap">AttrWrap</a></div><div class="l2"><a href="#Padding">Padding</a></div><div class="l2"><a href="#Divider">Divider</a></div><div class="l2"><a href="#LineBox">LineBox</a></div><div class="l2"><a href="#SolidFill">SolidFill</a></div><div class="l1">Composite widgets</div><div class="l2"><a href="#Columns">Columns</a></div><div class="l2"><a href="#Pile">Pile</a></div><div class="l2"><a href="#GridFlow">GridFlow</a></div><div class="l2"><a href="#BoxAdapter">BoxAdapter</a></div><div class="l2"><a href="#Overlay">Overlay</a></div></td><td width="33%" valign="top"><div class="l1">Content widgets</div><div class="l2"><a href="#FlowWidget">FlowWidget</a></div><div class="l2"><a href="#Text">Text</a></div><div class="l2"><a href="#Edit">Edit</a></div><div class="l2"><a href="#IntEdit">IntEdit</a></div><div class="l2"><a href="#Button">Button</a></div><div class="l2"><a href="#CheckBox">CheckBox</a></div><div class="l2"><a href="#RadioButton">RadioButton</a></div><div class="l1">Graphics</div><div class="l2"><a href="#BarGraph">BarGraph</a></div><div class="l2"><a href="#GraphVScale">GraphVScale</a></div><div class="l2"><a href="#ProgressBar">ProgressBar</a></div><div class="l1">Urwid class interfaces</div><div class="l2"><a href="#Widget_interface_definition">Widget interface definition</a></div><div class="l2"><a href="#List_Walker_interface_definition">List Walker interface definition</a></div><div class="l1">Canvas painting</div><div class="l2"><a href="#Canvas">Canvas</a></div><div class="l2"><a href="#CanvasCombine">CanvasCombine</a></div><div class="l2"><a href="#CanvasJoin">CanvasJoin</a></div></td><td width="33%" valign="top"><div class="l1">Custom formatting rules</div><div class="l2"><a href="#TextLayout">TextLayout</a></div><div class="l2"><a href="#StandardTextLayout">StandardTextLayout</a></div><div class="l1">Character encoding</div><div class="l2"><a href="#set_encoding">set_encoding</a></div><div class="l2"><a href="#get_encoding_mode">get_encoding_mode</a></div><div class="l2"><a href="#supports_unicode">supports_unicode</a></div><div class="l1">Screen capture</div><div class="l2"><a href="#html_fragment.screenshot_init">html_fragment.screenshot_init</a></div><div class="l2"><a href="#html_fragment.screenshot_collect">html_fragment.screenshot_collect</a></div><div class="l2"><a href="#html_fragment.HtmlGenerator">html_fragment.HtmlGenerator</a></div><div class="l1">Web Application Interface</div><div class="l2"><a href="#web_display.is_web_request">web_display.is_web_request</a></div><div class="l2"><a href="#web_display.set_preferences">web_display.set_preferences</a></div><div class="l2"><a href="#web_display.handle_short_request">web_display.handle_short_request</a></div><div class="l2"><a href="#web_display.Screen">web_display.Screen</a></div></td></tr></table><h2>User interface wrappers</h2><h3><a name="raw_display.Screen"></a><strong>raw_display.Screen</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<table width="100%"><tr><td width="33%" valign="top"><div class="l1">User interface wrappers</div><div class="l2"><a href="#raw_display.Screen">raw_display.Screen</a> </div><div class="l2"><a href="#curses_display.Screen">curses_display.Screen</a> </div><div class="l2"><a href="#web_display.Screen">web_display.Screen</a> </div><div class="l1">Top-level widgets</div><div class="l2"><a href="#Frame">Frame</a> [<b>B</b>]</div><div class="l2"><a href="#Filler">Filler</a> [<b>B</b>]</div><div class="l2"><a href="#ListBox">ListBox</a> [<b>B</b>]</div><div class="l1">Decorations</div><div class="l2"><a href="#WidgetWrap">WidgetWrap</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#AttrWrap">AttrWrap</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#Padding">Padding</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#Divider">Divider</a> [<b>F</b>]</div><div class="l2"><a href="#LineBox">LineBox</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#SolidFill">SolidFill</a> [<b>B</b>]</div><div class="l1">Composite widgets</div><div class="l2"><a href="#Columns">Columns</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#Pile">Pile</a> [<b>F</b>/<b>B</b>]</div><div class="l2"><a href="#GridFlow">GridFlow</a> [<b>F</b>]</div><div class="l2"><a href="#BoxAdapter">BoxAdapter</a> [<b>F</b>]</div><div class="l2"><a href="#Overlay">Overlay</a> [<b>B</b>]</div></td><td width="33%" valign="top"><div class="l1">Content widgets</div><div class="l2"><a href="#Text">Text</a> [<b>F</b>]</div><div class="l2"><a href="#Edit">Edit</a> [<b>F</b>]</div><div class="l2"><a href="#IntEdit">IntEdit</a> [<b>F</b>]</div><div class="l2"><a href="#Button">Button</a> [<b>F</b>]</div><div class="l2"><a href="#CheckBox">CheckBox</a> [<b>F</b>]</div><div class="l2"><a href="#RadioButton">RadioButton</a> [<b>F</b>]</div><div class="l1">Graphics</div><div class="l2"><a href="#BarGraph">BarGraph</a> [<b>B</b>]</div><div class="l2"><a href="#GraphVScale">GraphVScale</a> [<b>B</b>]</div><div class="l2"><a href="#ProgressBar">ProgressBar</a> [<b>F</b>]</div><div class="l1">Abstract widgets & interfaces</div><div class="l2"><a href="#Widget_interface_definition">Widget interface definition</a> </div><div class="l2"><a href="#BoxWidget">BoxWidget</a> </div><div class="l2"><a href="#FlowWidget">FlowWidget</a> </div><div class="l2"><a href="#List_Walker_interface_definition">List Walker interface definition</a> </div><div class="l1">ListBox list walkers</div><div class="l2"><a href="#SimpleListWalker">SimpleListWalker</a> </div></td><td width="33%" valign="top"><div class="l1">Canvas painting</div><div class="l2"><a href="#Canvas">Canvas</a> </div><div class="l2"><a href="#CanvasCombine">CanvasCombine</a> </div><div class="l2"><a href="#CanvasJoin">CanvasJoin</a> </div><div class="l1">Custom formatting rules</div><div class="l2"><a href="#TextLayout">TextLayout</a> </div><div class="l2"><a href="#StandardTextLayout">StandardTextLayout</a> </div><div class="l1">Character encoding</div><div class="l2"><a href="#set_encoding">set_encoding</a> </div><div class="l2"><a href="#get_encoding_mode">get_encoding_mode</a> </div><div class="l2"><a href="#supports_unicode">supports_unicode</a> </div><div class="l1">Screen capture</div><div class="l2"><a href="#html_fragment.screenshot_init">html_fragment.screenshot_init</a> </div><div class="l2"><a href="#html_fragment.screenshot_collect">html_fragment.screenshot_collect</a> </div><div class="l2"><a href="#html_fragment.HtmlGenerator">html_fragment.HtmlGenerator</a> </div><div class="l1">Web Application Interface</div><div class="l2"><a href="#web_display.is_web_request">web_display.is_web_request</a> </div><div class="l2"><a href="#web_display.set_preferences">web_display.set_preferences</a> </div><div class="l2"><a href="#web_display.handle_short_request">web_display.handle_short_request</a> </div></td></tr></table>
+<br>
+[<b>F</b>] = Flow Widget displayed with assigned screen columns and variable screen rows<br>
+[<b>B</b>] = Box Widget displayed with assigned screen columns and assigned screen rows<br>
+[<b>F</b>/<b>B</b>] = May behave as either Flow Widget or Box Widget<br>
+<br>
+<h2>User interface wrappers</h2><h3><a name="raw_display.Screen"></a><strong>raw_display.Screen</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="Screen-__init__"><strong>__init__</strong></a>(self)</dt></dl>
<dl><dt><a name="Screen-draw_screen"><strong>draw_screen</strong></a>(self, (maxcol, maxrow), r)</dt><dd><tt>Paint&nbsp;screen&nbsp;with&nbsp;rendered&nbsp;canvas.</tt></dd></dl>
@@ -217,10 +223,42 @@ resize_wait&nbsp;--&nbsp;amount&nbsp;of&nbsp;time&nbsp;in&nbsp;seconds&nbsp;to&n
After&nbsp;calling&nbsp;this&nbsp;function&nbsp;get_input&nbsp;will&nbsp;include&nbsp;mouse<br>
click&nbsp;events&nbsp;along&nbsp;with&nbsp;keystrokes.</tt></dd></dl>
-<h2>Top-level widgets</h2><h3><a name="BoxWidget">class <strong>BoxWidget</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
-<dl><dt><a name="BoxWidget-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;True.&nbsp;&nbsp;Selectable&nbsp;by&nbsp;default.</tt></dd></dl>
+<h3><a name="web_display.Screen"></a><strong>web_display.Screen</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<dl><dt><a name="Screen-__init__"><strong>__init__</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="Screen-draw_screen"><strong>draw_screen</strong></a>(self, (cols, rows), r)</dt><dd><tt>Send&nbsp;a&nbsp;screen&nbsp;update&nbsp;to&nbsp;the&nbsp;client.</tt></dd></dl>
+
+<dl><dt><a name="Screen-get_cols_rows"><strong>get_cols_rows</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;screen&nbsp;size.</tt></dd></dl>
+
+<dl><dt><a name="Screen-get_input"><strong>get_input</strong></a>(self, raw_keys<font color="#909090">=False</font>)</dt><dd><tt>Return&nbsp;pending&nbsp;input&nbsp;as&nbsp;a&nbsp;list.</tt></dd></dl>
+
+<dl><dt><a name="Screen-register_palette"><strong>register_palette</strong></a>(self, l)</dt><dd><tt>Register&nbsp;a&nbsp;list&nbsp;of&nbsp;palette&nbsp;entries.<br>
+&nbsp;<br>
+l&nbsp;--&nbsp;list&nbsp;of&nbsp;(name,&nbsp;foreground,&nbsp;background)&nbsp;or<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name,&nbsp;same_as_other_name)&nbsp;palette&nbsp;entries.<br>
+&nbsp;<br>
+calls&nbsp;self.<strong>register_palette_entry</strong>&nbsp;for&nbsp;each&nbsp;item&nbsp;in&nbsp;l</tt></dd></dl>
+
+<dl><dt><a name="Screen-register_palette_entry"><strong>register_palette_entry</strong></a>(self, name, foreground, background, mono<font color="#909090">=None</font>)</dt><dd><tt>Register&nbsp;a&nbsp;single&nbsp;palette&nbsp;entry.<br>
+&nbsp;<br>
+name&nbsp;--&nbsp;new&nbsp;entry/attribute&nbsp;name<br>
+foreground&nbsp;--&nbsp;foreground&nbsp;colour<br>
+background&nbsp;--&nbsp;background&nbsp;colour<br>
+mono&nbsp;--&nbsp;monochrome&nbsp;terminal&nbsp;attribute<br>
+&nbsp;<br>
+See&nbsp;curses_display.register_palette_entry&nbsp;for&nbsp;more&nbsp;info.</tt></dd></dl>
-<h3><a name="Frame">class <strong>Frame</strong></a>(BoxWidget) <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<dl><dt><a name="Screen-run_wrapper"><strong>run_wrapper</strong></a>(self, fn)</dt><dd><tt>Start&nbsp;the&nbsp;application&nbsp;main&nbsp;loop.<br>
+&nbsp;<br>
+This&nbsp;function&nbsp;reads&nbsp;the&nbsp;initial&nbsp;screen&nbsp;size,&nbsp;generates&nbsp;a<br>
+unique&nbsp;id&nbsp;and&nbsp;handles&nbsp;cleanup&nbsp;when&nbsp;fn&nbsp;exits.<br>
+&nbsp;<br>
+web_display.set_preferences(..)&nbsp;must&nbsp;be&nbsp;called&nbsp;before&nbsp;calling<br>
+this&nbsp;function&nbsp;for&nbsp;the&nbsp;preferences&nbsp;to&nbsp;take&nbsp;effect</tt></dd></dl>
+
+<dl><dt><a name="Screen-set_mouse_tracking"><strong>set_mouse_tracking</strong></a>(self)</dt><dd><tt>Not&nbsp;yet&nbsp;implemented</tt></dd></dl>
+
+<h2>Top-level widgets</h2><h3><a name="Frame">class <strong>Frame</strong></a>(BoxWidget) <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="Frame-__init__"><strong>__init__</strong></a>(self, body, header<font color="#909090">=None</font>, footer<font color="#909090">=None</font>, focus_part<font color="#909090">='body'</font>)</dt><dd><tt>body&nbsp;--&nbsp;a&nbsp;box&nbsp;widget&nbsp;for&nbsp;the&nbsp;body&nbsp;of&nbsp;the&nbsp;frame<br>
header&nbsp;--&nbsp;a&nbsp;flow&nbsp;widget&nbsp;for&nbsp;above&nbsp;the&nbsp;body&nbsp;(or&nbsp;None)<br>
footer&nbsp;--&nbsp;a&nbsp;flow&nbsp;widget&nbsp;for&nbsp;below&nbsp;the&nbsp;body&nbsp;(or&nbsp;None)<br>
@@ -376,17 +414,6 @@ offset_inset&nbsp;--&nbsp;either&nbsp;the&nbsp;number&nbsp;of&nbsp;rows&nbsp;bet
Methods inherited from BoxWidget:<br>
<dl><dt><a name="ListBox-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;True.&nbsp;&nbsp;Selectable&nbsp;by&nbsp;default.</tt></dd></dl>
-<h3><a name="SimpleListWalker">class <strong>SimpleListWalker</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
-<dl><dt><a name="SimpleListWalker-__init__"><strong>__init__</strong></a>(self, contents)</dt><dd><tt>contents&nbsp;--&nbsp;list&nbsp;to&nbsp;walk</tt></dd></dl>
-
-<dl><dt><a name="SimpleListWalker-get_focus"><strong>get_focus</strong></a>(self)</dt><dd><tt>Return&nbsp;(focus&nbsp;widget,&nbsp;focus&nbsp;position).</tt></dd></dl>
-
-<dl><dt><a name="SimpleListWalker-get_next"><strong>get_next</strong></a>(self, start_from)</dt><dd><tt>Return&nbsp;(widget&nbsp;after&nbsp;start_from,&nbsp;position&nbsp;after&nbsp;start_from).</tt></dd></dl>
-
-<dl><dt><a name="SimpleListWalker-get_prev"><strong>get_prev</strong></a>(self, start_from)</dt><dd><tt>Return&nbsp;(widget&nbsp;before&nbsp;start_from,&nbsp;position&nbsp;before&nbsp;start_from).</tt></dd></dl>
-
-<dl><dt><a name="SimpleListWalker-set_focus"><strong>set_focus</strong></a>(self, position)</dt><dd><tt>Set&nbsp;focus&nbsp;position.</tt></dd></dl>
-
<h2>Decorations</h2><h3><a name="WidgetWrap">class <strong>WidgetWrap</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="WidgetWrap-__getattr__"><strong>__getattr__</strong></a>(self, name)</dt><dd><tt>Call&nbsp;self.<strong>w</strong>&nbsp;if&nbsp;name&nbsp;is&nbsp;in&nbsp;Widget&nbsp;interface&nbsp;definition.</tt></dd></dl>
@@ -530,7 +557,9 @@ Only&nbsp;makes&nbsp;sense&nbsp;if&nbsp;self.<strong>widget_list</strong>&nbsp;c
<dl><dt><a name="Columns-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;selectable&nbsp;value&nbsp;of&nbsp;the&nbsp;focus&nbsp;column.</tt></dd></dl>
-<dl><dt><a name="Columns-set_focus"><strong>set_focus</strong></a>(self, widget)</dt><dd><tt>Set&nbsp;the&nbsp;column&nbsp;in&nbsp;focus&nbsp;with&nbsp;a&nbsp;widget&nbsp;in&nbsp;self.<strong>widget_list</strong>.</tt></dd></dl>
+<dl><dt><a name="Columns-set_focus"><strong>set_focus</strong></a>(self, item)</dt><dd><tt>Set&nbsp;the&nbsp;item&nbsp;in&nbsp;focus.&nbsp;&nbsp;<br>
+&nbsp;<br>
+item&nbsp;--&nbsp;widget&nbsp;or&nbsp;integer&nbsp;index</tt></dd></dl>
<dl><dt><a name="Columns-set_focus_column"><strong>set_focus_column</strong></a>(self, num)</dt><dd><tt>Set&nbsp;the&nbsp;column&nbsp;in&nbsp;focus&nbsp;by&nbsp;its&nbsp;index&nbsp;in&nbsp;self.<strong>widget_list</strong>.</tt></dd></dl>
@@ -684,10 +713,7 @@ always&nbsp;rendered&nbsp;the&nbsp;full&nbsp;size&nbsp;available&nbsp;"below"&nb
<dl><dt><a name="Overlay-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;selectable&nbsp;from&nbsp;top_w.</tt></dd></dl>
-<h2>Content widgets</h2><h3><a name="FlowWidget">class <strong>FlowWidget</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
-<dl><dt><a name="FlowWidget-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;False.&nbsp;&nbsp;Not&nbsp;selectable&nbsp;by&nbsp;default.</tt></dd></dl>
-
-<h3><a name="Text">class <strong>Text</strong></a>(FlowWidget) <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<h2>Content widgets</h2><h3><a name="Text">class <strong>Text</strong></a>(FlowWidget) <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="Text-__init__"><strong>__init__</strong></a>(self, markup, align<font color="#909090">='left'</font>, wrap<font color="#909090">='space'</font>, layout<font color="#909090">=None</font>)</dt><dd><tt>markup&nbsp;--&nbsp;content&nbsp;of&nbsp;text&nbsp;widget,&nbsp;one&nbsp;of:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain&nbsp;string&nbsp;--&nbsp;string&nbsp;is&nbsp;displayed<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&nbsp;attr,&nbsp;markup2&nbsp;)&nbsp;--&nbsp;markup2&nbsp;is&nbsp;given&nbsp;attribute&nbsp;attr<br>
@@ -1155,7 +1181,7 @@ Data and other attributes defined here:<br>
Methods inherited from FlowWidget:<br>
<dl><dt><a name="ProgressBar-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;False.&nbsp;&nbsp;Not&nbsp;selectable&nbsp;by&nbsp;default.</tt></dd></dl>
-<h2>Urwid class interfaces</h2><h3><a name="Widget_interface_definition"></a><strong>Widget interface definition</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<h2>Abstract widgets & interfaces</h2><h3><a name="Widget_interface_definition"></a><strong>Widget interface definition</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="WidgetInterface-get_cursor_coords"><strong>get_cursor_coords</strong></a>(self, size)</dt><dd><tt>size&nbsp;--&nbsp;flow&nbsp;widgets:&nbsp;(maxcol,)&nbsp;&nbsp;box&nbsp;widgets:&nbsp;(maxcol,maxrow)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;maxcol&nbsp;and&nbsp;maxrow&nbsp;are&nbsp;the&nbsp;maximum&nbsp;screen&nbsp;columns<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;rows&nbsp;for&nbsp;the&nbsp;widget&nbsp;when&nbsp;rendered<br>
@@ -1243,6 +1269,12 @@ should&nbsp;take&nbsp;the&nbsp;focus&nbsp;when&nbsp;changing&nbsp;focus&nbsp;bet
&nbsp;<br>
MUST&nbsp;be&nbsp;implemented.</tt></dd></dl>
+<h3><a name="BoxWidget">class <strong>BoxWidget</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<dl><dt><a name="BoxWidget-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;True.&nbsp;&nbsp;Selectable&nbsp;by&nbsp;default.</tt></dd></dl>
+
+<h3><a name="FlowWidget">class <strong>FlowWidget</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<dl><dt><a name="FlowWidget-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return&nbsp;False.&nbsp;&nbsp;Not&nbsp;selectable&nbsp;by&nbsp;default.</tt></dd></dl>
+
<h3><a name="List_Walker_interface_definition"></a><strong>List Walker interface definition</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="ListWalkerInterface-get_focus"><strong>get_focus</strong></a>(self)</dt><dd><tt>Returns&nbsp;(widget,&nbsp;position).<br>
&nbsp;<br>
@@ -1273,6 +1305,17 @@ Returns&nbsp;None.<br>
&nbsp;<br>
MUST&nbsp;be&nbsp;implemented.</tt></dd></dl>
+<h2>ListBox list walkers</h2><h3><a name="SimpleListWalker">class <strong>SimpleListWalker</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
+<dl><dt><a name="SimpleListWalker-__init__"><strong>__init__</strong></a>(self, contents)</dt><dd><tt>contents&nbsp;--&nbsp;list&nbsp;to&nbsp;walk</tt></dd></dl>
+
+<dl><dt><a name="SimpleListWalker-get_focus"><strong>get_focus</strong></a>(self)</dt><dd><tt>Return&nbsp;(focus&nbsp;widget,&nbsp;focus&nbsp;position).</tt></dd></dl>
+
+<dl><dt><a name="SimpleListWalker-get_next"><strong>get_next</strong></a>(self, start_from)</dt><dd><tt>Return&nbsp;(widget&nbsp;after&nbsp;start_from,&nbsp;position&nbsp;after&nbsp;start_from).</tt></dd></dl>
+
+<dl><dt><a name="SimpleListWalker-get_prev"><strong>get_prev</strong></a>(self, start_from)</dt><dd><tt>Return&nbsp;(widget&nbsp;before&nbsp;start_from,&nbsp;position&nbsp;before&nbsp;start_from).</tt></dd></dl>
+
+<dl><dt><a name="SimpleListWalker-set_focus"><strong>set_focus</strong></a>(self, position)</dt><dd><tt>Set&nbsp;focus&nbsp;position.</tt></dd></dl>
+
<h2>Canvas painting</h2><h3><a name="Canvas">class <strong>Canvas</strong></a> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
<dl><dt><a name="Canvas-__init__"><strong>__init__</strong></a>(self, text<font color="#909090">=None</font>, attr<font color="#909090">=None</font>, cs<font color="#909090">=None</font>, cursor<font color="#909090">=None</font>, maxcol<font color="#909090">=None</font>)</dt><dd><tt>text&nbsp;--&nbsp;list&nbsp;of&nbsp;strings,&nbsp;one&nbsp;for&nbsp;each&nbsp;line<br>
attr&nbsp;--&nbsp;list&nbsp;of&nbsp;run&nbsp;length&nbsp;encoded&nbsp;attributes&nbsp;for&nbsp;text<br>
@@ -1445,41 +1488,6 @@ script&nbsp;should&nbsp;immediately&nbsp;exit.<br>
&nbsp;<br>
web_display.set_preferences(..)&nbsp;should&nbsp;be&nbsp;called&nbsp;before&nbsp;calling&nbsp;this<br>
function&nbsp;for&nbsp;the&nbsp;preferences&nbsp;to&nbsp;take&nbsp;effect</tt></dd></dl>
-<h3><a name="web_display.Screen"></a><strong>web_display.Screen</strong> <span style="font-size:small; padding-left: 20px">[<a href="#top">back to top</a>]</span></h3>Methods defined here:<br>
-<dl><dt><a name="Screen-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Screen-draw_screen"><strong>draw_screen</strong></a>(self, (cols, rows), r)</dt><dd><tt>Send&nbsp;a&nbsp;screen&nbsp;update&nbsp;to&nbsp;the&nbsp;client.</tt></dd></dl>
-
-<dl><dt><a name="Screen-get_cols_rows"><strong>get_cols_rows</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;screen&nbsp;size.</tt></dd></dl>
-
-<dl><dt><a name="Screen-get_input"><strong>get_input</strong></a>(self, raw_keys<font color="#909090">=False</font>)</dt><dd><tt>Return&nbsp;pending&nbsp;input&nbsp;as&nbsp;a&nbsp;list.</tt></dd></dl>
-
-<dl><dt><a name="Screen-register_palette"><strong>register_palette</strong></a>(self, l)</dt><dd><tt>Register&nbsp;a&nbsp;list&nbsp;of&nbsp;palette&nbsp;entries.<br>
-&nbsp;<br>
-l&nbsp;--&nbsp;list&nbsp;of&nbsp;(name,&nbsp;foreground,&nbsp;background)&nbsp;or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name,&nbsp;same_as_other_name)&nbsp;palette&nbsp;entries.<br>
-&nbsp;<br>
-calls&nbsp;self.<strong>register_palette_entry</strong>&nbsp;for&nbsp;each&nbsp;item&nbsp;in&nbsp;l</tt></dd></dl>
-
-<dl><dt><a name="Screen-register_palette_entry"><strong>register_palette_entry</strong></a>(self, name, foreground, background, mono<font color="#909090">=None</font>)</dt><dd><tt>Register&nbsp;a&nbsp;single&nbsp;palette&nbsp;entry.<br>
-&nbsp;<br>
-name&nbsp;--&nbsp;new&nbsp;entry/attribute&nbsp;name<br>
-foreground&nbsp;--&nbsp;foreground&nbsp;colour<br>
-background&nbsp;--&nbsp;background&nbsp;colour<br>
-mono&nbsp;--&nbsp;monochrome&nbsp;terminal&nbsp;attribute<br>
-&nbsp;<br>
-See&nbsp;curses_display.register_palette_entry&nbsp;for&nbsp;more&nbsp;info.</tt></dd></dl>
-
-<dl><dt><a name="Screen-run_wrapper"><strong>run_wrapper</strong></a>(self, fn)</dt><dd><tt>Start&nbsp;the&nbsp;application&nbsp;main&nbsp;loop.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;reads&nbsp;the&nbsp;initial&nbsp;screen&nbsp;size,&nbsp;generates&nbsp;a<br>
-unique&nbsp;id&nbsp;and&nbsp;handles&nbsp;cleanup&nbsp;when&nbsp;fn&nbsp;exits.<br>
-&nbsp;<br>
-web_display.set_preferences(..)&nbsp;must&nbsp;be&nbsp;called&nbsp;before&nbsp;calling<br>
-this&nbsp;function&nbsp;for&nbsp;the&nbsp;preferences&nbsp;to&nbsp;take&nbsp;effect</tt></dd></dl>
-
-<dl><dt><a name="Screen-set_mouse_tracking"><strong>set_mouse_tracking</strong></a>(self)</dt><dd><tt>Not&nbsp;yet&nbsp;implemented</tt></dd></dl>
-
</body>
</html>
diff --git a/setup.py b/setup.py
index 17f9951..4675aff 100644
--- a/setup.py
+++ b/setup.py
@@ -19,11 +19,15 @@
#
# Urwid web site: http://excess.org/urwid/
-from distutils.core import setup
+try:
+ from setuptools import setup
+except ImportError:
+ from distutils.core import setup
import os
-release = "0.9.5"
+import urwid
+release = urwid.__version__
setup_d = {
'name':"urwid",
@@ -85,5 +89,6 @@ except:
del setup_d['classifiers']
del setup_d['download_url']
-setup( ** setup_d )
+if __name__ == "__main__":
+ setup( ** setup_d )
diff --git a/tmpl_tutorial.html b/tmpl_tutorial.html
index 6a4cd19..9317812 100644
--- a/tmpl_tutorial.html
+++ b/tmpl_tutorial.html
@@ -1,6 +1,6 @@
<html>
<head>
-<title>Urwid Tutorial</title>
+<title>Urwid ((version)) Tutorial</title>
<style type="text/css">
h1 { text-align: center; }
h2 { margin: 40px 0 0 0; padding: 10px; background: #6d96e8;}
@@ -13,7 +13,7 @@
</style>
<body>
<a name="top"></a>
-<h1>Urwid Tutorial</h1>
+<h1>Urwid ((version)) Tutorial</h1>
<div style="text-align: center;">
<a href="http://excess.org/urwid/">Urwid Home Page</a> /
@@ -279,7 +279,7 @@ widget so it supports the same wrapping and alignment modes.
{body[frlb]}
This program asks for your name and responds "Nice to meet you, (your name)"
-<i>while</i> you type your name. F1 exits.
+<i>while</i> you type your name. F8 exits.
<pre class="code">%example[0]%</pre>
@@ -315,7 +315,7 @@ but the ListBox will still be displaying the old list.
{body[lbcont]}
This program asks for your name and responds "Nice to meet you, (your name)."
It then asks again, and again. Old values may be changed and the responses
-will be updated when you press ENTER. F1 exits.
+will be updated when you press ENTER. F8 exits.
<br><br>
Update the <a href="#frlb">previous program</a> with this code:
<pre class="code">%example[0]%</pre>
diff --git a/tutorial.html b/tutorial.html
index 749c281..b90afa8 100644
--- a/tutorial.html
+++ b/tutorial.html
@@ -1,6 +1,6 @@
<html>
<head>
-<title>Urwid Tutorial</title>
+<title>Urwid 0.9.6 Tutorial</title>
<style type="text/css">
h1 { text-align: center; }
h2 { margin: 40px 0 0 0; padding: 10px; background: #6d96e8;}
@@ -13,7 +13,7 @@
</style>
<body>
<a name="top"></a>
-<h1>Urwid Tutorial</h1>
+<h1>Urwid 0.9.6 Tutorial</h1>
<div style="text-align: center;">
<a href="http://excess.org/urwid/">Urwid Home Page</a> /
@@ -97,8 +97,7 @@ def run():
while not ui.get_input():
pass
-ui.run_wrapper( run )
-</pre>
+ui.run_wrapper( run )</pre>
<ul>
<li>The <a href="reference.html#curses_display.Screen">curses_display.Screen</a>
@@ -151,8 +150,7 @@ def run():
while not ui.get_input():
pass
-ui.run_wrapper( run )
-</pre>
+ui.run_wrapper( run )</pre>
<ul>
<li><a href="reference.html#Screen-get_cols_rows">get_cols_rows</a>
@@ -229,8 +227,7 @@ def run():
while not ui.get_input():
pass
-ui.run_wrapper( run )
-</pre>
+ui.run_wrapper( run )</pre>
<ul>
<li>After creating the
@@ -320,8 +317,7 @@ def run():
if &quot;window resize&quot; in keys:
cols, rows = ui.get_cols_rows()
-ui.run_wrapper( run )
-</pre>
+ui.run_wrapper( run )</pre>
The <a href="reference.html#Screen-get_input">get_input</a> function will
return "window resize" among keys pressed when the window is resized. It
@@ -394,8 +390,7 @@ def run():
if fill.selectable():
fill.keypress( (cols, rows), k )
-ui.run_wrapper( run )
-</pre>
+ui.run_wrapper( run )</pre>
<ul>
<li>An <a href="reference.html#Edit">Edit</a> widget is created with the
@@ -451,7 +446,7 @@ widget so it supports the same wrapping and alignment modes.
<span class="back">[<a href="#top">back to top</a>]</span></h3>
This program asks for your name and responds "Nice to meet you, (your name)"
-<i>while</i> you type your name. F1 exits.
+<i>while</i> you type your name. F8 exits.
<pre class="code">import urwid.curses_display
import urwid
@@ -460,7 +455,7 @@ class Conversation:
def __init__(self):
self.items = [ self.new_question() ]
self.listbox = urwid.ListBox( self.items )
- instruct = urwid.Text(&quot;Press F1 to exit.&quot;)
+ instruct = urwid.Text(&quot;Press F8 to exit.&quot;)
header = urwid.AttrWrap( instruct, 'header' )
self.top = urwid.Frame(self.listbox, header)
@@ -468,7 +463,7 @@ class Conversation:
self.ui = urwid.curses_display.Screen()
self.ui.register_palette([
('header', 'black', 'dark cyan', 'standout'),
- ('I say', 'dark blue', 'default', 'bold'),
+ ('I say', 'default', 'default', 'bold'),
])
self.ui.run_wrapper( self.run )
@@ -478,7 +473,7 @@ class Conversation:
while True:
self.draw_screen( size )
keys = self.ui.get_input()
- if &quot;f1&quot; in keys:
+ if &quot;f8&quot; in keys:
break
for k in keys:
if k == &quot;window resize&quot;:
@@ -499,8 +494,7 @@ class Conversation:
def new_answer(self, name):
return urwid.Text(('I say',&quot;Nice to meet you, &quot;+name+&quot;\n&quot;))
-Conversation().main()
-</pre>
+Conversation().main()</pre>
<ul>
<li>In the __init__ function a list called self.items is created. It
@@ -523,35 +517,35 @@ editing operations on the list, eg. "list = list + [something]" will not work,
use "list += [something]" instead. The former code will create a new list
but the ListBox will still be displaying the old list.
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"><u> </u> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
</pre></div>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Tim t<u> </u> </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Tim</span>
-<span style="color:#0000c0;background:silver">t</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Tim</span>
+<span style="color:black;background:silver">t</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
</pre></div>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Tim the Ench<u> </u> </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Tim</span>
-<span style="color:#0000c0;background:silver">the Ench</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Tim</span>
+<span style="color:black;background:silver">the Ench</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
</pre></div>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Tim the Enchanter<u> </u> </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Tim</span>
-<span style="color:#0000c0;background:silver">the Enchanter</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Tim</span>
+<span style="color:black;background:silver">the Enchanter</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
</pre></div>
@@ -564,7 +558,7 @@ but the ListBox will still be displaying the old list.
This program asks for your name and responds "Nice to meet you, (your name)."
It then asks again, and again. Old values may be changed and the responses
-will be updated when you press ENTER. F1 exits.
+will be updated when you press ENTER. F8 exits.
<br><br>
Update the <a href="#frlb">previous program</a> with this code:
<pre class="code"> def run(self):
@@ -573,7 +567,7 @@ Update the <a href="#frlb">previous program</a> with this code:
while True:
self.draw_screen( size )
keys = self.ui.get_input()
- if &quot;f1&quot; in keys:
+ if &quot;f8&quot; in keys:
break
for k in keys:
if k == &quot;window resize&quot;:
@@ -599,8 +593,7 @@ Update the <a href="#frlb">previous program</a> with this code:
widget, pos = self.listbox.get_focus()
widget.set_edit_pos(0)
else:
- self.top.keypress( size, k )
-</pre>
+ self.top.keypress( size, k )</pre>
<ul>
<li>In this version only the ENTER key receives special attention. When the
@@ -635,12 +628,12 @@ does most of the hard work:
</ul>
</ul>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Abe </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Abe</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Abe</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Bob<u> </u> </span>
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
@@ -649,32 +642,32 @@ does most of the hard work:
<span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
</pre></div>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Abe</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">Nice to meet you, Abe</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Bob </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Bob</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Bob</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Carl </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Carl</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Carl</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"><u> </u> </span>
</pre></div>
-<div class="shot"><pre><span style="color:black;background:teal">Press F1 to exit. </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Bob</span><span style="color:black;background:silver"> </span>
+<div class="shot"><pre><span style="color:black;background:teal">Press F8 to exit. </span>
+<span style="color:black;background:silver">Nice to meet you, Bob</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Carl </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Carl</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Carl</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver">Dave </span>
-<span style="color:#0000c0;background:silver">Nice to meet you, Dave</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">Nice to meet you, Dave</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"> </span>
-<span style="color:#0000c0;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
+<span style="color:black;background:silver">What is your name?</span><span style="color:black;background:silver"> </span>
<span style="color:black;background:silver"><u> </u> </span>
</pre></div>
@@ -718,8 +711,7 @@ AttrWrap we can see what is happening while the focus changes:
urwid.Divider(&quot;-&quot;),
urwid.Text(&quot;What could be after this?&quot;),
urwid.Text(&quot;The end.&quot;),
-] ]
-</pre>
+] ]</pre>
<div class="shot"><pre><span style="color:white;background:black">Pressed: </span>
<span style="color:black;background:teal">This is a text </span>
<span style="color:black;background:teal">string that is </span>
@@ -1057,8 +1049,7 @@ This is an example of a custom widget that uses WidgetWrap:
def get_state(self):
for o in self.options:
if o.get_state() is True:
- return o.get_label()
-</pre>
+ return o.get_label()</pre>
The above code creates a group of RadioButtons and provides a method to
query the state of the buttons.
@@ -1096,8 +1087,7 @@ class BoxPudding( urwid.BoxWidget ):
return False
def render( self, (maxcol, maxrow), focus=False ):
num_pudding = maxcol / len(&quot;Pudding&quot;)
- return urwid.Canvas( [&quot;Pudding&quot;*num_pudding] * maxrow )
-</pre>
+ return urwid.Canvas( [&quot;Pudding&quot;*num_pudding] * maxrow )</pre>
The above code implements two widget classes. Pudding is a flow widget and
BoxPudding is a box widget. Pudding will render as much "Pudding" as will
@@ -1128,8 +1118,7 @@ row calculations for you:
return w.render( (maxcol,), focus )
def display_widget( self, (maxcol,), focus ):
num_pudding = maxcol / len(&quot;Pudding&quot;)
- return urwid.Text( &quot;Pudding&quot;*num_pudding )
-</pre>
+ return urwid.Text( &quot;Pudding&quot;*num_pudding )</pre>
The NewPudding class behaves the same way as the Pudding class above, but in
NewPudding you can change the way the widget appears by modifying only the
@@ -1157,8 +1146,7 @@ or box widget depending on what is required:
else:
(maxcol, maxrow) = size
num_pudding = maxcol / len(&quot;Pudding&quot;)
- return urwid.Canvas( [&quot;Pudding&quot;*num_pudding] * maxrow )
-</pre>
+ return urwid.Canvas( [&quot;Pudding&quot;*num_pudding] * maxrow )</pre>
MultiPudding will work in place of either Pudding or BoxPudding above. The
number of elements in the size tuple determines whether the containing widget
@@ -1199,8 +1187,7 @@ method to handle keyboard input.
if not self.pudding:
self.pudding = &quot;pudding&quot;
else:
- return key
-</pre>
+ return key</pre>
The SelectablePudding widget will display its contents in uppercase when it
is in focus, and it allows the user to "eat" the pudding by pressing each of
@@ -1249,8 +1236,7 @@ cursor is visible within its focus widget.
col = self.cursor_col +1
else:
return key
- self.cursor_x = max(0, min( maxcol-1, col ))
-</pre>
+ self.cursor_x = max(0, min( maxcol-1, col ))</pre>
CursorPudding will let the user move the cursor through the widget by
pressing LEFT and RIGHT. The cursor must only be added to the canvas when
@@ -1277,8 +1263,7 @@ method must move the cursor to that position and return True.
def move_cursor_to_coords( self, (maxcol,), col, row ):
assert row == 0
self.cursor_x = col
- return True
-</pre>
+ return True</pre>
<br clear="left">
<br>
diff --git a/urwid/__init__.py b/urwid/__init__.py
index 1747497..5d7c453 100644
--- a/urwid/__init__.py
+++ b/urwid/__init__.py
@@ -21,12 +21,15 @@
__all__ = [
'BoxWidget','Frame','Filler','ListBox','SimpleListWalker',
+ 'WidgetWrap','AttrWrap','Padding','Divider','LineBox','SolidFill',
+ 'Columns','Pile','GridFlow','BoxAdapter','Overlay',
'FlowWidget','Text','Edit','IntEdit','Button','CheckBox','RadioButton',
'BarGraph','ProgressBar','GraphVScale',
- 'Columns','Pile','GridFlow','BoxAdapter','Overlay',
- 'AttrWrap','Padding','Divider',
'Canvas','CanvasCombine','CanvasJoin',
+ 'TextLayout','StandardTextLayout',
+ 'set_encoding','get_encoding_mode','supports_unicode',
]
+__version__ = "0.9.6"
from widget import *
diff --git a/urwid/escape.py b/urwid/escape.py
index 2d39123..23f4d38 100644
--- a/urwid/escape.py
+++ b/urwid/escape.py
@@ -27,14 +27,18 @@ Terminal Escape Sequences for input and display
import util
import os
+import encodings
+utf8decode = lambda s: encodings.codecs.utf_8_decode(s)[0]
+
SO = "\x0e"
SI = "\x0f"
DEC_TAG = "0"
-DEC_SPECIAL_CHARS = u"◆▒°±┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·"
+DEC_SPECIAL_CHARS = utf8decode("◆▒°±┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·")
ALT_DEC_SPECIAL_CHARS = u"`afgjklmnopqrstuvwxyz{|}~"
DEC_SPECIAL_CHARMAP = {}
+assert len(DEC_SPECIAL_CHARS) == len(ALT_DEC_SPECIAL_CHARS), `DEC_SPECIAL_CHARS, ALT_DEC_SPECIAL_CHARS`
for c, alt in zip(DEC_SPECIAL_CHARS, ALT_DEC_SPECIAL_CHARS):
DEC_SPECIAL_CHARMAP[ord(c)] = SO + alt + SI
@@ -54,6 +58,7 @@ input_sequences = [
('[1~','home'),('[2~','insert'),('[3~','delete'),('[4~','end'),
('[5~','page up'),('[6~','page down'),
+ ('[7~','home'),('[8~','end'),
('[[A','f1'),('[[B','f2'),('[[C','f3'),('[[D','f4'),('[[E','f5'),
diff --git a/urwid/graphics.py b/urwid/graphics.py
index 3bbe250..07179ed 100755
--- a/urwid/graphics.py
+++ b/urwid/graphics.py
@@ -25,6 +25,7 @@ from __future__ import nested_scopes
from util import *
from canvas import *
from widget import *
+from escape import utf8decode
try: True # old python?
except: False, True = 0, 1
@@ -43,14 +44,14 @@ class LineBox(WidgetWrap):
t = urwid.AttrWrap(t, a)
return t
- tline = use_attr( tline, Divider(u"─"))
- bline = use_attr( bline, Divider(u"─"))
- lline = use_attr( rline, SolidFill(u"│"))
- rline = use_attr( rline, SolidFill(u"│"))
- tlcorner = use_attr( tlcorner, Text(u"┌"))
- trcorner = use_attr( trcorner, Text(u"┐"))
- blcorner = use_attr( blcorner, Text(u"└"))
- brcorner = use_attr( brcorner, Text(u"┘"))
+ tline = use_attr( tline, Divider(utf8decode("─")))
+ bline = use_attr( bline, Divider(utf8decode("─")))
+ lline = use_attr( rline, SolidFill(utf8decode("│")))
+ rline = use_attr( rline, SolidFill(utf8decode("│")))
+ tlcorner = use_attr( tlcorner, Text(utf8decode("┌")))
+ trcorner = use_attr( trcorner, Text(utf8decode("┐")))
+ blcorner = use_attr( blcorner, Text(utf8decode("└")))
+ brcorner = use_attr( brcorner, Text(utf8decode("┘")))
top = Columns([ ('fixed', 1, tlcorner),
tline, ('fixed', 1, trcorner) ])
middle = Columns( [('fixed', 1, lline),
@@ -67,8 +68,8 @@ class BarGraphError(Exception):
pass
class BarGraph(BoxWidget):
- eighths = u" ▁▂▃▄▅▆▇"
- hlines = u"_⎺⎻─⎼⎽"
+ eighths = utf8decode(" ▁▂▃▄▅▆▇")
+ hlines = utf8decode("_⎺⎻─⎼⎽")
def __init__(self, attlist, hatt=None, satt=None):
"""
@@ -656,7 +657,7 @@ def scale_bar_values( bar, top, maxrow ):
class ProgressBar( FlowWidget ):
- eighths = u" ▏▎▍▌▋▊▉"
+ eighths = utf8decode(" ▏▎▍▌▋▊▉")
def __init__(self, normal, complete, current=0, done=100, satt=None):
"""
normal -- attribute for uncomplete part of progress bar
diff --git a/urwid/util.py b/urwid/util.py
index 41df54d..86f4a57 100644
--- a/urwid/util.py
+++ b/urwid/util.py
@@ -25,13 +25,19 @@ from __future__ import nested_scopes
import utable
import escape
+import encodings
+
try: True # old python?
except: False, True = 0, 1
# Try to determine if using a supported double-byte encoding
import locale
try:
- detected_encoding = locale.getdefaultlocale()[1]
+ try:
+ locale.setlocale( locale.LC_ALL, "" )
+ except locale.Error:
+ pass
+ detected_encoding = locale.getlocale()[1]
if not detected_encoding:
detected_encoding = ""
except ValueError, e:
diff --git a/urwid/widget.py b/urwid/widget.py
index a5c9cfe..da4b0bb 100755
--- a/urwid/widget.py
+++ b/urwid/widget.py
@@ -2167,9 +2167,15 @@ class Columns: # either FlowWidget or BoxWidget
"""Return the focus column index."""
return self.focus_col
- def set_focus(self, widget):
- """Set the column in focus with a widget in self.widget_list."""
- position = self.widget_list.index(widget)
+ def set_focus(self, item):
+ """Set the item in focus.
+
+ item -- widget or integer index"""
+ if type(item) == type(0):
+ assert item>=0 and item<len(self.widget_list)
+ position = item
+ else:
+ position = self.widget_list.index(item)
self.focus_col = position
def get_focus(self):