diff options
-rwxr-xr-x | docgen_reference.py | 156 | ||||
-rwxr-xr-x | docgen_tutorial.py | 334 | ||||
-rw-r--r-- | reference.html | 124 | ||||
-rw-r--r-- | setup.py | 11 | ||||
-rw-r--r-- | tmpl_tutorial.html | 8 | ||||
-rw-r--r-- | tutorial.html | 125 | ||||
-rw-r--r-- | urwid/__init__.py | 7 | ||||
-rw-r--r-- | urwid/escape.py | 7 | ||||
-rwxr-xr-x | urwid/graphics.py | 23 | ||||
-rw-r--r-- | urwid/util.py | 8 | ||||
-rwxr-xr-x | urwid/widget.py | 12 |
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 screen with rendered canvas.</tt></dd></dl> @@ -217,10 +223,42 @@ resize_wait -- amount of time in seconds to&n After calling this function get_input will include mouse<br> click events along with 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 True. Selectable by 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 a screen update to the client.</tt></dd></dl> + +<dl><dt><a name="Screen-get_cols_rows"><strong>get_cols_rows</strong></a>(self)</dt><dd><tt>Return the screen 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 pending input as a list.</tt></dd></dl> + +<dl><dt><a name="Screen-register_palette"><strong>register_palette</strong></a>(self, l)</dt><dd><tt>Register a list of palette entries.<br> + <br> +l -- list of (name, foreground, background) or<br> + (name, same_as_other_name) palette entries.<br> + <br> +calls self.<strong>register_palette_entry</strong> for each item in 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 a single palette entry.<br> + <br> +name -- new entry/attribute name<br> +foreground -- foreground colour<br> +background -- background colour<br> +mono -- monochrome terminal attribute<br> + <br> +See curses_display.register_palette_entry for more 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 the application main loop.<br> + <br> +This function reads the initial screen size, generates a<br> +unique id and handles cleanup when fn exits.<br> + <br> +web_display.set_preferences(..) must be called before calling<br> +this function for the preferences to take effect</tt></dd></dl> + +<dl><dt><a name="Screen-set_mouse_tracking"><strong>set_mouse_tracking</strong></a>(self)</dt><dd><tt>Not yet 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 -- a box widget for the body of the frame<br> header -- a flow widget for above the body (or None)<br> footer -- a flow widget for below the body (or None)<br> @@ -376,17 +414,6 @@ offset_inset -- either the number of rows bet Methods inherited from BoxWidget:<br> <dl><dt><a name="ListBox-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return True. Selectable by 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 -- list to walk</tt></dd></dl> - -<dl><dt><a name="SimpleListWalker-get_focus"><strong>get_focus</strong></a>(self)</dt><dd><tt>Return (focus widget, focus position).</tt></dd></dl> - -<dl><dt><a name="SimpleListWalker-get_next"><strong>get_next</strong></a>(self, start_from)</dt><dd><tt>Return (widget after start_from, position after start_from).</tt></dd></dl> - -<dl><dt><a name="SimpleListWalker-get_prev"><strong>get_prev</strong></a>(self, start_from)</dt><dd><tt>Return (widget before start_from, position before start_from).</tt></dd></dl> - -<dl><dt><a name="SimpleListWalker-set_focus"><strong>set_focus</strong></a>(self, position)</dt><dd><tt>Set focus 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 self.<strong>w</strong> if name is in Widget interface definition.</tt></dd></dl> @@ -530,7 +557,9 @@ Only makes sense if self.<strong>widget_list</strong> c <dl><dt><a name="Columns-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return the selectable value of the focus column.</tt></dd></dl> -<dl><dt><a name="Columns-set_focus"><strong>set_focus</strong></a>(self, widget)</dt><dd><tt>Set the column in focus with a widget in 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 the item in focus. <br> + <br> +item -- widget or integer index</tt></dd></dl> <dl><dt><a name="Columns-set_focus_column"><strong>set_focus_column</strong></a>(self, num)</dt><dd><tt>Set the column in focus by its index in self.<strong>widget_list</strong>.</tt></dd></dl> @@ -684,10 +713,7 @@ always rendered the full size available "below"&nb <dl><dt><a name="Overlay-selectable"><strong>selectable</strong></a>(self)</dt><dd><tt>Return selectable from 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 False. Not selectable by 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 -- content of text widget, one of:<br> plain string -- string is displayed<br> ( attr, markup2 ) -- markup2 is given attribute 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 False. Not selectable by 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 -- flow widgets: (maxcol,) box widgets: (maxcol,maxrow)<br> where maxcol and maxrow are the maximum screen columns<br> and rows for the widget when rendered<br> @@ -1243,6 +1269,12 @@ should take the focus when changing focus bet <br> MUST be 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 True. Selectable by 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 False. Not selectable by 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 (widget, position).<br> <br> @@ -1273,6 +1305,17 @@ Returns None.<br> <br> MUST be 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 -- list to walk</tt></dd></dl> + +<dl><dt><a name="SimpleListWalker-get_focus"><strong>get_focus</strong></a>(self)</dt><dd><tt>Return (focus widget, focus position).</tt></dd></dl> + +<dl><dt><a name="SimpleListWalker-get_next"><strong>get_next</strong></a>(self, start_from)</dt><dd><tt>Return (widget after start_from, position after start_from).</tt></dd></dl> + +<dl><dt><a name="SimpleListWalker-get_prev"><strong>get_prev</strong></a>(self, start_from)</dt><dd><tt>Return (widget before start_from, position before start_from).</tt></dd></dl> + +<dl><dt><a name="SimpleListWalker-set_focus"><strong>set_focus</strong></a>(self, position)</dt><dd><tt>Set focus 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 -- list of strings, one for each line<br> attr -- list of run length encoded attributes for text<br> @@ -1445,41 +1488,6 @@ script should immediately exit.<br> <br> web_display.set_preferences(..) should be called before calling this<br> function for the preferences to take 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 a screen update to the client.</tt></dd></dl> - -<dl><dt><a name="Screen-get_cols_rows"><strong>get_cols_rows</strong></a>(self)</dt><dd><tt>Return the screen 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 pending input as a list.</tt></dd></dl> - -<dl><dt><a name="Screen-register_palette"><strong>register_palette</strong></a>(self, l)</dt><dd><tt>Register a list of palette entries.<br> - <br> -l -- list of (name, foreground, background) or<br> - (name, same_as_other_name) palette entries.<br> - <br> -calls self.<strong>register_palette_entry</strong> for each item in 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 a single palette entry.<br> - <br> -name -- new entry/attribute name<br> -foreground -- foreground colour<br> -background -- background colour<br> -mono -- monochrome terminal attribute<br> - <br> -See curses_display.register_palette_entry for more info.</tt></dd></dl> - -<dl><dt><a name="Screen-run_wrapper"><strong>run_wrapper</strong></a>(self, fn)</dt><dd><tt>Start the application main loop.<br> - <br> -This function reads the initial screen size, generates a<br> -unique id and handles cleanup when fn exits.<br> - <br> -web_display.set_preferences(..) must be called before calling<br> -this function for the preferences to take effect</tt></dd></dl> - -<dl><dt><a name="Screen-set_mouse_tracking"><strong>set_mouse_tracking</strong></a>(self)</dt><dd><tt>Not yet implemented</tt></dd></dl> - </body> </html> @@ -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 "window resize" 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("Press F1 to exit.") + instruct = urwid.Text("Press F8 to exit.") 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 "f1" in keys: + if "f8" in keys: break for k in keys: if k == "window resize": @@ -499,8 +494,7 @@ class Conversation: def new_answer(self, name): return urwid.Text(('I say',"Nice to meet you, "+name+"\n")) -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 "f1" in keys: + if "f8" in keys: break for k in keys: if k == "window resize": @@ -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("-"), urwid.Text("What could be after this?"), urwid.Text("The end."), -] ] -</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("Pudding") - return urwid.Canvas( ["Pudding"*num_pudding] * maxrow ) -</pre> + return urwid.Canvas( ["Pudding"*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("Pudding") - return urwid.Text( "Pudding"*num_pudding ) -</pre> + return urwid.Text( "Pudding"*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("Pudding") - return urwid.Canvas( ["Pudding"*num_pudding] * maxrow ) -</pre> + return urwid.Canvas( ["Pudding"*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 = "pudding" 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): |