diff options
author | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-05-11 21:25:29 -0700 |
---|---|---|
committer | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-05-11 21:25:29 -0700 |
commit | 33a2ea5a7dde93022635617c015363b52e749088 (patch) | |
tree | 15d82429d3479b3df59db835c98514a47087e57c | |
parent | ea27cfaa3ef5dcf9f4028938a171d6ea513a287d (diff) | |
download | urwid-33a2ea5a7dde93022635617c015363b52e749088.tar.gz |
Fix all trailing whitespace.
-rwxr-xr-x | examples/bigtext.py | 26 | ||||
-rwxr-xr-x | examples/browse.py | 52 | ||||
-rwxr-xr-x | examples/calc.py | 244 | ||||
-rwxr-xr-x | examples/dialog.py | 76 | ||||
-rwxr-xr-x | examples/edit.py | 58 | ||||
-rwxr-xr-x | examples/fib.py | 22 | ||||
-rwxr-xr-x | examples/graph.py | 58 | ||||
-rwxr-xr-x | examples/input_test.py | 10 | ||||
-rwxr-xr-x | examples/lcd_cf635.py | 38 | ||||
-rwxr-xr-x | examples/palette_test.py | 42 | ||||
-rwxr-xr-x | examples/treesample.py | 16 | ||||
-rw-r--r-- | urwid/canvas.py | 164 | ||||
-rwxr-xr-x | urwid/container.py | 2 | ||||
-rwxr-xr-x | urwid/curses_display.py | 100 | ||||
-rwxr-xr-x | urwid/display_common.py | 50 | ||||
-rw-r--r-- | urwid/escape.py | 52 | ||||
-rwxr-xr-x | urwid/font.py | 206 | ||||
-rwxr-xr-x | urwid/html_fragment.py | 46 | ||||
-rw-r--r-- | urwid/lcd_display.py | 30 | ||||
-rwxr-xr-x | urwid/main_loop.py | 10 | ||||
-rwxr-xr-x | urwid/old_str_util.py | 10 | ||||
-rw-r--r-- | urwid/raw_display.py | 74 | ||||
-rwxr-xr-x | urwid/split_repr.py | 4 | ||||
-rw-r--r-- | urwid/text_layout.py | 46 | ||||
-rw-r--r-- | urwid/treetools.py | 72 | ||||
-rw-r--r-- | urwid/util.py | 54 | ||||
-rwxr-xr-x | urwid/web_display.py | 160 | ||||
-rw-r--r-- | urwid/widget.py | 10 |
28 files changed, 866 insertions, 866 deletions
diff --git a/examples/bigtext.py b/examples/bigtext.py index aa5c3a1..8fc448c 100755 --- a/examples/bigtext.py +++ b/examples/bigtext.py @@ -50,7 +50,7 @@ class BigTextDisplay: ('chars', 'light gray', 'black'), ('exit', 'white', 'dark cyan'), ] - + def create_radio_button(self, g, name, font, fn): w = urwid.RadioButton(g, name, False, on_state_change=fn) w.font = font @@ -61,7 +61,7 @@ class BigTextDisplay: w = urwid.Text(" " + name + " (UTF-8 mode required)") w = urwid.AttrWrap(w, 'button disabled') return w - + def create_edit(self, label, text, fn): w = urwid.Edit(label, text) urwid.connect_signal(w, 'change', fn) @@ -94,35 +94,35 @@ class BigTextDisplay: chosen_font_rb = rb exit_font = font self.font_buttons.append( rb ) - + # Create BigText self.bigtext = urwid.BigText("", None) bt = SwitchingPadding(self.bigtext, 'left', None) bt = urwid.AttrWrap(bt, 'bigtext') bt = urwid.Filler(bt, 'bottom', None, 7) bt = urwid.BoxAdapter(bt, 7) - + # Create chars_avail cah = urwid.Text("Characters Available:") self.chars_avail = urwid.Text("", wrap='any') ca = urwid.AttrWrap(self.chars_avail, 'chars') - + chosen_font_rb.set_state(True) # causes set_font_event call - + # Create Edit widget edit = self.create_edit("", "Urwid "+urwid.__version__, self.edit_change_event) - + # ListBox chars = urwid.Pile([cah, ca]) fonts = urwid.Pile([urwid.Text("Fonts:")] + self.font_buttons, focus_item=1) - col = urwid.Columns([('fixed',16,chars), fonts], 3, + col = urwid.Columns([('fixed',16,chars), fonts], 3, focus_column=1) bt = urwid.Pile([bt, edit], focus_item=1) l = [bt, urwid.Divider(), col] w = urwid.ListBox(urwid.SimpleListWalker(l)) - + # Frame w = urwid.AttrWrap(w, 'body') hdr = urwid.Text("Urwid BigText example program - F8 exits.") @@ -137,10 +137,10 @@ class BigTextDisplay: def main(self): self.view, self.exit_view = self.setup_view() - self.loop = urwid.MainLoop(self.view, self.palette, + self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input) self.loop.run() - + def unhandled_input(self, key): if key == 'f8': self.loop.widget = self.exit_view @@ -152,10 +152,10 @@ class BigTextDisplay: if key in ('n', 'N'): self.loop.widget = self.view return True - + def main(): BigTextDisplay().main() - + if '__main__'==__name__: main() diff --git a/examples/browse.py b/examples/browse.py index e182cde..d5a5f16 100755 --- a/examples/browse.py +++ b/examples/browse.py @@ -93,7 +93,7 @@ class FileTreeWidget(FlagFileWidget): def get_display_text(self): return self.get_node().get_key() - + class EmptyWidget(urwid.TreeWidget): @@ -164,7 +164,7 @@ class DirectoryNode(urwid.ParentNode): else: depth = path.count(dir_sep()) key = os.path.basename(path) - urwid.ParentNode.__init__(self, path, key=key, parent=parent, + urwid.ParentNode.__init__(self, path, key=key, parent=parent, depth=depth) def load_parent(self): @@ -186,7 +186,7 @@ class DirectoryNode(urwid.ParentNode): files.append(a) except OSError, e: depth = self.get_depth() + 1 - self._children[None] = ErrorNode(self, parent=self, key=None, + self._children[None] = ErrorNode(self, parent=self, key=None, depth=depth) return [None] @@ -199,7 +199,7 @@ class DirectoryNode(urwid.ParentNode): keys = dirs + files if len(keys) == 0: depth=self.get_depth() + 1 - self._children[None] = EmptyNode(self, parent=self, key=None, + self._children[None] = EmptyNode(self, parent=self, key=None, depth=depth) keys = [None] return keys @@ -226,7 +226,7 @@ class DirectoryBrowser: ('body', 'black', 'light gray'), ('flagged', 'black', 'dark green', ('bold','underline')), ('focus', 'light gray', 'dark blue', 'standout'), - ('flagged focus', 'yellow', 'dark cyan', + ('flagged focus', 'yellow', 'dark cyan', ('bold','standout','underline')), ('head', 'yellow', 'black', 'standout'), ('foot', 'light gray', 'black'), @@ -236,7 +236,7 @@ class DirectoryBrowser: ('flag', 'dark gray', 'light gray'), ('error', 'dark red', 'light gray'), ] - + footer_text = [ ('title', "Directory Browser"), " ", ('key', "UP"), ",", ('key', "DOWN"), ",", @@ -246,12 +246,12 @@ class DirectoryBrowser: ('key', "+"), ",", ('key', "-"), " ", ('key', "LEFT"), " ", - ('key', "HOME"), " ", + ('key', "HOME"), " ", ('key', "END"), " ", ('key', "Q"), ] - - + + def __init__(self): cwd = os.getcwd() store_initial_cwd(cwd) @@ -261,17 +261,17 @@ class DirectoryBrowser: self.footer = urwid.AttrWrap(urwid.Text(self.footer_text), 'foot') self.view = urwid.Frame( - urwid.AttrWrap(self.listbox, 'body'), - header=urwid.AttrWrap(self.header, 'head'), + urwid.AttrWrap(self.listbox, 'body'), + header=urwid.AttrWrap(self.header, 'head'), footer=self.footer) def main(self): """Run the program.""" - + self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input) self.loop.run() - + # on exit, write the flagged filenames to the console names = [escape_filename_sh(x) for x in get_flagged_names()] print " ".join(names) @@ -299,13 +299,13 @@ def add_widget(path, widget): def get_flagged_names(): """Return a list of all filenames marked as flagged.""" - + l = [] for w in _widget_cache.values(): if w.flagged: l.append(w.get_node().get_value()) return l - + ###### @@ -314,7 +314,7 @@ _initial_cwd = [] def store_initial_cwd(name): """Store the initial current working directory path components.""" - + global _initial_cwd _initial_cwd = name.split(dir_sep()) @@ -323,14 +323,14 @@ def starts_expanded(name): if name is '/': return True - + l = name.split(dir_sep()) if len(l) > len(_initial_cwd): return False - + if l != _initial_cwd[:len(l)]: return False - + return True @@ -338,11 +338,11 @@ def escape_filename_sh(name): """Return a hopefully safe shell-escaped version of a filename.""" # check whether we have unprintable characters - for ch in name: - if ord(ch) < 32: + for ch in name: + if ord(ch) < 32: # found one so use the ansi-c escaping return escape_filename_sh_ansic(name) - + # all printable characters, so return a double-quoted version name.replace('\\','\\\\') name.replace('"','\\"') @@ -353,7 +353,7 @@ def escape_filename_sh(name): def escape_filename_sh_ansic(name): """Return an ansi-c shell-escaped version of a filename.""" - + out =[] # gather the escaped characters into a list for ch in name: @@ -363,7 +363,7 @@ def escape_filename_sh_ansic(name): out.append('\\\\') else: out.append(ch) - + # slap them back together in an ansi-c quote $'...' return "$'" + "".join(out) + "'" @@ -383,6 +383,6 @@ def dir_sep(): return getattr(os.path,'sep','/') -if __name__=="__main__": +if __name__=="__main__": main() - + diff --git a/examples/calc.py b/examples/calc.py index f132172..ec1f039 100755 --- a/examples/calc.py +++ b/examples/calc.py @@ -44,7 +44,7 @@ else: def div_or_none(a,b): """Divide a by b. Return result or None on divide by zero.""" - if b == 0: + if b == 0: return None return a/b @@ -72,8 +72,8 @@ E_no_parent_column = "There is no parent column to return to." E_cant_combine = "Cannot combine cells with sub-expressions." E_invalid_in_parent_cell = "Cannot enter numbers into parent cell." E_invalid_in_help_col = [ - "Help Column is in focus. Press ", - ('key',COLUMN_KEYS[1]),"-",('key',COLUMN_KEYS[-1]), + "Help Column is in focus. Press ", + ('key',COLUMN_KEYS[1]),"-",('key',COLUMN_KEYS[-1]), " to select another column."] # Shared layout object @@ -82,12 +82,12 @@ CALC_LAYOUT = None class CalcEvent(Exception): """Events triggered by user input.""" - + attr = 'event' - + def __init__(self, message): self.message = message - + def widget(self): """Return a widget containing event information""" text = urwid.Text( self.message, 'center' ) @@ -115,24 +115,24 @@ class Cell: self.child = None self.setup_edit() self.result = urwid.Text("", layout=CALC_LAYOUT) - + def show_result(self, next_cell): """Return whether this widget should display its result. next_cell -- the cell following self or None""" - - if self.is_top: + + if self.is_top: return False if next_cell is None: return True if self.op == "+" and next_cell.op == "+": return False return True - - + + def setup_edit(self): """Create the standard edit widget for this cell.""" - + self.edit = urwid.IntEdit() if not self.is_top: self.edit.set_caption( self.op + " " ) @@ -140,38 +140,38 @@ class Cell: def get_value(self): """Return the numeric value of the cell.""" - + if self.child is not None: return self.child.get_result() else: return long("0"+self.edit.edit_text) - + def get_result(self): """Return the numeric result of this cell's operation.""" - + if self.is_top: return self.get_value() - if self.result.text == "": + if self.result.text == "": return None return long(self.result.text) def set_result(self, result): """Set the numeric result for this cell.""" - + if result == None: self.result.set_text("") else: self.result.set_text( "%d" %result ) - + def become_parent(self, column, letter): """Change the edit widget to a parent cell widget.""" - + self.child = column self.edit = ParentEdit( self.op, letter ) - + def remove_child(self): """Change the edit widget back to a standard edit widget.""" - + self.child = None self.setup_edit() @@ -183,39 +183,39 @@ class Cell: class ParentEdit(urwid.Edit): """Edit widget modified to link to a child column""" - + def __init__(self, op, letter): """Use the operator and letter of the child column as caption - + op -- operator or None letter -- letter of child column remove_fn -- function to call when user wants to remove child function takes no parameters """ - + urwid.Edit.__init__(self, layout=CALC_LAYOUT) self.op = op self.set_letter( letter ) - + def set_letter(self, letter): """Set the letter of the child column for display.""" - + self.letter = letter caption = "("+letter+")" if self.op is not None: caption = self.op+" "+caption self.set_caption(caption) - + def keypress(self, size, key): - """Disable usual editing, allow only removing of child""" - + """Disable usual editing, allow only removing of child""" + if key == "backspace": raise ColumnDeleteEvent(self.letter, from_parent=True) elif key in list("0123456789"): raise CalcEvent, E_invalid_in_parent_cell else: return key - + class CellWalker(urwid.ListWalker): def __init__(self, content): @@ -243,13 +243,13 @@ class CellWalker(urwid.ListWalker): return self.div, pos else: return self.content[i].result, pos - + def get_focus(self): return self._get_at_pos(self.focus) - + def set_focus(self, focus): self.focus = focus - + def get_next(self, start_from): i, sub = start_from assert sub in (0,1,2) @@ -264,7 +264,7 @@ class CellWalker(urwid.ListWalker): return self._get_at_pos( (i, 2) ) else: return self._get_at_pos( (i+1, 0) ) - + def get_prev(self, start_from): i, sub = start_from assert sub in (0,1,2) @@ -280,8 +280,8 @@ class CellWalker(urwid.ListWalker): return self._get_at_pos( (i, 0) ) else: return self._get_at_pos( (i, 1) ) - - + + class CellColumn( urwid.WidgetWrap ): def __init__(self, letter): self.walker = CellWalker([Cell(None)]) @@ -289,26 +289,26 @@ class CellColumn( urwid.WidgetWrap ): self.listbox = urwid.ListBox( self.walker ) self.set_letter( letter ) urwid.WidgetWrap.__init__(self, self.frame) - + def set_letter(self, letter): """Set the column header with letter.""" - + self.letter = letter header = urwid.AttrWrap( urwid.Text( ["Column ",('key',letter)], layout = CALC_LAYOUT), 'colhead' ) self.frame = urwid.Frame( self.listbox, header ) - + def keypress(self, size, key): key = self.frame.keypress( size, key) - if key is None: + if key is None: changed = self.update_results() if changed: raise UpdateParentEvent() return - + f, (i, sub) = self.walker.get_focus() - if sub != 0: + if sub != 0: # f is not an edit widget return key if OPERATORS.has_key(key): @@ -317,27 +317,27 @@ class CellColumn( urwid.WidgetWrap ): cursor_pos = edit.edit_pos tail = edit.edit_text[cursor_pos:] edit.set_edit_text( edit.edit_text[:cursor_pos] ) - + new_cell = Cell( key ) new_cell.edit.set_edit_text( tail ) self.content[i+1:i+1] = [new_cell] - + changed = self.update_results() self.move_focus_next( size ) self.content[i+1].edit.set_edit_pos(0) if changed: raise UpdateParentEvent() return - + elif key == 'backspace': # unhandled backspace, we're at beginning of number # append current number to cell above, removing operator above = self.walker.get_cell(i-1) if above is None: # we're the first cell - raise ColumnDeleteEvent( self.letter, + raise ColumnDeleteEvent( self.letter, from_parent=False ) - + edit = self.walker.get_cell(i).edit # check that we can combine if above.child is not None: @@ -346,7 +346,7 @@ class CellColumn( urwid.WidgetWrap ): # ..and current not empty, no good raise CalcEvent, E_cant_combine above_pos = 0 - else: + else: # above is normal number cell above_pos = len(above.edit.edit_text) above.edit.set_edit_text( above.edit.edit_text + @@ -359,7 +359,7 @@ class CellColumn( urwid.WidgetWrap ): if changed: raise UpdateParentEvent() return - + elif key == 'delete': # pull text from next cell into current cell = self.walker.get_cell(i) @@ -373,7 +373,7 @@ class CellColumn( urwid.WidgetWrap ): if below.child is not None: # cell below is a parent raise CalcEvent, E_cant_combine - + edit = self.walker.get_cell(i).edit edit.set_edit_text( edit.edit_text + below.edit.edit_text ) @@ -385,53 +385,53 @@ class CellColumn( urwid.WidgetWrap ): return return key - + def move_focus_next(self, size): f, (i, sub) = self.walker.get_focus() assert i<len(self.content)-1 - + ni = i while ni == i: self.frame.keypress(size, 'down') nf, (ni, nsub) = self.walker.get_focus() - + def move_focus_prev(self, size): f, (i, sub) = self.walker.get_focus() assert i>0 - + ni = i while ni == i: self.frame.keypress(size, 'up') nf, (ni, nsub) = self.walker.get_focus() - - + + def update_results( self, start_from=None ): """Update column. Return True if final result changed. - + start_from -- Cell to start updating from or None to start from the current focus (default None) """ - + if start_from is None: f, (i, sub) = self.walker.get_focus() else: i = self.content.index(start_from) if i == None: return False - + focus_cell = self.walker.get_cell(i) - + if focus_cell.is_top: x = focus_cell.get_value() last_op = None - else: + else: last_cell = self.walker.get_cell(i-1) x = last_cell.get_result() - + if x is not None and focus_cell.op is not None: - x = OPERATORS[focus_cell.op]( x, + x = OPERATORS[focus_cell.op]( x, focus_cell.get_value() ) focus_cell.set_result(x) - + for cell in self.content[i+1:]: if cell.op is None: x = None @@ -443,11 +443,11 @@ class CellColumn( urwid.WidgetWrap ): return True - + def create_child( self, letter ): """Return (parent cell,child column) or None,None on failure.""" f, (i, sub) = self.walker.get_focus() - if sub != 0: + if sub != 0: # f is not an edit widget return None, None @@ -467,10 +467,10 @@ class CellColumn( urwid.WidgetWrap ): return len(self.content)==1 and self.content[0].is_empty() - + def get_expression(self): """Return the expression as a printable string.""" - + l = [] for c in self.content: if c.op is not None: # only applies to first cell @@ -479,16 +479,16 @@ class CellColumn( urwid.WidgetWrap ): l.append("("+c.child.get_expression()+")") else: l.append("%d"%c.get_value()) - + return "".join(l) def get_result(self): """Return the result of the last cell in the column.""" - + return self.content[-1].get_result() - - + + class HelpColumn(urwid.BoxWidget): help_text = [ @@ -507,8 +507,8 @@ class HelpColumn(urwid.BoxWidget): "", [ "Sub-expressions: ", ('key', "("), " and ", ('key', ")") ], "", - [ "Columns: ", ('key', COLUMN_KEYS[0]), " and ", - ('key',COLUMN_KEYS[1]), "-", + [ "Columns: ", ('key', COLUMN_KEYS[0]), " and ", + ('key',COLUMN_KEYS[1]), "-", ('key',COLUMN_KEYS[-1]) ], "", [ "Exit: ", ('key', "Q") ], @@ -516,39 +516,39 @@ class HelpColumn(urwid.BoxWidget): "", ["Column Calculator does operations in the order they are ", "typed, not by following usual precedence rules. ", - "If you want to calculate ", ('key', "12 - 2 * 3"), + "If you want to calculate ", ('key', "12 - 2 * 3"), " with the multiplication happening before the ", - "subtraction you must type ", + "subtraction you must type ", ('key', "12 - (2 * 3)"), " instead."], ] - + def __init__(self): self.head = urwid.AttrWrap( urwid.Text(["Help Column ", ('key',"?")], layout = CALC_LAYOUT), 'help') - self.foot = urwid.AttrWrap( + self.foot = urwid.AttrWrap( urwid.Text(["[text continues.. press ", ('key',"?"), " then scroll]"]), 'helpnote' ) self.items = [urwid.Text(x) for x in self.help_text] self.listbox = urwid.ListBox(urwid.SimpleListWalker(self.items)) self.body = urwid.AttrWrap( self.listbox, 'help' ) self.frame = urwid.Frame( self.body, header=self.head) - + def render(self, size, focus=False): maxcol, maxrow = size head_rows = self.head.rows((maxcol,)) - if "bottom" in self.listbox.ends_visible( + if "bottom" in self.listbox.ends_visible( (maxcol, maxrow-head_rows) ): self.frame.footer = None else: self.frame.footer = self.foot return self.frame.render( (maxcol, maxrow), focus) - + def keypress( self, size, key ): return self.frame.keypress( size, key ) - + class CalcDisplay: palette = [ @@ -563,7 +563,7 @@ class CalcDisplay: ('event', 'light red', 'black', 'standout'), ('confirm', 'yellow', 'black', 'bold'), ] - + def __init__(self): self.columns = urwid.Columns([HelpColumn(), CellColumn("A")], 1) self.col_list = self.columns.widget_list @@ -586,7 +586,7 @@ class CalcDisplay: def input_filter(self, input, raw_input): if 'q' in input or 'Q' in input: raise urwid.ExitMainLoop() - + # handle other keystrokes for k in input: try: @@ -597,51 +597,51 @@ class CalcDisplay: # display any message self.event = e self.view.footer = e.widget() - + # remove all input from further processing by MainLoop return [] - + def wrap_keypress(self, key): """Handle confirmation and throw event on bad input.""" - + try: key = self.keypress(key) - + except ColumnDeleteEvent, e: if e.letter == COLUMN_KEYS[1]: # cannot delete the first column, ignore key return - + if not self.column_empty( e.letter ): # need to get two in a row, so check last event if not isinstance(self.event,ColumnDeleteEvent): # ask for confirmation raise e self.delete_column(e.letter) - + except UpdateParentEvent, e: self.update_parent_columns() return - + if key is None: return if self.columns.get_focus_column() == 0: if key not in ('up','down','page up','page down'): raise CalcEvent, E_invalid_in_help_col - + if key not in EDIT_KEYS and key not in MOVEMENT_KEYS: raise CalcEvent, E_invalid_key % key.upper() - + def keypress(self, key): """Handle a keystroke.""" self.loop.process_input([key]) - + if key.upper() in COLUMN_KEYS: # column switch i = COLUMN_KEYS.index(key.upper()) - if i >= len( self.col_list ): + if i >= len( self.col_list ): raise CalcEvent, E_no_such_column % key.upper() self.columns.set_focus_column( i ) return @@ -650,7 +650,7 @@ class CalcDisplay: if len( self.col_list ) >= len(COLUMN_KEYS): raise CalcEvent, E_no_more_columns i = self.columns.get_focus_column() - if i == 0: + if i == 0: # makes no sense in help column return key col = self.col_list[i] @@ -662,7 +662,7 @@ class CalcDisplay: self.col_list.append(child) self.set_link( parent, col, child ) self.columns.set_focus_column(len(self.col_list)-1) - + elif key == ")": i = self.columns.get_focus_column() if i == 0: @@ -670,43 +670,43 @@ class CalcDisplay: return key col = self.col_list[i] parent, pcol = self.get_parent( col ) - if parent is None: + if parent is None: # column has no parent raise CalcEvent, E_no_parent_column - + new_i = self.col_list.index( pcol ) self.columns.set_focus_column( new_i ) else: return key - + def set_link( self, parent, pcol, child ): """Store the link between a parent cell and child column. - + parent -- parent Cell object pcol -- CellColumn where parent resides child -- child CellColumn object""" self.col_link[ child ] = parent, pcol - + def get_parent( self, child ): """Return the parent and parent column for a given column.""" return self.col_link.get( child, (None,None) ) - + def column_empty(self, letter): """Return True if the column passed is empty.""" - + i = COLUMN_KEYS.index(letter) col = self.col_list[i] return col.is_empty() - - + + def delete_column(self, letter): """Delete the column with the given letter.""" - + i = COLUMN_KEYS.index(letter) col = self.col_list[i] - + parent, pcol = self.get_parent( col ) f = self.columns.get_focus_column() @@ -714,11 +714,11 @@ class CalcDisplay: # move focus to the parent column f = self.col_list.index(pcol) self.columns.set_focus_column(f) - + parent.remove_child() pcol.update_results(parent) del self.col_list[i] - + # delete children of this column keep_right_cols = [] remove_cols = [col] @@ -732,7 +732,7 @@ class CalcDisplay: # remove the links del self.col_link[rc] # keep only the non-children - self.col_list[i:] = keep_right_cols + self.col_list[i:] = keep_right_cols # fix the letter assignments for j in range(i, len(self.col_list)): @@ -750,21 +750,21 @@ class CalcDisplay: col = self.col_list[f] while 1: parent, pcol = self.get_parent(col) - if pcol is None: + if pcol is None: return changed = pcol.update_results( start_from = parent ) - if not changed: + if not changed: return col = pcol - - + + def get_expression_result(self): """Return (expression, result) as strings.""" - + col = self.col_list[1] return col.get_expression(), "%d"%col.get_result() - + class CalcNumLayout(urwid.TextLayout): @@ -800,19 +800,19 @@ class CalcNumLayout(urwid.TextLayout): return l - - - + + + def main(): """Launch Column Calculator.""" global CALC_LAYOUT CALC_LAYOUT = CalcNumLayout() - + urwid.web_display.set_preferences("Column Calculator") # try to handle short web requests quickly if urwid.web_display.handle_short_request(): return - + CalcDisplay().main() if '__main__'==__name__ or urwid.web_display.is_web_request(): diff --git a/examples/dialog.py b/examples/dialog.py index 2de61c0..dbdeb28 100755 --- a/examples/dialog.py +++ b/examples/dialog.py @@ -42,7 +42,7 @@ class DialogDisplay: ('focus','white','dark blue','bold'), ('focustext','light gray','dark blue'), ] - + def __init__(self, text, height, width, body=None): width = int(width) if width <= 0: @@ -50,7 +50,7 @@ class DialogDisplay: height = int(height) if height <= 0: height = ('relative', 80) - + self.body = body if body is None: # fill space with nothing @@ -61,24 +61,24 @@ class DialogDisplay: self.frame.header = urwid.Pile( [urwid.Text(text), urwid.Divider()] ) w = self.frame - + # pad area around listbox w = urwid.Padding(w, ('fixed left',2), ('fixed right',2)) w = urwid.Filler(w, ('fixed top',1), ('fixed bottom',1)) w = urwid.AttrWrap(w, 'body') - + # "shadow" effect w = urwid.Columns( [w,('fixed', 2, urwid.AttrWrap( urwid.Filler(urwid.Text(('border',' ')), "top") ,'shadow'))]) - w = urwid.Frame( w, footer = + w = urwid.Frame( w, footer = urwid.AttrWrap(urwid.Text(('border',' ')),'shadow')) # outermost border area w = urwid.Padding(w, 'center', width ) w = urwid.Filler(w, 'middle', height ) w = urwid.AttrWrap( w, 'border' ) - + self.view = w @@ -102,10 +102,10 @@ class DialogDisplay: self.loop.run() except DialogExit, e: return self.on_exit( e.args[0] ) - + def on_exit(self, exitcode): return exitcode, "" - + class InputDialogDisplay(DialogDisplay): @@ -113,11 +113,11 @@ class InputDialogDisplay(DialogDisplay): self.edit = urwid.Edit() body = urwid.ListBox([self.edit]) body = urwid.AttrWrap(body, 'selectable','focustext') - + DialogDisplay.__init__(self, text, height, width, body) - + self.frame.set_focus('body') - + def unhandled_key(self, size, k): if k in ('up','page up'): self.frame.set_focus('body') @@ -127,11 +127,11 @@ class InputDialogDisplay(DialogDisplay): # pass enter to the "ok" button self.frame.set_focus('footer') self.view.keypress( size, k ) - + def on_exit(self, exitcode): return exitcode, self.edit.get_edit_text() - + class TextDialogDisplay(DialogDisplay): def __init__(self, file, height, width): l = [] @@ -154,20 +154,20 @@ class TextDialogDisplay(DialogDisplay): class ListDialogDisplay(DialogDisplay): def __init__(self, text, height, width, constr, items, has_default): j = [] - if has_default: + if has_default: k, tail = 3, () - else: + else: k, tail = 2, ("no",) while items: j.append( items[:k] + tail ) items = items[k:] - + l = [] self.items = [] for tag, item, default in j: w = constr( tag, default=="on" ) self.items.append(w) - w = urwid.Columns( [('fixed', 12, w), + w = urwid.Columns( [('fixed', 12, w), urwid.Text(item)], 2 ) w = urwid.AttrWrap(w, 'selectable','focus') l.append(w) @@ -175,9 +175,9 @@ class ListDialogDisplay(DialogDisplay): lb = urwid.ListBox(l) lb = urwid.AttrWrap( lb, "selectable" ) DialogDisplay.__init__(self, text, height, width, lb ) - + self.frame.set_focus('body') - + def unhandled_key(self, size, k): if k in ('up','page up'): self.frame.set_focus('body') @@ -199,14 +199,14 @@ class ListDialogDisplay(DialogDisplay): s = i.get_label() break return exitcode, s - - - + + + class CheckListDialogDisplay(ListDialogDisplay): def on_exit(self, exitcode): """ - Mimic dialog(1)'s --checklist exit. + Mimic dialog(1)'s --checklist exit. Put each checked item in double quotes with a trailing space. """ if exitcode != 0: @@ -250,7 +250,7 @@ def do_checklist(text, height, width, list_height, *items): d = CheckListDialogDisplay( text, height, width, constr, items, True) d.add_buttons([ ("OK", 0), ("Cancel", 1) ]) return d - + def do_inputbox(text, height, width): d = InputDialogDisplay( text, height, width ) d.add_buttons([ ("Exit", 0) ]) @@ -286,22 +286,22 @@ def do_yesno(text, height, width): d.add_buttons([ ("Yes", 0), ("No", 1) ]) return d -MODES={ '--checklist': (do_checklist, +MODES={ '--checklist': (do_checklist, "text height width list-height [ tag item status ] ..."), - '--inputbox': (do_inputbox, + '--inputbox': (do_inputbox, "text height width"), - '--menu': (do_menu, + '--menu': (do_menu, "text height width menu-height [ tag item ] ..."), - '--msgbox': (do_msgbox, + '--msgbox': (do_msgbox, "text height width"), - '--radiolist': (do_radiolist, + '--radiolist': (do_radiolist, "text height width list-height [ tag item status ] ..."), '--textbox': (do_textbox, "file height width"), - '--yesno': (do_yesno, + '--yesno': (do_yesno, "text height width"), } - + def show_usage(): """ @@ -310,7 +310,7 @@ def show_usage(): modelist = [(mode, help) for (mode, (fn, help)) in MODES.items()] modelist.sort() sys.stdout.write( - __doc__ + + __doc__ + "\n".join(["%-15s %s"%(mode,help) for (mode,help) in modelist]) + """ @@ -324,20 +324,20 @@ def main(): if len(sys.argv) < 2 or not MODES.has_key(sys.argv[1]): show_usage() return - + # Create a DialogDisplay instance fn, help = MODES[sys.argv[1]] d = fn( * sys.argv[2:] ) - + # Run it exitcode, exitstring = d.main() - + # Exit if exitstring: sys.stderr.write(exitstring+"\n") - + sys.exit(exitcode) - -if __name__=="__main__": + +if __name__=="__main__": main() diff --git a/examples/edit.py b/examples/edit.py index eed7970..e4fb4b0 100755 --- a/examples/edit.py +++ b/examples/edit.py @@ -37,30 +37,30 @@ import urwid class LineWalker(urwid.ListWalker): """ListWalker-compatible class for lazily reading file contents.""" - + def __init__(self, name): self.file = open(name) self.lines = [] self.focus = 0 - - def get_focus(self): + + def get_focus(self): return self._get_at_pos(self.focus) - + def set_focus(self, focus): self.focus = focus self._modified() - + def get_next(self, start_from): return self._get_at_pos(start_from + 1) - + def get_prev(self, start_from): return self._get_at_pos(start_from - 1) def read_next_line(self): """Read another line from the file.""" - + next_line = self.file.readline() - + if not next_line or next_line[-1:] != '\n': # no newline on last line of file self.file = None @@ -69,22 +69,22 @@ class LineWalker(urwid.ListWalker): next_line = next_line[:-1] expanded = next_line.expandtabs() - + edit = urwid.Edit("", expanded, allow_tab=True) edit.set_edit_pos(0) edit.original_text = next_line self.lines.append(edit) return next_line - - + + def _get_at_pos(self, pos): """Return a widget for the line number passed.""" - + if pos < 0: # line 0 is the start of the file, no more above return None, None - + if len(self.lines) > pos: # we have that line so return it return self.lines[pos], pos @@ -96,12 +96,12 @@ class LineWalker(urwid.ListWalker): assert pos == len(self.lines), "out of order request?" self.read_next_line() - + return self.lines[-1], pos - + def split_focus(self): """Divide the focus edit widget at the cursor location.""" - + focus = self.lines[self.focus] pos = focus.edit_pos edit = urwid.Edit("",focus.edit_text[pos:], allow_tab=True) @@ -117,7 +117,7 @@ class LineWalker(urwid.ListWalker): if above is None: # already at the top return - + focus = self.lines[self.focus] above.set_edit_pos(len(above.edit_text)) above.set_edit_text(above.edit_text + focus.edit_text) @@ -131,7 +131,7 @@ class LineWalker(urwid.ListWalker): if below is None: # already at bottom return - + focus = self.lines[self.focus] focus.set_edit_text(focus.edit_text + below.edit_text) del self.lines[self.focus+1] @@ -143,16 +143,16 @@ class EditDisplay: ('foot','dark cyan', 'dark blue', 'bold'), ('key','light cyan', 'dark blue', 'underline'), ] - + footer_text = ('foot', [ "Text Editor ", ('key', "F5"), " save ", ('key', "F8"), " quit", ]) - + def __init__(self, name): self.save_name = name - self.walker = LineWalker(name) + self.walker = LineWalker(name) self.listbox = urwid.ListBox(self.walker) self.footer = urwid.AttrWrap(urwid.Text(self.footer_text), "foot") @@ -163,7 +163,7 @@ class EditDisplay: self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_keypress) self.loop.run() - + def unhandled_keypress(self, k): """Last resort for keypresses.""" @@ -197,11 +197,11 @@ class EditDisplay: else: return return True - + def save_file(self): """Write the file out to disk.""" - + l = [] walk = self.walker for edit in walk.lines: @@ -210,14 +210,14 @@ class EditDisplay: l.append(edit.original_text) else: l.append(re_tab(edit.edit_text)) - + # then the rest while walk.file is not None: l.append(walk.read_next_line()) - + # write back to disk outfile = open(self.save_name, "w") - + prefix = "" for line in l: outfile.write(prefix + line) @@ -249,7 +249,7 @@ def main(): sys.stderr.write(__doc__) return EditDisplay(name).main() - -if __name__=="__main__": + +if __name__=="__main__": main() diff --git a/examples/fib.py b/examples/fib.py index 7f8d4b7..e3262b4 100755 --- a/examples/fib.py +++ b/examples/fib.py @@ -28,32 +28,32 @@ Features: """ import urwid - + class FibonacciWalker(urwid.ListWalker): """ListWalker-compatible class for browsing fibonacci set. - + positions returned are (value at position-1, value at position) tuples. """ def __init__(self): self.focus = (0L,1L) self.numeric_layout = NumericLayout() - + def _get_at_pos(self, pos): """Return a widget and the position passed.""" return urwid.Text("%d"%pos[1], layout=self.numeric_layout), pos - - def get_focus(self): + + def get_focus(self): return self._get_at_pos(self.focus) - + def set_focus(self, focus): self.focus = focus self._modified() - + def get_next(self, start_from): a, b = start_from focus = b, a+b return self._get_at_pos(focus) - + def get_prev(self, start_from): a, b = start_from focus = b-a, a @@ -66,7 +66,7 @@ def main(): ('key','light cyan', 'black', 'underline'), ('title', 'white', 'black',), ] - + footer_text = [ ('title', "Fibonacci Set Viewer"), " ", ('key', "UP"), ", ", ('key', "DOWN"), ", ", @@ -74,7 +74,7 @@ def main(): " move view ", ('key', "Q"), " exits", ] - + def exit_on_q(input): if input in ('q', 'Q'): raise urwid.ExitMainLoop() @@ -108,5 +108,5 @@ class NumericLayout(urwid.TextLayout): return [[(width, x, x+width)] for x in linestarts] -if __name__=="__main__": +if __name__=="__main__": main() diff --git a/examples/graph.py b/examples/graph.py index a882599..c21c9a9 100755 --- a/examples/graph.py +++ b/examples/graph.py @@ -20,7 +20,7 @@ # Urwid web site: http://excess.org/urwid/ """ -Urwid example demonstrating use of the BarGraph widget and creating a +Urwid example demonstrating use of the BarGraph widget and creating a floating-window appearance. Also shows use of alarms to create timed animation. """ @@ -33,12 +33,12 @@ import time UPDATE_INTERVAL = 0.2 def sin100( x ): - """ + """ A sin function that returns values between 0 and 100 and repeats after x == 100. """ return 50 + 50 * math.sin( x * math.pi / 50 ) - + class GraphModel: """ A class responsible for storing the data that will be displayed @@ -46,14 +46,14 @@ class GraphModel: """ data_max_value = 100 - + def __init__(self): data = [ ('Saw', range(0,100,2)*2), ('Square', [0]*30 + [100]*30), ('Sine 1', [sin100(x) for x in range(100)] ), - ('Sine 2', [(sin100(x) + sin100(x*2))/2 + ('Sine 2', [(sin100(x) + sin100(x*2))/2 for x in range(100)] ), - ('Sine 3', [(sin100(x) + sin100(x*3))/2 + ('Sine 3', [(sin100(x) + sin100(x*3))/2 for x in range(100)] ), ] self.modes = [] @@ -61,13 +61,13 @@ class GraphModel: for m, d in data: self.modes.append(m) self.data[m] = d - + def get_modes(self): return self.modes - + def set_mode(self, m): self.current_mode = m - + def get_data(self, offset, r): """ Return the data in [offset:offset+r], the maximum value @@ -108,11 +108,11 @@ class GraphView(urwid.WidgetWrap): ('pg complete', 'white', 'dark magenta'), ('pg smooth', 'dark magenta','black') ] - + graph_samples_per_bar = 10 graph_num_bars = 5 graph_offset_per_second = 5 - + def __init__(self, controller): self.controller = controller self.started = True @@ -146,7 +146,7 @@ class GraphView(urwid.WidgetWrap): else: l.append([value,0]) self.graph.set_data(l,max_value) - + # also update progress if (o//repeat)&1: # show 100% for first half, 0 for second half @@ -171,8 +171,8 @@ class GraphView(urwid.WidgetWrap): self.started = True self.start_time = time.time() self.controller.animate_graph() - - + + def on_reset_button(self, w): self.offset = 0 self.start_time = time.time() @@ -199,13 +199,13 @@ class GraphView(urwid.WidgetWrap): self.animate_progress = self.progress_bar( state ) self.animate_progress_wrap._w = self.animate_progress self.update_graph( True ) - + def main_shadow(self, w): """Wrap a shadow and background around widget w.""" bg = urwid.AttrWrap(urwid.SolidFill(u"\u2592"), 'screen edge') shadow = urwid.AttrWrap(urwid.SolidFill(u" "), 'main shadow') - + bg = urwid.Overlay( shadow, bg, ('fixed left', 3), ('fixed right', 1), ('fixed top', 2), ('fixed bottom', 1)) @@ -213,7 +213,7 @@ class GraphView(urwid.WidgetWrap): ('fixed left', 2), ('fixed right', 3), ('fixed top', 1), ('fixed bottom', 2)) return w - + def bar_graph(self, smooth=False): satt = None if smooth: @@ -233,7 +233,7 @@ class GraphView(urwid.WidgetWrap): def progress_bar(self, smooth=False): if smooth: - return urwid.ProgressBar('pg normal', 'pg complete', + return urwid.ProgressBar('pg normal', 'pg complete', 0, 1, 'pg smooth') else: return urwid.ProgressBar('pg normal', 'pg complete', @@ -255,11 +255,11 @@ class GraphView(urwid.WidgetWrap): self.on_animate_button( self.animate_button ) self.offset = 0 self.animate_progress = self.progress_bar() - animate_controls = urwid.GridFlow( [ + animate_controls = urwid.GridFlow( [ self.animate_button, self.button("Reset", self.on_reset_button), ], 9, 2, 0, 'center') - + if urwid.get_encoding_mode() == "utf8": unicode_checkbox = urwid.CheckBox( "Enable Unicode Graphics", @@ -267,10 +267,10 @@ class GraphView(urwid.WidgetWrap): else: unicode_checkbox = urwid.Text( "UTF-8 encoding not detected") - + self.animate_progress_wrap = urwid.WidgetWrap( self.animate_progress) - + l = [ urwid.Text("Mode",align="center"), ] + self.mode_buttons + [ urwid.Divider(), @@ -285,7 +285,7 @@ class GraphView(urwid.WidgetWrap): w = urwid.ListBox(urwid.SimpleListWalker(l)) return w - def main_window(self): + def main_window(self): self.graph = self.bar_graph() self.graph_wrap = urwid.WidgetWrap( self.graph ) vline = urwid.AttrWrap( urwid.SolidFill(u'\u2502'), 'line') @@ -299,7 +299,7 @@ class GraphView(urwid.WidgetWrap): w = urwid.AttrWrap(w,'line') w = self.main_shadow(w) return w - + class GraphController: """ @@ -320,17 +320,17 @@ class GraphController: def get_modes(self): """Allow our view access to the list of modes.""" return self.model.get_modes() - + def set_mode(self, m): """Allow our view to set the mode.""" rval = self.model.set_mode( m ) self.view.update_graph(True) return rval - + def get_data(self, offset, range): """Provide data to our view for the graph.""" return self.model.get_data( offset, range ) - + def main(self): self.loop = urwid.MainLoop(self.view, self.view.palette) @@ -347,10 +347,10 @@ class GraphController: if self.animate_alarm: self.loop.remove_alarm(self.animate_alarm) self.animate_alarm = None - + def main(): GraphController().main() - + if '__main__'==__name__: main() diff --git a/examples/input_test.py b/examples/input_test.py index e202162..2c154bc 100755 --- a/examples/input_test.py +++ b/examples/input_test.py @@ -63,9 +63,9 @@ def key_test(): t += ["("] + out + [")"] else: t += ["'",('key',k),"' "] - + rawt = urwid.Text(", ".join(["%d"%r for r in raw])) - + if t: lw.append( urwid.Columns([ @@ -87,8 +87,8 @@ def key_test(): loop.run() finally: screen.tty_signal_keys(*old) - - + + def main(): @@ -96,7 +96,7 @@ def main(): if urwid.web_display.handle_short_request(): return key_test() - + if '__main__'==__name__ or urwid.web_display.is_web_request(): main() diff --git a/examples/lcd_cf635.py b/examples/lcd_cf635.py index 77e8f17..09f66ef 100755 --- a/examples/lcd_cf635.py +++ b/examples/lcd_cf635.py @@ -13,7 +13,7 @@ The crystalfontz 635 has these characters in ROM: ...... ...... ...... 0x11 0xd0 0xbb -By adding the characters in CGRAM below we can use them as part of a +By adding the characters in CGRAM below we can use them as part of a horizontal slider control, selected check box and selected radio button respectively. """ @@ -22,14 +22,14 @@ import sys import urwid.lcd_display CGRAM = """ -...... ...... ...... ...... ..X... ...... ...... ...... -XXXXXX XXXXXX XXXXXX XXXXXX X.XX.. .XXXXX ..XXX. .....X -...... XX.... XXXX.. XXXXXX X.XXX. .X...X .X...X ....XX -...... XX.... XXXX.. XXXXXX X.XXXX .X...X .X...X .X.XX. -...... XX.... XXXX.. XXXXXX X.XXX. .X...X .X...X .XXX.. -XXXXXX XXXXXX XXXXXX XXXXXX X.XX.. .XXXXX ..XXX. ..X... -...... ...... ...... ...... ..X... ...... ...... ...... -...... ...... ...... ...... ...... ...... ...... ...... +...... ...... ...... ...... ..X... ...... ...... ...... +XXXXXX XXXXXX XXXXXX XXXXXX X.XX.. .XXXXX ..XXX. .....X +...... XX.... XXXX.. XXXXXX X.XXX. .X...X .X...X ....XX +...... XX.... XXXX.. XXXXXX X.XXXX .X...X .X...X .X.XX. +...... XX.... XXXX.. XXXXXX X.XXX. .X...X .X...X .XXX.. +XXXXXX XXXXXX XXXXXX XXXXXX X.XX.. .XXXXX ..XXX. ..X... +...... ...... ...... ...... ..X... ...... ...... ...... +...... ...... ...... ...... ...... ...... ...... ...... """ def program_cgram(screen): @@ -94,11 +94,11 @@ class LCDProgressBar(urwid.FlowWidget): filled = urwid.int_scale(self.value, self.range, steps) full_segments = int(filled / (len(self.segments) - 1)) last_char = filled % (len(self.segments) - 1) + 1 - s = (self.segments[-1] * full_segments + + s = (self.segments[-1] * full_segments + self.segments[last_char] + self.segments[0] * (maxcol -full_segments - 1)) return urwid.Text(s).render(size) - + def move_position(self, size, direction): """ Update and return the value one step +ve or -ve, based on @@ -166,7 +166,7 @@ class MenuOption(urwid.Button): ('fixed', 1, urwid.SelectableIcon('\xdf', cursor_position=0)), self._label]) - urwid.connect_signal(self, 'click', + urwid.connect_signal(self, 'click', lambda option: show_menu(submenu)) def keypress(self, size, key): @@ -214,10 +214,10 @@ def build_menus(): apply an exponential transformation to values sent so that apparent brightness increases in a natural way. """ - return lambda value: screen.set_led_pin(index, rg, - [0, 1, 2, 3, 4, 5, 6, 8, 11, 14, 18, + return lambda value: screen.set_led_pin(index, rg, + [0, 1, 2, 3, 4, 5, 6, 8, 11, 14, 18, 23, 29, 38, 48, 61, 79, 100][value]) - + return urwid.Columns([ ('fixed', 2, urwid.Text('%dR' % index)), LCDHorizontalSlider(18, 0, exp_scale_led(0)), @@ -228,15 +228,15 @@ def build_menus(): menu_structure = [ ('Display Settings', [ display_setting('Brightness', 101, screen.set_backlight), - display_setting('Contrast', 76, + display_setting('Contrast', 76, lambda x: screen.set_lcd_contrast(x + 75)), ]), ('Cursor Settings', [ cursor_option('Block', screen.CURSOR_BLINKING_BLOCK), cursor_option('Underscore', screen.CURSOR_UNDERSCORE), - cursor_option('Block + Underscore', + cursor_option('Block + Underscore', screen.CURSOR_BLINKING_BLOCK_UNDERSCORE), - cursor_option('Inverting Block', + cursor_option('Inverting Block', screen.CURSOR_INVERTING_BLINKING_BLOCK), ]), ('LEDs', [ @@ -279,7 +279,7 @@ screen = urwid.lcd_display.CF635Screen(sys.argv[1]) # set up our font program_cgram(screen) loop = urwid.MainLoop(build_menus(), screen=screen) -# FIXME: want screen to know it is in narrow mode, or better yet, +# FIXME: want screen to know it is in narrow mode, or better yet, # do the unicode conversion for us urwid.set_encoding('narrow') diff --git a/examples/palette_test.py b/examples/palette_test.py index 271dd51..820feb5 100755 --- a/examples/palette_test.py +++ b/examples/palette_test.py @@ -34,10 +34,10 @@ CHART_256 = """ brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ yellow_ light_red light_magenta light_blue light_cyan light_green - #00f#06f#08f#0af#0df#0ff black_______ dark_gray___ + #00f#06f#08f#0af#0df#0ff black_______ dark_gray___ #60f#00d#06d#08d#0ad#0dd#0fd light_gray__ white_______ - #80f#60d#00a#06a#08a#0aa#0da#0fa - #a0f#80d#60a#008#068#088#0a8#0d8#0f8 + #80f#60d#00a#06a#08a#0aa#0da#0fa + #a0f#80d#60a#008#068#088#0a8#0d8#0f8 #d0f#a0d#80d#608#006#066#086#0a6#0d6#0f6 #f0f#d0d#a0a#808#606#000#060#080#0a0#0d0#0f0#0f6#0f8#0fa#0fd#0ff #f0d#d0a#a08#806#600#660#680#6a0#6d0#6f0#6f6#6f8#6fa#6fd#6ff#0df @@ -50,29 +50,29 @@ yellow_ light_red light_magenta light_blue light_cyan light_green #86d#66a#68a#6aa#6da #f80#f86#f88#f8a#f8d#f8f#d6f#a0f #a6d#86a#668#688#6a8#6d8 #f60#f66#f68#f6a#f6d#f6f#d0f #d6d#a6a#868#666#686#6a6#6d6#6d8#6da#6dd #f00#f06#f08#f0a#f0d#f0f - #d6a#a68#866#886#8a6#8d6#8d8#8da#8dd#6ad - #d68#a66#a86#aa6#ad6#ad8#ada#add#8ad#68d - #d66#d86#da6#dd6#dd8#dda#ddd#aad#88d#66d g78_g82_g85_g89_g93_g100 + #d6a#a68#866#886#8a6#8d6#8d8#8da#8dd#6ad + #d68#a66#a86#aa6#ad6#ad8#ada#add#8ad#68d + #d66#d86#da6#dd6#dd8#dda#ddd#aad#88d#66d g78_g82_g85_g89_g93_g100 #da6#da8#daa#dad#a8d#86d g52_g58_g62_g66_g70_g74_ #88a#8aa #d86#d88#d8a#d8d#a6d g27_g31_g35_g38_g42_g46_g50_ #a8a#888#8a8#8aa #d66#d68#d6a#d6d g0__g3__g7__g11_g15_g19_g23_ - #a88#aa8#aaa#88a + #a88#aa8#aaa#88a #a88#a8a -""" +""" CHART_88 = """ brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ yellow_ light_red light_magenta light_blue light_cyan light_green - #00f#08f#0cf#0ff black_______ dark_gray___ - #80f#00c#08c#0cc#0fc light_gray__ white_______ + #00f#08f#0cf#0ff black_______ dark_gray___ + #80f#00c#08c#0cc#0fc light_gray__ white_______ #c0f#80c#008#088#0c8#0f8 -#f0f#c0c#808#000#080#0c0#0f0#0f8#0fc#0ff #88c#8cc - #f0c#c08#800#880#8c0#8f0#8f8#8fc#8ff#0cf #c8c#888#8c8#8cc +#f0f#c0c#808#000#080#0c0#0f0#0f8#0fc#0ff #88c#8cc + #f0c#c08#800#880#8c0#8f0#8f8#8fc#8ff#0cf #c8c#888#8c8#8cc #f08#c00#c80#cc0#cf0#cf8#cfc#cff#8cf#08f #c88#cc8#ccc#88c - #f00#f80#fc0#ff0#ff8#ffc#fff#ccf#88f#00f #c88#c8c - #fc0#fc8#fcc#fcf#c8f#80f - #f80#f88#f8c#f8f#c0f g62_g74_g82_g89_g100 + #f00#f80#fc0#ff0#ff8#ffc#fff#ccf#88f#00f #c88#c8c + #fc0#fc8#fcc#fcf#c8f#80f + #f80#f88#f8c#f8f#c0f g62_g74_g82_g89_g100 #f00#f08#f0c#f0f g0__g19_g35_g46_g52 """ @@ -80,7 +80,7 @@ CHART_16 = """ brown__ dark_red_ dark_magenta_ dark_blue_ dark_cyan_ dark_green_ yellow_ light_red light_magenta light_blue light_cyan light_green -black_______ dark_gray___ light_gray__ white_______ +black_______ dark_gray___ light_gray__ white_______ """ ATTR_RE = re.compile("(?P<whitespace>[ \n]*)(?P<entry>[^ \n]+)") @@ -115,7 +115,7 @@ def parse_chart(chart, convert): attr, text = attrtext out.append((attr, text.ljust(elen))) return out - + def foreground_chart(chart, background, colors): """ Create text markup for a foreground colour chart @@ -199,7 +199,7 @@ def main(): if state: is_foreground_chart = chart_radio_buttons[0].state set_mode(colors, is_foreground_chart) - + def mode_rb(text, colors, state=False): # mode radio buttons rb = urwid.RadioButton(mode_radio_buttons, text, state) @@ -209,10 +209,10 @@ def main(): def on_chart_change(rb, state): # handle foreground check box state change set_mode(screen.colors, state) - + def click_exit(button): raise urwid.ExitMainLoop() - + lb.extend([ urwid.AttrMap(urwid.Text("Urwid Palette Test"), 'header'), urwid.AttrMap(urwid.Columns([ @@ -238,7 +238,7 @@ def main(): ]) set_mode(16, True) # displays the chart - + def unhandled_input(key): if key in ('Q','q','esc'): raise urwid.ExitMainLoop() diff --git a/examples/treesample.py b/examples/treesample.py index 5d492c4..f6f771d 100755 --- a/examples/treesample.py +++ b/examples/treesample.py @@ -78,7 +78,7 @@ class ExampleTreeBrowser: ('flag', 'dark gray', 'light gray'), ('error', 'dark red', 'light gray'), ] - + footer_text = [ ('title', "Example Data Browser"), " ", ('key', "UP"), ",", ('key', "DOWN"), ",", @@ -87,7 +87,7 @@ class ExampleTreeBrowser: ('key', "+"), ",", ('key', "-"), " ", ('key', "LEFT"), " ", - ('key', "HOME"), " ", + ('key', "HOME"), " ", ('key', "END"), " ", ('key', "Q"), ] @@ -99,14 +99,14 @@ class ExampleTreeBrowser: self.header = urwid.Text( "" ) self.footer = urwid.AttrWrap( urwid.Text( self.footer_text ), 'foot') - self.view = urwid.Frame( - urwid.AttrWrap( self.listbox, 'body' ), - header=urwid.AttrWrap(self.header, 'head' ), + self.view = urwid.Frame( + urwid.AttrWrap( self.listbox, 'body' ), + header=urwid.AttrWrap(self.header, 'head' ), footer=self.footer ) def main(self): """Run the program.""" - + self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input) self.loop.run() @@ -123,7 +123,7 @@ def get_example_tree(): retval['children'].append({"name":"child " + str(i)}) retval['children'][i]['children']=[] for j in range(10): - retval['children'][i]['children'].append({"name":"grandchild " + + retval['children'][i]['children'].append({"name":"grandchild " + str(i) + "." + str(j)}) return retval @@ -133,6 +133,6 @@ def main(): ExampleTreeBrowser(sample).main() -if __name__=="__main__": +if __name__=="__main__": main() diff --git a/urwid/canvas.py b/urwid/canvas.py index d27e7ab..4a51d3e 100644 --- a/urwid/canvas.py +++ b/urwid/canvas.py @@ -30,13 +30,13 @@ from urwid.compat import bytes class CanvasCache(object): """ Cache for rendered canvases. Automatically populated and - accessed by Widget render() MetaClass magic, cleared by + accessed by Widget render() MetaClass magic, cleared by Widget._invalidate(). Stores weakrefs to the canvas objects, so an external class must maintain a reference for this cache to be effective. - At present the Screen classes store the last topmost canvas - after redrawing the screen, keeping the canvases from being + At present the Screen classes store the last topmost canvas + after redrawing the screen, keeping the canvases from being garbage collected. _widgets[widget] = {(wcls, size, focus): weakref.ref(canvas), ...} @@ -67,7 +67,7 @@ class CanvasCache(object): Collect all child widgets for determining who we depend on. """ - # FIXME: is this recursion necessary? The cache + # FIXME: is this recursion necessary? The cache # invalidating might work with only one level. depends = [] for x, y, c, pos in canv.children: @@ -114,7 +114,7 @@ class CanvasCache(object): cls.hits += 1 # more stats return canv fetch = classmethod(fetch) - + def invalidate(cls, widget): """ Remove all canvases cached for widget. @@ -172,7 +172,7 @@ class CanvasCache(object): clear = classmethod(clear) - + class CanvasError(Exception): pass @@ -198,12 +198,12 @@ class Canvas(object): value1, value2, value3 -- if not None, raise a helpful error: the old Canvas class is now called TextCanvas. """ - if value1 is not None: + if value1 is not None: raise self._renamed_error self._widget_info = None self.coords = {} self.shortcuts = {} - + def finalize(self, widget, size, focus): """ Mark this canvas as finalized (should not be any future @@ -226,7 +226,7 @@ class Canvas(object): def _raise_old_repr_error(self, val=None): raise self._old_repr_error - + def _text_content(self): """ Return the text content of the canvas as a list of strings, @@ -238,8 +238,8 @@ class Canvas(object): text = property(_text_content, _raise_old_repr_error) attr = property(_raise_old_repr_error, _raise_old_repr_error) cs = property(_raise_old_repr_error, _raise_old_repr_error) - - def content(self, trim_left=0, trim_top=0, cols=None, rows=None, + + def content(self, trim_left=0, trim_top=0, cols=None, rows=None, attr=None): raise NotImplementedError() @@ -248,7 +248,7 @@ class Canvas(object): def rows(self): raise NotImplementedError() - + def content_delta(self): raise NotImplementedError() @@ -313,7 +313,7 @@ class TextCanvas(Canvas): """ class for storing rendered text and attributes """ - def __init__(self, text=None, attr=None, cs=None, + def __init__(self, text=None, attr=None, cs=None, cursor=None, maxcol=None, check_width=True): """ text -- list of strings, one for each line @@ -324,7 +324,7 @@ class TextCanvas(Canvas): check_width -- check and fix width of all lines in text """ Canvas.__init__(self) - if text == None: + if text == None: text = [] if check_width: @@ -344,7 +344,7 @@ class TextCanvas(Canvas): else: maxcol = 0 - if attr == None: + if attr == None: attr = [[] for x in range(len(text))] if cs == None: cs = [[] for x in range(len(text))] @@ -352,7 +352,7 @@ class TextCanvas(Canvas): # pad text and attr to maxcol for i in range(len(text)): w = widths[i] - if w > maxcol: + if w > maxcol: raise CanvasError("Canvas text is wider than the maxcol specified \n%r\n%r\n%r"%(maxcol,widths,text)) if w < maxcol: text[i] = text[i] + bytes().rjust(maxcol-w) @@ -361,13 +361,13 @@ class TextCanvas(Canvas): raise CanvasError("Attribute extends beyond text \n%r\n%r" % (text[i],attr[i]) ) if a_gap: rle_append_modify( attr[i], (None, a_gap)) - + cs_gap = len(text[i]) - rle_len( cs[i] ) if cs_gap < 0: raise CanvasError("Character Set extends beyond text \n%r\n%r" % (text[i],cs[i]) ) if cs_gap: rle_append_modify( cs[i], (None, cs_gap)) - + self._attr = attr self._cs = cs self.cursor = cursor @@ -383,7 +383,7 @@ class TextCanvas(Canvas): def cols(self): """Return the screen column width of this canvas.""" return self._maxcol - + def translated_coords(self,dx,dy): """ Return cursor coords shifted by (dx, dy), or None if there @@ -400,33 +400,33 @@ class TextCanvas(Canvas): Return the canvas content as a list of rows where each row is a list of (attr, cs, text) tuples. - trim_left, trim_top, cols, rows may be set by + trim_left, trim_top, cols, rows may be set by CompositeCanvas when rendering a partially obscured canvas. """ maxcol, maxrow = self.cols(), self.rows() - if not cols: + if not cols: cols = maxcol - trim_left if not rows: rows = maxrow - trim_top - + assert trim_left >= 0 and trim_left < maxcol assert cols > 0 and trim_left + cols <= maxcol assert trim_top >=0 and trim_top < maxrow assert rows > 0 and trim_top + rows <= maxrow - + if trim_top or rows < maxrow: text_attr_cs = zip( self._text[trim_top:trim_top+rows], - self._attr[trim_top:trim_top+rows], + self._attr[trim_top:trim_top+rows], self._cs[trim_top:trim_top+rows]) else: text_attr_cs = zip(self._text, self._attr, self._cs) - + for text, a_row, cs_row in text_attr_cs: if trim_left or cols < self._maxcol: text, a_row, cs_row = trim_text_attr_cs( - text, a_row, cs_row, trim_left, + text, a_row, cs_row, trim_left, trim_left + cols) attr_cs = rle_product(a_row, cs_row) i = 0 @@ -437,20 +437,20 @@ class TextCanvas(Canvas): row.append((a, cs, text[i:i+run])) i += run yield row - + def content_delta(self, other): """ Return the differences between other and this canvas. - If other is the same object as self this will return no - differences, otherwise this is the same as calling + If other is the same object as self this will return no + differences, otherwise this is the same as calling content(). """ if other is self: return [self.cols()]*self.rows() return self.content() - + class BlankCanvas(Canvas): @@ -477,10 +477,10 @@ class BlankCanvas(Canvas): def rows(self): raise NotImplementedError("BlankCanvas doesn't know its own size!") - + def content_delta(self): raise NotImplementedError("BlankCanvas doesn't know its own size!") - + blank_canvas = BlankCanvas() @@ -496,14 +496,14 @@ class SolidCanvas(Canvas): self._cs = cs[0][0] self.size = cols, rows self.cursor = None - + def cols(self): return self.size[0] - + def rows(self): return self.size[1] - def content(self, trim_left=0, trim_top=0, cols=None, rows=None, + def content(self, trim_left=0, trim_top=0, cols=None, rows=None, attr=None): if cols is None: cols = self.size[0] @@ -524,7 +524,7 @@ class SolidCanvas(Canvas): if other is self: return [self.cols()]*self.rows() return self.content() - + @@ -538,15 +538,15 @@ class CompositeCanvas(Canvas): if canv is a CompositeCanvas, make a copy of its contents """ - # a "shard" is a (num_rows, list of cviews) tuple, one for + # a "shard" is a (num_rows, list of cviews) tuple, one for # each cview starting in this shard # a "cview" is a tuple that defines a view of a canvas: # (trim_left, trim_top, cols, rows, attr_map, canv) # a "shard tail" is a list of tuples: - # (col_gap, done_rows, content_iter, cview) - + # (col_gap, done_rows, content_iter, cview) + # tuples that define the unfinished cviews that are part of # shards following the first shard. Canvas.__init__(self) @@ -559,7 +559,7 @@ class CompositeCanvas(Canvas): self.shards = canv.shards else: self.shards = [(canv.rows(), [ - (0, 0, canv.cols(), canv.rows(), + (0, 0, canv.cols(), canv.rows(), None, canv)])] self.children = [(0, 0, canv, None)] self.coords.update(canv.coords) @@ -583,7 +583,7 @@ class CompositeCanvas(Canvas): assert isinstance(cols, int) return cols - + def content(self): """ Return the canvas content as a list of rows where each row @@ -598,11 +598,11 @@ class CompositeCanvas(Canvas): for i in range(num_rows): yield shard_body_row(sbody) - # prepare next shard tail + # prepare next shard tail shard_tail = shard_body_tail(num_rows, sbody) - - + + def content_delta(self, other): """ Return the differences between other and this canvas. @@ -621,7 +621,7 @@ class CompositeCanvas(Canvas): # output rows row = [] for i in range(num_rows): - # if whole shard is unchanged, don't keep + # if whole shard is unchanged, don't keep # calling shard_body_row if len(row) != 1 or type(row[0]) != int: row = shard_body_row(sbody) @@ -629,8 +629,8 @@ class CompositeCanvas(Canvas): # prepare next shard tail shard_tail = shard_body_tail(num_rows, sbody) - - + + def trim(self, top, count=None): """Trim lines from the top and/or bottom of canvas. @@ -642,7 +642,7 @@ class CompositeCanvas(Canvas): top, self.rows()) if self.widget_info: raise self._finalized_error - + if top: self.shards = shards_trim_top(self.shards, top) @@ -653,10 +653,10 @@ class CompositeCanvas(Canvas): self.coords = self.translate_coords(0, -top) - + def trim_end(self, end): """Trim lines from the bottom of the canvas. - + end -- number of lines to remove from the end """ assert end > 0, "invalid trim amount %d!"%end @@ -664,14 +664,14 @@ class CompositeCanvas(Canvas): end, self.rows()) if self.widget_info: raise self._finalized_error - + self.shards = shards_trim_rows(self.shards, self.rows() - end) - + def pad_trim_left_right(self, left, right): """ Pad or trim this canvas on the left and right - + values > 0 indicate screen columns to pad values < 0 indicate screen columns to trim """ @@ -721,24 +721,24 @@ class CompositeCanvas(Canvas): [(0,0,cols,top,None,blank_canvas)])] + \ self.shards self.coords = self.translate_coords(0, top) - + if bottom > 0: if orig_shards is self.shards: self.shards = self.shards[:] self.shards.append((bottom, [(0,0,cols,bottom,None,blank_canvas)])) - + def overlay(self, other, left, top ): """Overlay other onto this canvas.""" if self.widget_info: raise self._finalized_error - + width = other.cols() height = other.rows() right = self.cols() - left - width bottom = self.rows() - top - height - + assert right >= 0, "top canvas of overlay not the size expected!" + repr((other.cols(),left,right,width)) assert bottom >= 0, "top canvas of overlay not the size expected!" + repr((other.rows(),top,bottom,height)) @@ -764,13 +764,13 @@ class CompositeCanvas(Canvas): if not self.rows(): middle_shards = [] elif left or right: - middle_shards = shards_join(left_shards + + middle_shards = shards_join(left_shards + [other.shards] + right_shards) else: middle_shards = other.shards self.shards = top_shards + middle_shards + bottom_shards - + self.coords.update(other.translate_coords(left, top)) @@ -780,7 +780,7 @@ class CompositeCanvas(Canvas): attribute currently set to None, leaving other attributes intact.""" self.fill_attr_apply({None:a}) - + def fill_attr_apply(self, mapping): """ Apply an attribute-mapping dictionary to the canvas. @@ -796,7 +796,7 @@ class CompositeCanvas(Canvas): for cv in original_cviews: # cv[4] == attr_map if cv[4] is None: - new_cviews.append(cv[:4] + + new_cviews.append(cv[:4] + (mapping,) + cv[5:]) else: combined = dict(mapping) @@ -859,7 +859,7 @@ def shard_body_tail(num_rows, sbody): def shards_delta(shards, other_shards): """ - Yield shards1 with cviews that are the same as shards2 + Yield shards1 with cviews that are the same as shards2 having canv = None. """ other_shards_iter = iter(other_shards) @@ -910,11 +910,11 @@ def shard_cviews_delta(cviews, other_cviews): def shard_body(cviews, shard_tail, create_iter=True, iter_default=None): """ - Return a list of (done_rows, content_iter, cview) tuples for + Return a list of (done_rows, content_iter, cview) tuples for this shard and shard tail. - If a canvas in cviews is None (eg. when unchanged from - shard_cviews_delta()) or if create_iter is False then no + If a canvas in cviews is None (eg. when unchanged from + shard_cviews_delta()) or if create_iter is False then no iterator is created for content_iter. iter_default is the value used for content_iter when no iterator @@ -938,7 +938,7 @@ def shard_body(cviews, shard_tail, create_iter=True, iter_default=None): raise CanvasError("cviews overflow gaps in" " shard_tail!") if create_iter and canv: - new_iter = canv.content(trim_left, trim_top, + new_iter = canv.content(trim_left, trim_top, cols, rows, attr_map) else: new_iter = iter_default @@ -948,7 +948,7 @@ def shard_body(cviews, shard_tail, create_iter=True, iter_default=None): (trim_left, trim_top, cols, rows, attr_map, canv) = \ cview[:6] if create_iter and canv: - new_iter = canv.content(trim_left, trim_top, cols, rows, + new_iter = canv.content(trim_left, trim_top, cols, rows, attr_map) else: new_iter = iter_default @@ -973,19 +973,19 @@ def shards_trim_top(shards, top): top -= num_rows else: raise CanvasError("tried to trim shards out of existence") - + sbody = shard_body(cviews, shard_tail, False) shard_tail = shard_body_tail(num_rows, sbody) # trim the top of this shard new_sbody = [] for done_rows, content_iter, cv in sbody: - new_sbody.append((0, content_iter, + new_sbody.append((0, content_iter, cview_trim_top(cv, done_rows+top))) sbody = new_sbody - - new_shards = [(num_rows-top, + + new_shards = [(num_rows-top, [cv for done_rows, content_iter, cv in sbody])] - + # write out the rest of the shards new_shards.extend(shard_iter) @@ -1005,7 +1005,7 @@ def shards_trim_rows(shards, keep_rows): new_cviews = [] for cv in cviews: if cv[3] + done_rows > keep_rows: - new_cviews.append(cview_trim_rows(cv, + new_cviews.append(cview_trim_rows(cv, keep_rows - done_rows)) else: new_cviews.append(cv) @@ -1214,13 +1214,13 @@ def apply_text_layout(text, attr, ls, maxcol): t = [] a = [] c = [] - + class AttrWalk: pass aw = AttrWalk aw.k = 0 # counter for moving through elements of a aw.off = 0 # current offset into text of attr[ak] - + def arange( start_offs, end_offs ): """Return an attribute list for the range of text specified.""" if start_offs < aw.off: @@ -1246,19 +1246,19 @@ def apply_text_layout(text, attr, ls, maxcol): aw.off += run return o - + for line_layout in ls: # trim the line to fit within maxcol line_layout = trim_line( line_layout, text, 0, maxcol ) - + line = [] linea = [] linec = [] - + def attrrange( start_offs, end_offs, destw ): """ Add attributes based on attributes between - start_offs and end_offs. + start_offs and end_offs. """ if start_offs == end_offs: [(at,run)] = arange(start_offs,end_offs) @@ -1277,12 +1277,12 @@ def apply_text_layout(text, attr, ls, maxcol): tseg = text[o:o+run] tseg, cs = apply_target_encoding( tseg ) segw = rle_len(cs) - + rle_append_modify( linea, ( at, segw )) o += run destw -= segw - - + + for seg in line_layout: #if seg is None: assert 0, ls s = LayoutSegment(seg) diff --git a/urwid/container.py b/urwid/container.py index aa81614..24dddf9 100755 --- a/urwid/container.py +++ b/urwid/container.py @@ -130,7 +130,7 @@ class GridFlow(WidgetWrap, WidgetContainerMixin, WidgetContainerListContentsMixi """ The GridFlow widget is a flow widget that renders all the widgets it contains the same width and it arranges them from left to right and top to - bottom. + bottom. """ def sizing(self): return frozenset([FLOW]) diff --git a/urwid/curses_display.py b/urwid/curses_display.py index b7f1cea..758d621 100755 --- a/urwid/curses_display.py +++ b/urwid/curses_display.py @@ -126,13 +126,13 @@ class Screen(BaseScreen, RealTerminal): curses.meta(1) curses.halfdelay(10) # use set_input_timeouts to adjust self.s.keypad(0) - + if not self._signal_keys_set: self._old_signal_keys = self.tty_signal_keys() super(Screen, self).start() - + def stop(self): """ Restore the screen. @@ -145,20 +145,20 @@ class Screen(BaseScreen, RealTerminal): curses.endwin() except _curses.error: pass # don't block original error with curses error - + if self._old_signal_keys: self.tty_signal_keys(*self._old_signal_keys) super(Screen, self).stop() - + def run_wrapper(self,fn): """Call fn in fullscreen mode. Return to normal on exit. - + This function should be called to wrap your main program loop. Exception tracebacks will be displayed in normal mode. """ - + try: self.start() return fn() @@ -185,7 +185,7 @@ class Screen(BaseScreen, RealTerminal): curses.init_pair(bg * 8 + 7 - fg, fg, bg) def _curs_set(self,x): - if self.cursor_state== "fixed" or x == self.cursor_state: + if self.cursor_state== "fixed" or x == self.cursor_state: return try: curses.curs_set(x) @@ -193,12 +193,12 @@ class Screen(BaseScreen, RealTerminal): except _curses.error: self.cursor_state = "fixed" - + def _clear(self): self.s.clear() self.s.refresh() - - + + def _getch(self, wait_tenths): if wait_tenths==0: return self._getch_nodelay() @@ -208,7 +208,7 @@ class Screen(BaseScreen, RealTerminal): curses.halfdelay(wait_tenths) self.s.nodelay(0) return self.s.getch() - + def _getch_nodelay(self): self.s.nodelay(1) while 1: @@ -218,17 +218,17 @@ class Screen(BaseScreen, RealTerminal): break except _curses.error: pass - + return self.s.getch() - def set_input_timeouts(self, max_wait=None, complete_wait=0.1, + def set_input_timeouts(self, max_wait=None, complete_wait=0.1, resize_wait=0.1): """ Set the get_input timeout values. All values have a granularity of 0.1s, ie. any value between 0.15 and 0.05 will be treated as 0.1 and any value less than 0.05 will be treated as 0. The maximum timeout value for this module is 25.5 seconds. - + max_wait -- amount of time in seconds to wait for input when there is no input pending, wait forever if None complete_wait -- amount of time in seconds to wait when @@ -295,14 +295,14 @@ class Screen(BaseScreen, RealTerminal): keys, raw = self._get_input( self.max_tenths ) # Avoid pegging CPU at 100% when slowly resizing, and work - # around a bug with some braindead curses implementations that - # return "no key" between "window resize" commands + # around a bug with some braindead curses implementations that + # return "no key" between "window resize" commands if keys==['window resize'] and self.prev_input_resize: while True: keys, raw2 = self._get_input(self.resize_tenths) raw += raw2 if not keys: - keys, raw2 = self._get_input( + keys, raw2 = self._get_input( self.resize_tenths) raw += raw2 if keys!=['window resize']: @@ -310,33 +310,33 @@ class Screen(BaseScreen, RealTerminal): if keys[-1:]!=['window resize']: keys.append('window resize') - + if keys==['window resize']: self.prev_input_resize = 2 elif self.prev_input_resize == 2 and not keys: self.prev_input_resize = 1 else: self.prev_input_resize = 0 - + if raw_keys: return keys, raw return keys - - + + def _get_input(self, wait_tenths): - # this works around a strange curses bug with window resizing + # this works around a strange curses bug with window resizing # not being reported correctly with repeated calls to this # function without a doupdate call in between - curses.doupdate() - + curses.doupdate() + key = self._getch(wait_tenths) resize = False raw = [] keys = [] - + while key >= 0: raw.append(key) - if key==KEY_RESIZE: + if key==KEY_RESIZE: resize = True elif key==KEY_MOUSE: keys += self._encode_mouse_event() @@ -345,7 +345,7 @@ class Screen(BaseScreen, RealTerminal): key = self._getch_nodelay() processed = [] - + try: while keys: run, keys = escape.process_keyqueue(keys, True) @@ -354,7 +354,7 @@ class Screen(BaseScreen, RealTerminal): key = self._getch(self.complete_tenths) while key >= 0: raw.append(key) - if key==KEY_RESIZE: + if key==KEY_RESIZE: resize = True elif key==KEY_MOUSE: keys += self._encode_mouse_event() @@ -369,23 +369,23 @@ class Screen(BaseScreen, RealTerminal): processed.append('window resize') return processed, raw - - + + def _encode_mouse_event(self): # convert to escape sequence last = next = self.last_bstate (id,x,y,z,bstate) = curses.getmouse() - + mod = 0 if bstate & curses.BUTTON_SHIFT: mod |= 4 if bstate & curses.BUTTON_ALT: mod |= 8 if bstate & curses.BUTTON_CTRL: mod |= 16 - + l = [] def append_button( b ): b |= mod l.extend([ 27, ord('['), ord('M'), b+32, x+33, y+33 ]) - + if bstate & curses.BUTTON1_PRESSED and last & 1 == 0: append_button( 0 ) next |= 1 @@ -410,7 +410,7 @@ class Screen(BaseScreen, RealTerminal): if bstate & curses.BUTTON4_RELEASED and last & 8: append_button( 64 + escape.MOUSE_RELEASE_FLAG ) next &= ~ 8 - + if bstate & curses.BUTTON1_DOUBLE_CLICKED: append_button( 0 + escape.MOUSE_MULTIPLE_CLICK_FLAG ) if bstate & curses.BUTTON2_DOUBLE_CLICKED: @@ -431,7 +431,7 @@ class Screen(BaseScreen, RealTerminal): self.last_bstate = next return l - + def _dbg_instr(self): # messy input string (intended for debugging) curses.echo() @@ -440,17 +440,17 @@ class Screen(BaseScreen, RealTerminal): str = self.s.getstr() curses.noecho() return str - + def _dbg_out(self,str): # messy output function (intended for debugging) self.s.clrtoeol() self.s.addstr(str) self.s.refresh() self._curs_set(1) - + def _dbg_query(self,question): # messy query (intended for debugging) self._dbg_out(question) return self._dbg_instr() - + def _dbg_refresh(self): self.s.refresh() @@ -460,7 +460,7 @@ class Screen(BaseScreen, RealTerminal): """Return the terminal dimensions (num columns, num rows).""" rows,cols = self.s.getmaxyx() return cols,rows - + def _setattr(self, a): if a is None: @@ -502,19 +502,19 @@ class Screen(BaseScreen, RealTerminal): def draw_screen(self, (cols, rows), r ): """Paint screen with rendered canvas.""" assert self._started - + assert r.rows() == rows, "canvas size and passed size don't match" - + y = -1 for row in r.content(): y += 1 try: self.s.move( y, 0 ) except _curses.error: - # terminal shrunk? + # terminal shrunk? # move failed so stop rendering. return - + first = True lasta = None nr = 0 @@ -558,7 +558,7 @@ class Screen(BaseScreen, RealTerminal): else: self._curs_set(0) self.s.move(0,0) - + self.s.refresh() self.keep_cache_alive_link = r @@ -585,7 +585,7 @@ class _test: (c+" on light gray",c,'light gray', 'standout'), ]) self.ui.run_wrapper(self.run) - + def run(self): class FakeRender: pass r = FakeRender() @@ -593,12 +593,12 @@ class _test: attr = [[],[]] r.coords = {} r.cursor = None - + for c in self.l: t = "" a = [] for p in c+" on black",c+" on dark blue",c+" on light gray": - + a.append((p,27)) t=t+ (p+27*" ")[:27] text.append( t ) @@ -624,13 +624,13 @@ class _test: t += "'"+k + "' " a += [(None,1), ('yellow on dark blue',len(k)), (None,2)] - + text.append(t + ": "+ repr(raw)) attr.append(a) text = text[-rows:] attr = attr[-rows:] - - + + if '__main__'==__name__: diff --git a/urwid/display_common.py b/urwid/display_common.py index cbe433f..789442f 100755 --- a/urwid/display_common.py +++ b/urwid/display_common.py @@ -67,11 +67,11 @@ _BASIC_COLOR_VALUES = [(0,0,0), (205, 0, 0), (0, 205, 0), (205, 205, 0), (0x5c, 0x5c, 0xff), (255, 0, 255), (0, 255, 255), (255, 255, 255)] _COLOR_VALUES_256 = (_BASIC_COLOR_VALUES + - [(r, g, b) for r in _CUBE_STEPS_256 for g in _CUBE_STEPS_256 + [(r, g, b) for r in _CUBE_STEPS_256 for g in _CUBE_STEPS_256 for b in _CUBE_STEPS_256] + [(gr, gr, gr) for gr in _GRAY_STEPS_256]) _COLOR_VALUES_88 = (_BASIC_COLOR_VALUES + - [(r, g, b) for r in _CUBE_STEPS_88 for g in _CUBE_STEPS_88 + [(r, g, b) for r in _CUBE_STEPS_88 for g in _CUBE_STEPS_88 for b in _CUBE_STEPS_88] + [(gr, gr, gr) for gr in _GRAY_STEPS_88]) @@ -142,10 +142,10 @@ def _value_lookup_table(values, size): """ Generate a lookup table for finding the closest item in values. Lookup returns (index into values)+1 - + values -- list of values in ascending order, all < size size -- size of lookup table and maximum value - + >>> _value_lookup_table([0, 7, 9], 10) [0, 0, 0, 0, 1, 1, 1, 1, 2, 2] """ @@ -181,11 +181,11 @@ _GRAY_88_LOOKUP_101 = [_GRAY_88_LOOKUP[int_scale(n, 101, 0x100)] for n in range(101)] -# The functions _gray_num_256() and _gray_num_88() do not include the gray -# values from the color cube so that the gray steps are an even width. -# The color cube grays are available by using the rgb functions. Pure -# white and black are taken from the color cube, since the gray range does -# not include them, and the basic colors are more likely to have been +# The functions _gray_num_256() and _gray_num_88() do not include the gray +# values from the color cube so that the gray steps are an even width. +# The color cube grays are available by using the rgb functions. Pure +# white and black are taken from the color cube, since the gray range does +# not include them, and the basic colors are more likely to have been # customized by an end-user. @@ -262,7 +262,7 @@ def _color_desc_88(num): 0..15 -> 'h0'..'h15' basic colors (as high-colors) 16..79 -> '#000'..'#fff' color cube colors 80..87 -> 'g18'..'g90' grays - + >>> _color_desc_88(15) 'h15' >>> _color_desc_88(16) @@ -295,7 +295,7 @@ def _parse_color_256(desc): '#000'..'#fff' -> 16..231 color cube colors 'g0'..'g100' -> 16, 232..255, 231 grays and color cube black/white 'g#00'..'g#ff' -> 16, 232...255, 231 gray and color cube black/white - + Returns None if desc is invalid. >>> _parse_color_256('h142') @@ -363,9 +363,9 @@ def _parse_color_88(desc): '#000'..'#fff' -> 16..79 color cube colors 'g0'..'g100' -> 16, 80..87, 79 grays and color cube black/white 'g#00'..'g#ff' -> 16, 80...87, 79 gray and color cube black/white - + Returns None if desc is invalid. - + >>> _parse_color_88('h142') >>> _parse_color_88('h42') 42 @@ -438,7 +438,7 @@ class AttrSpec(object): 'default' (use the terminal's default foreground), 'black', 'dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray', 'dark gray', - 'light red', 'light green', 'yellow', 'light blue', + 'light red', 'light green', 'yellow', 'light blue', 'light magenta', 'light cyan', 'white' High-color example values: @@ -470,7 +470,7 @@ class AttrSpec(object): colors -- the maximum colors available for the specification - Valid values include: 1, 16, 88 and 256. High-color + Valid values include: 1, 16, 88 and 256. High-color values are only usable with 88 or 256 colors. With 1 color only the foreground settings may be used. @@ -498,7 +498,7 @@ class AttrSpec(object): foreground_number = property(lambda s: s._value & _FG_COLOR_MASK) background_basic = property(lambda s: s._value & _BG_BASIC_COLOR != 0) background_high = property(lambda s: s._value & _BG_HIGH_COLOR != 0) - background_number = property(lambda s: (s._value & _BG_COLOR_MASK) + background_number = property(lambda s: (s._value & _BG_COLOR_MASK) >> _BG_SHIFT) bold = property(lambda s: s._value & _BOLD != 0) underline = property(lambda s: s._value & _UNDERLINE != 0) @@ -556,7 +556,7 @@ class AttrSpec(object): # parse and store "settings"/attributes in flags if flags & _ATTRIBUTES[part]: raise AttrSpecError(("Setting %s specified more than" + - "once in foreground (%s)") % (repr(part), + "once in foreground (%s)") % (repr(part), repr(foreground))) flags |= _ATTRIBUTES[part] continue @@ -595,7 +595,7 @@ class AttrSpec(object): if self._value & _HIGH_88_COLOR: return _color_desc_88(self.background_number) return _color_desc_256(self.background_number) - + def _set_background(self, background): flags = 0 if background in ('', 'default'): @@ -621,7 +621,7 @@ class AttrSpec(object): Return (fg_red, fg_green, fg_blue, bg_red, bg_green, bg_blue) color components. Each component is in the range 0-255. Values are taken from the XTerm defaults and may not exactly match the user's terminal. - + If the foreground or background is 'default' then all their compenents will be returned as None. @@ -653,8 +653,8 @@ class RealTerminal(object): super(RealTerminal,self).__init__() self._signal_keys_set = False self._old_signal_keys = None - - def tty_signal_keys(self, intr=None, quit=None, start=None, + + def tty_signal_keys(self, intr=None, quit=None, start=None, stop=None, susp=None, fileno=None): """ Read and/or set the tty's signal character settings. @@ -679,25 +679,25 @@ class RealTerminal(object): skeys = (sattr[termios.VINTR], sattr[termios.VQUIT], sattr[termios.VSTART], sattr[termios.VSTOP], sattr[termios.VSUSP]) - + if intr == 'undefined': intr = 0 if quit == 'undefined': quit = 0 if start == 'undefined': start = 0 if stop == 'undefined': stop = 0 if susp == 'undefined': susp = 0 - + if intr is not None: tattr[6][termios.VINTR] = intr if quit is not None: tattr[6][termios.VQUIT] = quit if start is not None: tattr[6][termios.VSTART] = start if stop is not None: tattr[6][termios.VSTOP] = stop if susp is not None: tattr[6][termios.VSUSP] = susp - + if intr is not None or quit is not None or \ start is not None or stop is not None or \ susp is not None: termios.tcsetattr(fileno, termios.TCSADRAIN, tattr) self._signal_keys_set = True - + return skeys diff --git a/urwid/escape.py b/urwid/escape.py index bf34921..077e38e 100644 --- a/urwid/escape.py +++ b/urwid/escape.py @@ -63,7 +63,7 @@ class MoreInputRequired(Exception): def escape_modifier( digit ): mode = ord(digit) - ord("1") return "shift "*(mode&1) + "meta "*((mode&2)//2) + "ctrl "*((mode&4)//4) - + input_sequences = [ ('[A','up'),('[B','down'),('[C','right'),('[D','left'), @@ -74,7 +74,7 @@ input_sequences = [ ('[7~','home'),('[8~','end'), ('[[A','f1'),('[[B','f2'),('[[C','f3'),('[[D','f4'),('[[E','f5'), - + ('[11~','f1'),('[12~','f2'),('[13~','f3'),('[14~','f4'), ('[15~','f5'),('[17~','f6'),('[18~','f7'),('[19~','f8'), ('[20~','f9'),('[21~','f10'),('[23~','f11'),('[24~','f12'), @@ -111,7 +111,7 @@ input_sequences = [ ("O"+digit+letter, escape_modifier(digit) + key) for digit in "12345678" for letter,key in zip("PQRS",('f1','f2','f3','f4')) -] + [ +] + [ # modified F1-F13 keys -- [XX;#~ form ("["+str(num)+";"+digit+"~", escape_modifier(digit) + key) for digit in "12345678" @@ -133,11 +133,11 @@ class KeyqueueTrie(object): for s, result in sequences: assert type(result) != dict self.add(self.data, s, result) - + def add(self, root, s, result): assert type(root) == dict, "trie conflict detected" assert len(s) > 0, "trie conflict detected" - + if root.has_key(ord(s[0])): return self.add(root[ord(s[0])], s[1:], result) if len(s)>1: @@ -145,17 +145,17 @@ class KeyqueueTrie(object): root[ord(s[0])] = d return self.add(d, s[1:], result) root[ord(s)] = result - + def get(self, keys, more_available): result = self.get_recurse(self.data, keys, more_available) if not result: result = self.read_cursor_position(keys, more_available) return result - + def get_recurse(self, root, keys, more_available): if type(root) != dict: if root == "mouse": - return self.read_mouse_info(keys, + return self.read_mouse_info(keys, more_available) return (root, keys) if not keys: @@ -166,16 +166,16 @@ class KeyqueueTrie(object): if not root.has_key(keys[0]): return None return self.get_recurse(root[keys[0]], keys[1:], more_available) - + def read_mouse_info(self, keys, more_available): if len(keys) < 3: if more_available: raise MoreInputRequired() return None - + b = keys[0] - 32 x, y = (keys[1] - 33)%256, (keys[2] - 33)%256 # supports 0-255 - + prefix = "" if b & 4: prefix = prefix + "shift " if b & 8: prefix = prefix + "meta " @@ -186,7 +186,7 @@ class KeyqueueTrie(object): # 0->1, 1->2, 2->3, 64->4, 65->5 button = ((b&64)/64*3) + (b & 3) + 1 - if b & 3 == 3: + if b & 3 == 3: action = "release" button = 0 elif b & MOUSE_RELEASE_FLAG: @@ -199,7 +199,7 @@ class KeyqueueTrie(object): action = "press" return ( (prefix + "mouse " + action, button, x, y), keys[3:] ) - + def read_cursor_position(self, keys, more_available): """ Interpret cursor position information being sent by the @@ -252,8 +252,8 @@ class KeyqueueTrie(object): # This is added to button value to signal mouse release by curses_display -# and raw_display when we know which button was released. NON-STANDARD -MOUSE_RELEASE_FLAG = 2048 +# and raw_display when we know which button was released. NON-STANDARD +MOUSE_RELEASE_FLAG = 2048 # This 2-bit mask is used to check if the mouse release from curses or gpm # is a double or triple release. 00 means single click, 01 double, @@ -308,10 +308,10 @@ _keyconv = { def process_keyqueue(codes, more_available): """ codes -- list of key codes - more_available -- if True then raise MoreInputRequired when in the - middle of a character sequence (escape/utf8/wide) and caller + more_available -- if True then raise MoreInputRequired when in the + middle of a character sequence (escape/utf8/wide) and caller will attempt to send more key codes on the next call. - + returns (list of input, list of remaining key codes). """ code = codes[0] @@ -324,10 +324,10 @@ def process_keyqueue(codes, more_available): return ["ctrl %s" % chr(ord('a')+code-1)], codes[1:] if code >27 and code <32: return ["ctrl %s" % chr(ord('A')+code-1)], codes[1:] - + em = str_util.get_byte_encoding() - - if (em == 'wide' and code < 256 and + + if (em == 'wide' and code < 256 and within_double_byte(chr(code),0,0)): if not codes[1:]: if more_available: @@ -363,7 +363,7 @@ def process_keyqueue(codes, more_available): return [s.decode("utf-8")], codes[need_more+1:] except UnicodeDecodeError: return ["<%d>"%code], codes[1:] - + if code >127 and code <256: key = chr(code) return [key], codes[1:] @@ -371,19 +371,19 @@ def process_keyqueue(codes, more_available): return ["<%d>"%code], codes[1:] result = input_trie.get(codes[1:], more_available) - + if result is not None: result, remaining_codes = result return [result], remaining_codes - + if codes[1:]: # Meta keys -- ESC+Key form - run, remaining_codes = process_keyqueue(codes[1:], + run, remaining_codes = process_keyqueue(codes[1:], more_available) if run[0] == "esc" or run[0].find("meta ") >= 0: return ['esc']+run, remaining_codes return ['meta '+run[0]]+run[1:], remaining_codes - + return ['esc'], codes[1:] diff --git a/urwid/font.py b/urwid/font.py index c6362ae..0a3261b 100755 --- a/urwid/font.py +++ b/urwid/font.py @@ -65,11 +65,11 @@ def separate_glyphs(gdata, height): j += 1 assert y + fill == end_col - start_col, \ repr((y, fill, end_col)) - + segment = l[jl[k]:j] if not SAFE_ASCII_DEC_SPECIAL_RE.match(segment): utf8_required = True - + out.append(segment + " " * fill) jl[k] = j @@ -98,7 +98,7 @@ class Font(object): self.utf8_required = False for gdata in self.data: self.add_glyphs(gdata) - + def add_glyphs(self, gdata): d, utf8_required = separate_glyphs(gdata, self.height) @@ -114,7 +114,7 @@ class Font(object): if self.char.has_key(c): return self.char[c][0] return 0 - + def char_data(self, c): return self.char[c][1] @@ -128,13 +128,13 @@ class Font(object): t, cs = apply_target_encoding(d) tl.append(t) csl.append(cs) - canv = TextCanvas(tl, None, csl, maxcol=width, + canv = TextCanvas(tl, None, csl, maxcol=width, check_width=False) self.canvas[c] = canv return canv - - + + #safe_palette = u"┘┐┌└┼─├┤┴┬│" #more_palette = u"═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬○" #block_palette = u"▄#█#▀#▌#▐#▖#▗#▘#▙#▚#▛#▜#▝#▞#▟" @@ -150,7 +150,7 @@ class Thin3x3Font(Font): """, ur""" "###$$$%%%'*++,--.///:;==???[[\\\]]^__` " ┼┼┌┼┐O /' /.. _┌─┐┌ \ ┐^ ` - ┼┼└┼┐ / * ┼ ─ / ., _ ┌┘│ \ │ + ┼┼└┼┐ / * ┼ ─ / ., _ ┌┘│ \ │ └┼┘/ O , ./ . └ \ ┘ ── """] add_font("Thin 3x3",Thin3x3Font) @@ -169,57 +169,57 @@ class HalfBlock5x4Font(Font): height = 4 data = [u""" 00000111112222233333444445555566666777778888899999 !! -▄▀▀▄ ▄█ ▄▀▀▄ ▄▀▀▄ ▄ █ █▀▀▀ ▄▀▀ ▀▀▀█ ▄▀▀▄ ▄▀▀▄ █ -█ █ █ ▄▀ ▄▀ █▄▄█ █▄▄ █▄▄ ▐▌ ▀▄▄▀ ▀▄▄█ █ -█ █ █ ▄▀ ▄ █ █ █ █ █ █ █ █ █ ▀ - ▀▀ ▀▀▀ ▀▀▀▀ ▀▀ ▀ ▀▀▀ ▀▀ ▀ ▀▀ ▀▀ ▀ +▄▀▀▄ ▄█ ▄▀▀▄ ▄▀▀▄ ▄ █ █▀▀▀ ▄▀▀ ▀▀▀█ ▄▀▀▄ ▄▀▀▄ █ +█ █ █ ▄▀ ▄▀ █▄▄█ █▄▄ █▄▄ ▐▌ ▀▄▄▀ ▀▄▄█ █ +█ █ █ ▄▀ ▄ █ █ █ █ █ █ █ █ █ ▀ + ▀▀ ▀▀▀ ▀▀▀▀ ▀▀ ▀ ▀▀▀ ▀▀ ▀ ▀▀ ▀▀ ▀ """, u''' """######$$$$$$%%%%%&&&&&((()))******++++++,,,-----..////:::;; -█▐▌ █ █ ▄▀█▀▄ ▐▌▐▌ ▄▀▄ █ █ ▄ ▄ ▄ ▐▌ - ▀█▀█▀ ▀▄█▄ █ ▀▄▀ ▐▌ ▐▌ ▄▄█▄▄ ▄▄█▄▄ ▄▄▄▄ █ ▀ ▀ - ▀█▀█▀ ▄ █ █ ▐▌▄ █ ▀▄▌▐▌ ▐▌ ▄▀▄ █ ▐▌ ▀ ▄▀ - ▀ ▀ ▀▀▀ ▀ ▀ ▀▀ ▀ ▀ ▄▀ ▀ ▀ +█▐▌ █ █ ▄▀█▀▄ ▐▌▐▌ ▄▀▄ █ █ ▄ ▄ ▄ ▐▌ + ▀█▀█▀ ▀▄█▄ █ ▀▄▀ ▐▌ ▐▌ ▄▄█▄▄ ▄▄█▄▄ ▄▄▄▄ █ ▀ ▀ + ▀█▀█▀ ▄ █ █ ▐▌▄ █ ▀▄▌▐▌ ▐▌ ▄▀▄ █ ▐▌ ▀ ▄▀ + ▀ ▀ ▀▀▀ ▀ ▀ ▀▀ ▀ ▀ ▄▀ ▀ ▀ ''', ur""" <<<<<=====>>>>>?????@@@@@@[[[[\\\\]]]]^^^^____```{{{{||}}}}~~~~''´´´ - ▄▀ ▀▄ ▄▀▀▄ ▄▀▀▀▄ █▀▀ ▐▌ ▀▀█ ▄▀▄ ▀▄ ▄▀ █ ▀▄ ▄ █ ▄▀ -▄▀ ▀▀▀▀ ▀▄ ▄▀ █ █▀█ █ █ █ ▄▀ █ ▀▄ ▐▐▌▌ - ▀▄ ▀▀▀▀ ▄▀ ▀ █ ▀▀▀ █ ▐▌ █ █ █ █ ▀ - ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀▀ ▀ ▀ ▀ + ▄▀ ▀▄ ▄▀▀▄ ▄▀▀▀▄ █▀▀ ▐▌ ▀▀█ ▄▀▄ ▀▄ ▄▀ █ ▀▄ ▄ █ ▄▀ +▄▀ ▀▀▀▀ ▀▄ ▄▀ █ █▀█ █ █ █ ▄▀ █ ▀▄ ▐▐▌▌ + ▀▄ ▀▀▀▀ ▄▀ ▀ █ ▀▀▀ █ ▐▌ █ █ █ █ ▀ + ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀▀ ▀ ▀ ▀ """, u''' AAAAABBBBBCCCCCDDDDDEEEEEFFFFFGGGGGHHHHHIIJJJJJKKKKK -▄▀▀▄ █▀▀▄ ▄▀▀▄ █▀▀▄ █▀▀▀ █▀▀▀ ▄▀▀▄ █ █ █ █ █ █ -█▄▄█ █▄▄▀ █ █ █ █▄▄ █▄▄ █ █▄▄█ █ █ █▄▀ -█ █ █ █ █ ▄ █ █ █ █ █ ▀█ █ █ █ ▄ █ █ ▀▄ -▀ ▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀ +▄▀▀▄ █▀▀▄ ▄▀▀▄ █▀▀▄ █▀▀▀ █▀▀▀ ▄▀▀▄ █ █ █ █ █ █ +█▄▄█ █▄▄▀ █ █ █ █▄▄ █▄▄ █ █▄▄█ █ █ █▄▀ +█ █ █ █ █ ▄ █ █ █ █ █ ▀█ █ █ █ ▄ █ █ ▀▄ +▀ ▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ''', u''' LLLLLMMMMMMNNNNNOOOOOPPPPPQQQQQRRRRRSSSSSTTTTT █ █▄ ▄█ ██ █ ▄▀▀▄ █▀▀▄ ▄▀▀▄ █▀▀▄ ▄▀▀▄ ▀▀█▀▀ -█ █ ▀ █ █▐▌█ █ █ █▄▄▀ █ █ █▄▄▀ ▀▄▄ █ +█ █ ▀ █ █▐▌█ █ █ █▄▄▀ █ █ █▄▄▀ ▀▄▄ █ █ █ █ █ ██ █ █ █ █ ▌█ █ █ ▄ █ █ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀▀ ▀ ▀▀▌ ▀ ▀ ▀▀ ▀ ''', u''' UUUUUVVVVVVWWWWWWXXXXXXYYYYYYZZZZZ -█ █ █ █ █ █ █ █ █ █ ▀▀▀█ -█ █ ▐▌ ▐▌ █ ▄ █ ▀▄▀ ▀▄▀ ▄▀ -█ █ █ █ ▐▌█▐▌ ▄▀ ▀▄ █ █ - ▀▀ ▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀▀ +█ █ █ █ █ █ █ █ █ █ ▀▀▀█ +█ █ ▐▌ ▐▌ █ ▄ █ ▀▄▀ ▀▄▀ ▄▀ +█ █ █ █ ▐▌█▐▌ ▄▀ ▀▄ █ █ + ▀▀ ▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀▀ ''', u''' aaaaabbbbbcccccdddddeeeeeffffggggghhhhhiijjjjkkkkk █ █ ▄▀▀ █ ▄ ▄ █ - ▀▀▄ █▀▀▄ ▄▀▀▄ ▄▀▀█ ▄▀▀▄ ▀█▀ ▄▀▀▄ █▀▀▄ ▄ ▄ █ ▄▀ -▄▀▀█ █ █ █ ▄ █ █ █▀▀ █ ▀▄▄█ █ █ █ █ █▀▄ - ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀ ▄▄▀ ▀ ▀ ▀ ▄▄▀ ▀ ▀ + ▀▀▄ █▀▀▄ ▄▀▀▄ ▄▀▀█ ▄▀▀▄ ▀█▀ ▄▀▀▄ █▀▀▄ ▄ ▄ █ ▄▀ +▄▀▀█ █ █ █ ▄ █ █ █▀▀ █ ▀▄▄█ █ █ █ █ █▀▄ + ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀ ▄▄▀ ▀ ▀ ▀ ▄▄▀ ▀ ▀ ''', u''' llmmmmmmnnnnnooooopppppqqqqqrrrrssssstttt -█ █ -█ █▀▄▀▄ █▀▀▄ ▄▀▀▄ █▀▀▄ ▄▀▀█ █▀▀ ▄▀▀▀ ▀█▀ +█ █ +█ █▀▄▀▄ █▀▀▄ ▄▀▀▄ █▀▀▄ ▄▀▀█ █▀▀ ▄▀▀▀ ▀█▀ █ █ █ █ █ █ █ █ █ █ █ █ █ ▀▀▄ █ ▀ ▀ ▀ ▀ ▀ ▀▀ █▀▀ ▀▀█ ▀ ▀▀▀ ▀ ''', u''' uuuuuvvvvvwwwwwwxxxxxxyyyyyzzzzz - + █ █ █ █ █ ▄ █ ▀▄ ▄▀ █ █ ▀▀█▀ -█ █ ▐▌▐▌ ▐▌█▐▌ ▄▀▄ ▀▄▄█ ▄▀ +█ █ ▐▌▐▌ ▐▌█▐▌ ▄▀▄ ▀▄▄█ ▄▀ ▀▀ ▀▀ ▀ ▀ ▀ ▀ ▄▄▀ ▀▀▀▀ '''] add_font("Half Block 5x4",HalfBlock5x4Font) @@ -253,34 +253,34 @@ class Thin6x6Font(Font): data = [u""" 000000111111222222333333444444555555666666777777888888999999'' ┌───┐ ┐ ┌───┐ ┌───┐ ┐ ┌─── ┌─── ┌───┐ ┌───┐ ┌───┐ │ -│ │ │ │ │ ┌ │ │ │ │ │ │ │ │ -│ / │ │ ┌───┘ ─┤ └──┼─ └───┐ ├───┐ ┼ ├───┤ └───┤ -│ │ │ │ │ │ │ │ │ │ │ │ │ -└───┘ ┴ └─── └───┘ ┴ ───┘ └───┘ ┴ └───┘ ───┘ +│ │ │ │ │ ┌ │ │ │ │ │ │ │ │ +│ / │ │ ┌───┘ ─┤ └──┼─ └───┐ ├───┐ ┼ ├───┤ └───┤ +│ │ │ │ │ │ │ │ │ │ │ │ │ +└───┘ ┴ └─── └───┘ ┴ ───┘ └───┘ ┴ └───┘ ───┘ """, ur''' !! """######$$$$$$%%%%%%&&&&&&((()))******++++++ -│ ││ ┌ ┌ ┌─┼─┐ ┌┐ / ┌─┐ / \ +│ ││ ┌ ┌ ┌─┼─┐ ┌┐ / ┌─┐ / \ │ ─┼─┼─ │ │ └┘ / │ │ │ │ \ / │ -│ │ │ └─┼─┐ / ┌─\┘ │ │ ──X── ──┼── +│ │ │ └─┼─┐ / ┌─\┘ │ │ ──X── ──┼── │ ─┼─┼─ │ │ / ┌┐ │ \, │ │ / \ │ -. ┘ ┘ └─┼─┘ / └┘ └───\ \ / +. ┘ ┘ └─┼─┘ / └┘ └───\ \ / ''', ur""" ,,-----..//////::;;<<<<=====>>>>??????@@@@@@ / ┌───┐ ┌───┐ / . . / ──── \ │ │┌──┤ - ──── / / \ ┌─┘ ││ │ + ──── / / \ ┌─┘ ││ │ / . , \ ──── / │ │└──┘ , . / \ / . └───┘ """, ur""" [[\\\\\\]]^^^____``{{||}}~~~~~~ -┌ \ ┐ /\ \ ┌ │ ┐ +┌ \ ┐ /\ \ ┌ │ ┐ │ \ │ │ │ │ ┌─┐ │ \ │ ┤ │ ├ └─┘ -│ \ │ │ │ │ -└ \ ┘ ──── └ │ ┘ +│ \ │ │ │ │ +└ \ ┘ ──── └ │ ┘ """, u""" AAAAAABBBBBBCCCCCCDDDDDDEEEEEEFFFFFFGGGGGGHHHHHHIIJJJJJJ @@ -300,15 +300,15 @@ KKKKKKLLLLLLMMMMMMNNNNNNOOOOOOPPPPPPQQQQQQRRRRRRSSSSSS └ """, u""" TTTTTTUUUUUUVVVVVVWWWWWWXXXXXXYYYYYYZZZZZZ -┌─┬─┐ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┌───┐ - │ │ │ │ │ │ │ └┐ ┌┘ │ │ ┌─┘ - │ │ │ │ │ │ │ │ ├─┤ └─┬─┘ ┌┘ - │ │ │ └┐ ┌┘ │ │ │ ┌┘ └┐ │ ┌┘ - ┴ └───┘ └─┘ └─┴─┘ ┴ ┴ ┴ └───┘ - +┌─┬─┐ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┌───┐ + │ │ │ │ │ │ │ └┐ ┌┘ │ │ ┌─┘ + │ │ │ │ │ │ │ │ ├─┤ └─┬─┘ ┌┘ + │ │ │ └┐ ┌┘ │ │ │ ┌┘ └┐ │ ┌┘ + ┴ └───┘ └─┘ └─┴─┘ ┴ ┴ ┴ └───┘ + """, u""" aaaaaabbbbbbccccccddddddeeeeeefffgggggghhhhhhiijjj - ┌─┐ + ┌─┐ │ │ │ │ . . ┌───┐ ├───┐ ┌───┐ ┌───┤ ┌───┐ ┼ ┌───┐ ├───┐ ┐ ┐ ┌───┤ │ │ │ │ │ ├───┘ │ │ │ │ │ │ │ @@ -316,16 +316,16 @@ aaaaaabbbbbbccccccddddddeeeeeefffgggggghhhhhhiijjj └───┘ ─┘ """, u""" kkkkkkllmmmmmmnnnnnnooooooppppppqqqqqqrrrrrssssss - -│ │ + +│ │ │ ┌─ │ ┬─┬─┐ ┬───┐ ┌───┐ ┌───┐ ┌───┐ ┬──┐ ┌───┐ ├─┴┐ │ │ │ │ │ │ │ │ │ │ │ │ │ └───┐ ┴ └─ └ ┴ ┴ ┴ ┴ └───┘ ├───┘ └───┤ ┴ └───┘ - │ │ + │ │ """, u""" ttttuuuuuuvvvvvvwwwwwwxxxxxxyyyyyyzzzzzz - - │ + + │ ─┼─ ┬ ┬ ┬ ┬ ┬ ┬ ─┐ ┌─ ┬ ┬ ────┬ │ │ │ └┐ ┌┘ │ │ │ ├─┤ │ │ ┌───┘ └─ └───┴ └─┘ └─┴─┘ ─┘ └─ └───┤ ┴──── @@ -340,92 +340,92 @@ class HalfBlock7x7Font(Font): 0000000111111122222223333333444444455555556666666777777788888889999999''' ▄███▄ ▐█▌ ▄███▄ ▄███▄ █▌ ▐█████▌ ▄███▄ ▐█████▌ ▄███▄ ▄███▄ ▐█ ▐█ █▌ ▀█▌ ▐█ █▌▐█ █▌▐█ █▌ ▐█ ▐█ ▐█ ▐█ █▌▐█ █▌▐█ -▐█ ▐ █▌ █▌ █▌ ▐██ ▐█████▌▐████▄ ▐████▄ █▌ █████ ▀████▌ -▐█ ▌ █▌ █▌ ▄█▀ █▌ █▌ █▌▐█ █▌ ▐█ ▐█ █▌ █▌ -▐█ █▌ █▌ ▄█▀ ▐█ █▌ █▌ █▌▐█ █▌ █▌ ▐█ █▌ █▌ - ▀███▀ ███▌ ▐█████▌ ▀███▀ █▌ ▐████▀ ▀███▀ ▐█ ▀███▀ ▀███▀ +▐█ ▐ █▌ █▌ █▌ ▐██ ▐█████▌▐████▄ ▐████▄ █▌ █████ ▀████▌ +▐█ ▌ █▌ █▌ ▄█▀ █▌ █▌ █▌▐█ █▌ ▐█ ▐█ █▌ █▌ +▐█ █▌ █▌ ▄█▀ ▐█ █▌ █▌ █▌▐█ █▌ █▌ ▐█ █▌ █▌ + ▀███▀ ███▌ ▐█████▌ ▀███▀ █▌ ▐████▀ ▀███▀ ▐█ ▀███▀ ▀███▀ """, u''' !!! """""#######$$$$$$$%%%%%%%&&&&&&&(((())))*******++++++ -▐█ ▐█ █▌ ▐█ █▌ █ ▄ █▌ ▄█▄ █▌▐█ ▄▄ ▄▄ +▐█ ▐█ █▌ ▐█ █▌ █ ▄ █▌ ▄█▄ █▌▐█ ▄▄ ▄▄ ▐█ ▐█ █▌▐█████▌ ▄███▄ ▐█▌▐█ ▐█ █▌ ▐█ █▌ ▀█▄█▀ ▐█ ▐█ ▐█ █▌ ▐█▄█▄▄ ▀ █▌ ███ █▌ ▐█ ▐█████▌ ████▌ -▐█ ▐█████▌ ▀▀█▀█▌ ▐█ ▄ ███▌▄ █▌ ▐█ ▄█▀█▄ ▐█ - ▐█ █▌ ▀███▀ █▌▐█▌▐█ █▌ ▐█ █▌ ▀▀ ▀▀ -▐█ █ ▐█ ▀ ▀██▀█▌ █▌▐█ - +▐█ ▐█████▌ ▀▀█▀█▌ ▐█ ▄ ███▌▄ █▌ ▐█ ▄█▀█▄ ▐█ + ▐█ █▌ ▀███▀ █▌▐█▌▐█ █▌ ▐█ █▌ ▀▀ ▀▀ +▐█ █ ▐█ ▀ ▀██▀█▌ █▌▐█ + ''', u""" ,,,------.../////:::;;;<<<<<<<======>>>>>>>???????@@@@@@@ - █▌ ▄█▌ ▐█▄ ▄███▄ ▄███▄ - ▐█ ▐█ ▐█ ▄█▀ ▐████▌ ▀█▄ ▐█ █▌▐█ ▄▄█▌ + █▌ ▄█▌ ▐█▄ ▄███▄ ▄███▄ + ▐█ ▐█ ▐█ ▄█▀ ▐████▌ ▀█▄ ▐█ █▌▐█ ▄▄█▌ ▐████▌ █▌ ▐██ ██▌ █▌ ▐█▐█▀█▌ ▐█ ▐█ ▐█ ▀█▄ ▐████▌ ▄█▀ █▌ ▐█▐█▄█▌ - █▌ ▀ ▀█▌ ▐█▀ ▐█ ▀▀▀ -▐█ ▐█ ▐█ █▌ ▀███▀ -▀ + █▌ ▀ ▀█▌ ▐█▀ ▐█ ▀▀▀ +▐█ ▐█ ▐█ █▌ ▀███▀ +▀ """, ur""" [[[[\\\\\]]]]^^^^^^^_____```{{{{{|||}}}}}~~~~~~~´´´ -▐██▌▐█ ▐██▌ ▐█▌ ▐█ █▌▐█ ▐█ █▌ -▐█ █▌ █▌ ▐█ █▌ █▌ █▌ ▐█ ▐█ ▄▄ ▐█ +▐██▌▐█ ▐██▌ ▐█▌ ▐█ █▌▐█ ▐█ █▌ +▐█ █▌ █▌ ▐█ █▌ █▌ █▌ ▐█ ▐█ ▄▄ ▐█ ▐█ ▐█ █▌▐█ █▌ ▄█▌ ▐█ ▐█▄ ▐▀▀█▄▄▌ ▐█ █▌ █▌ ▀█▌ ▐█ ▐█▀ ▀▀ -▐█ ▐█ █▌ █▌ ▐█ ▐█ -▐██▌ █▌▐██▌ █████ █▌▐█ ▐█ - +▐█ ▐█ █▌ █▌ ▐█ ▐█ +▐██▌ █▌▐██▌ █████ █▌▐█ ▐█ + """, u""" AAAAAAABBBBBBBCCCCCCCDDDDDDDEEEEEEEFFFFFFFGGGGGGGHHHHHHHIIIIJJJJJJJ - ▄███▄ ▐████▄ ▄███▄ ▐████▄ ▐█████▌▐█████▌ ▄███▄ ▐█ █▌ ██▌ █▌ -▐█ █▌▐█ █▌▐█ ▐█ █▌▐█ ▐█ ▐█ ▐█ █▌ ▐█ █▌ + ▄███▄ ▐████▄ ▄███▄ ▐████▄ ▐█████▌▐█████▌ ▄███▄ ▐█ █▌ ██▌ █▌ +▐█ █▌▐█ █▌▐█ ▐█ █▌▐█ ▐█ ▐█ ▐█ █▌ ▐█ █▌ ▐█████▌▐█████ ▐█ ▐█ █▌▐████ ▐████ ▐█ ▐█████▌ ▐█ █▌ ▐█ █▌▐█ █▌▐█ ▐█ █▌▐█ ▐█ ▐█ ██▌▐█ █▌ ▐█ █▌ ▐█ █▌▐█ █▌▐█ ▐█ █▌▐█ ▐█ ▐█ █▌▐█ █▌ ▐█ ▐█ █▌ -▐█ █▌▐████▀ ▀███▀ ▐████▀ ▐█████▌▐█ ▀███▀ ▐█ █▌ ██▌ ▀███▀ - +▐█ █▌▐████▀ ▀███▀ ▐████▀ ▐█████▌▐█ ▀███▀ ▐█ █▌ ██▌ ▀███▀ + """, u""" KKKKKKKLLLLLLLMMMMMMMMNNNNNNNOOOOOOOPPPPPPPQQQQQQQRRRRRRRSSSSSSS -▐█ █▌▐█ ▄█▌▐█▄ ▐██ █▌ ▄███▄ ▐████▄ ▄███▄ ▐████▄ ▄███▄ -▐█ █▌ ▐█ ▐█ ▐▌ █▌▐██▌ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ -▐█▄█▌ ▐█ ▐█ ▐▌ █▌▐█▐█ █▌▐█ █▌▐████▀ ▐█ █▌▐█████ ▀███▄ +▐█ █▌▐█ ▄█▌▐█▄ ▐██ █▌ ▄███▄ ▐████▄ ▄███▄ ▐████▄ ▄███▄ +▐█ █▌ ▐█ ▐█ ▐▌ █▌▐██▌ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ +▐█▄█▌ ▐█ ▐█ ▐▌ █▌▐█▐█ █▌▐█ █▌▐████▀ ▐█ █▌▐█████ ▀███▄ ▐█▀█▌ ▐█ ▐█ █▌▐█ █▌█▌▐█ █▌▐█ ▐█ █▌▐█ █▌ █▌ ▐█ █▌ ▐█ ▐█ █▌▐█ ▐██▌▐█ █▌▐█ ▐█ █▌█▌▐█ █▌ █▌ -▐█ █▌▐█████▌▐█ █▌▐█ ██▌ ▀███▀ ▐█ ▀███▀ ▐█ █▌ ▀███▀ - ▀▀ +▐█ █▌▐█████▌▐█ █▌▐█ ██▌ ▀███▀ ▐█ ▀███▀ ▐█ █▌ ▀███▀ + ▀▀ """, u""" TTTTTTTUUUUUUUVVVVVVVWWWWWWWWXXXXXXXYYYYYYYZZZZZZZ - █████▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌ █▌ █▌▐█████▌ - █▌ ▐█ █▌ █▌ ▐█ ▐█ █▌ ▐█ █▌ ▐█ ▐█ █▌ - █▌ ▐█ █▌ ▐█ █▌ ▐█ █▌ ▐█▌ ▐██ █▌ + █████▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌ █▌ █▌▐█████▌ + █▌ ▐█ █▌ █▌ ▐█ ▐█ █▌ ▐█ █▌ ▐█ ▐█ █▌ + █▌ ▐█ █▌ ▐█ █▌ ▐█ █▌ ▐█▌ ▐██ █▌ █▌ ▐█ █▌ ███ ▐█ ▐▌ █▌ ███ █▌ █▌ █▌ ▐█ █▌ ▐█▌ ▐█ ▐▌ █▌ █▌ ▐█ █▌ █▌ - █▌ ▀███▀ █ ▀█▌▐█▀ ▐█ █▌ █▌ ▐█████▌ - + █▌ ▀███▀ █ ▀█▌▐█▀ ▐█ █▌ █▌ ▐█████▌ + """, u""" aaaaaaabbbbbbbcccccccdddddddeeeeeeefffffggggggghhhhhhhiiijjjj ▐█ █▌ ▄█▌ ▐█ █▌ █▌ - ▐█ █▌ ▐█ ▐█ + ▐█ █▌ ▐█ ▐█ ▄███▄ ▐████▄ ▄███▄ ▄████▌ ▄███▄ ▐███ ▄███▄ ▐████▄ ▐█▌ ▐█▌ - ▄▄▄█▌▐█ █▌▐█ ▐█ █▌▐█▄▄▄█▌ ▐█ ▐█ █▌▐█ █▌ █▌ █▌ + ▄▄▄█▌▐█ █▌▐█ ▐█ █▌▐█▄▄▄█▌ ▐█ ▐█ █▌▐█ █▌ █▌ █▌ ▐█▀▀▀█▌▐█ █▌▐█ ▐█ █▌▐█▀▀▀ ▐█ ▐█▄▄▄█▌▐█ █▌ █▌ █▌ ▀████▌▐████▀ ▀███▀ ▀████▌ ▀███▀ ▐█ ▀▀▀█▌▐█ █▌ █▌ █▌ - ▀███▀ ▐██ + ▀███▀ ▐██ """, u""" kkkkkkkllllmmmmmmmmnnnnnnnooooooopppppppqqqqqqqrrrrrrsssssss -▐█ ██ -▐█ ▐█ -▐█ ▄█▌ ▐█ ▄█▌▐█▄ ▐████▄ ▄███▄ ▐████▄ ▄████▌ ▄███▌ ▄███▄ -▐█▄█▀ ▐█ ▐█ ▐▌ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ ▐█▄▄▄ +▐█ ██ +▐█ ▐█ +▐█ ▄█▌ ▐█ ▄█▌▐█▄ ▐████▄ ▄███▄ ▐████▄ ▄████▌ ▄███▌ ▄███▄ +▐█▄█▀ ▐█ ▐█ ▐▌ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ ▐█▄▄▄ ▐█▀▀█▄ ▐█ ▐█ ▐▌ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ ▀▀▀█▌ -▐█ █▌ ▐█▌▐█ █▌▐█ █▌ ▀███▀ ▐████▀ ▀████▌▐█ ▀███▀ +▐█ █▌ ▐█▌▐█ █▌▐█ █▌ ▀███▀ ▐████▀ ▀████▌▐█ ▀███▀ ▐█ █▌ """, u""" tttttuuuuuuuvvvvvvvwwwwwwwwxxxxxxxyyyyyyyzzzzzzz █▌ █▌ - ███▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█████▌ - █▌ ▐█ █▌ █▌ ▐█ ▐█ █▌ ▀█▄█▀ ▐█ █▌ ▄█▀ + ███▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█ █▌▐█████▌ + █▌ ▐█ █▌ █▌ ▐█ ▐█ █▌ ▀█▄█▀ ▐█ █▌ ▄█▀ █▌ ▐█ █▌ ███ ▐█ ▐▌ █▌ ▄█▀█▄ ▐█▄▄▄█▌ ▄█▀ █▌ ▀███▀ ▐█▌ ▀█▌▐█▀ ▐█ █▌ ▀▀▀█▌▐█████▌ - ▀███▀ + ▀███▀ """] add_font("Half Block 7x7",HalfBlock7x7Font) diff --git a/urwid/html_fragment.py b/urwid/html_fragment.py index 7ba835e..159bc81 100755 --- a/urwid/html_fragment.py +++ b/urwid/html_fragment.py @@ -49,12 +49,12 @@ class HtmlGenerator(BaseScreen): self.colors = 16 self.bright_is_bold = False # ignored self.has_underline = True # ignored - self.register_palette_entry(None, + self.register_palette_entry(None, _default_foreground, _default_background) def set_terminal_properties(self, colors=None, bright_is_bold=None, has_underline=None): - + if colors is None: colors = self.colors if bright_is_bold is None: @@ -72,10 +72,10 @@ class HtmlGenerator(BaseScreen): def start(self): pass - + def stop(self): pass - + def set_input_timeouts(self, *args): pass @@ -87,24 +87,24 @@ class HtmlGenerator(BaseScreen): return fn() def draw_screen(self, (cols, rows), r ): - """Create an html fragment from the render object. + """Create an html fragment from the render object. Append it to HtmlGenerator.fragments list. """ # collect output in l l = [] - + assert r.rows() == rows - + if r.cursor is not None: cx, cy = r.cursor else: cx = cy = None - + y = -1 for row in r.content(): y += 1 col = 0 - + for a, cs, run in row: run = run.translate(_trans_table) if isinstance(a, AttrSpec): @@ -126,10 +126,10 @@ class HtmlGenerator(BaseScreen): l.append(html_span(run, aspec)) l.append("\n") - + # add the fragment to the list self.fragments.append( "<pre>%s</pre>" % "".join(l) ) - + def clear(self): """ Force the screen to be completely repainted on the next @@ -138,7 +138,7 @@ class HtmlGenerator(BaseScreen): (does nothing for html_fragment) """ pass - + def get_cols_rows(self): """Return the next screen size in HtmlGenerator.sizes.""" if not self.sizes: @@ -173,9 +173,9 @@ def html_span(s, aspec, cursor = -1): def html_span(fg, bg, s): if not s: return "" return ('<span style="color:%s;' - 'background:%s%s">%s</span>' % + 'background:%s%s">%s</span>' % (fg, bg, extra, html_escape(s))) - + if cursor >= 0: c_off, _ign = util.calc_text_pos(s, 0, len(s), cursor) c2_off = util.move_next_char(s, c_off, len(s)) @@ -195,17 +195,17 @@ def html_escape(text): def screenshot_init( sizes, keys ): """ - Replace curses_display.Screen and raw_display.Screen class with + Replace curses_display.Screen and raw_display.Screen class with HtmlGenerator. - - Call this function before executing an application that uses + + Call this function before executing an application that uses curses_display.Screen to have that code use HtmlGenerator instead. - + sizes -- list of ( columns, rows ) tuples to be returned by each call to HtmlGenerator.get_cols_rows() keys -- list of lists of keys to be returned by each call to HtmlGenerator.get_input() - + Lists of keys may include "window resize" to force the application to call get_cols_rows and read a new screen size. @@ -228,7 +228,7 @@ def screenshot_init( sizes, keys ): assert row>0 and col>0 except (AssertionError, ValueError): raise Exception, "sizes must be in the form [ (col1,row1), (col2,row2), ...]" - + try: for l in keys: assert type(l) == list @@ -236,12 +236,12 @@ def screenshot_init( sizes, keys ): assert type(k) == str except (AssertionError, ValueError): raise Exception, "keys must be in the form [ [keyA1, keyA2, ..], [keyB1, ..], ...]" - + import curses_display curses_display.Screen = HtmlGenerator import raw_display raw_display.Screen = HtmlGenerator - + HtmlGenerator.sizes = sizes HtmlGenerator.keys = keys @@ -252,4 +252,4 @@ def screenshot_collect(): HtmlGenerator.fragments = [] return l - + diff --git a/urwid/lcd_display.py b/urwid/lcd_display.py index 71a1cfa..ca6336f 100644 --- a/urwid/lcd_display.py +++ b/urwid/lcd_display.py @@ -47,7 +47,7 @@ class LCDScreen(BaseScreen): def run_wrapper(self,fn): return fn() - + def draw_screen(self, (cols, rows), r ): pass @@ -68,7 +68,7 @@ class CFLCDScreen(LCDScreen): 'right_press', 'enter_press', 'exit_press', 'up_release', 'down_release', 'left_release', 'right_release', 'enter_release', 'exit_release', - 'ul_press', 'ur_press', 'll_press', 'lr_press', + 'ul_press', 'ur_press', 'll_press', 'lr_press', 'ul_release', 'ur_release', 'll_release', 'lr_release'] CMD_PING = 0 CMD_VERSION = 1 @@ -146,15 +146,15 @@ class CFLCDScreen(LCDScreen): def _send_packet(self, command, data): """ - low-level packet sending. - Following the protocol requires waiting for ack packet between + low-level packet sending. + Following the protocol requires waiting for ack packet between sending each packet to the device. """ buf = chr(command) + chr(len(data)) + data crc = self.get_crc(buf) buf = buf + chr(crc & 0xff) + chr(crc >> 8) self._device.write(buf) - + def _read_packet(self): """ low-level packet reading. @@ -171,7 +171,7 @@ class CFLCDScreen(LCDScreen): self._unprocessed = unprocessed return command, data except self.MoreDataRequired: - return + return except self.InvalidPacket: # throw out a byte and try to parse again self._unprocessed = self._unprocessed[1:] @@ -206,9 +206,9 @@ class CFLCDScreen(LCDScreen): class KeyRepeatSimulator(object): """ - Provide simulated repeat key events when given press and + Provide simulated repeat key events when given press and release events. - + If two or more keys are pressed disable repeating until all keys are released. """ @@ -236,7 +236,7 @@ class KeyRepeatSimulator(object): def next_event(self): """ - Return (remaining, key) where remaining is the number of seconds + Return (remaining, key) where remaining is the number of seconds (float) until the key repeat event should be sent, or None if no events are pending. """ @@ -301,8 +301,8 @@ class CF635Screen(CFLCDScreen): cursor_style = CFLCDScreen.CURSOR_INVERTING_BLINKING_BLOCK - def __init__(self, device_path, baud=115200, - repeat_delay=0.5, repeat_next=0.125, + def __init__(self, device_path, baud=115200, + repeat_delay=0.5, repeat_next=0.125, key_map=['up', 'down', 'left', 'right', 'enter', 'esc']): """ device_path -- eg. '/dev/ttyUSB0' @@ -357,7 +357,7 @@ class CF635Screen(CFLCDScreen): if not packet: break command, data = packet - + if command == self.CMD_KEY_ACTIVITY and data: d0 = ord(data[0]) if 1 <= d0 <= 12: @@ -374,7 +374,7 @@ class CF635Screen(CFLCDScreen): elif command & 0xc0 == 0x40: # "ACK" if command & 0x3f == self._last_command: self._send_next_command() - + next_repeat = self.key_repeat.next_event() if next_repeat: timeout, key = next_repeat @@ -424,7 +424,7 @@ class CF635Screen(CFLCDScreen): sb.append(text) y += 1 - if (self._previous_canvas and + if (self._previous_canvas and self._previous_canvas.cursor == canvas.cursor and (not self._update_cursor or not canvas.cursor)): pass @@ -489,6 +489,6 @@ class CF635Screen(CFLCDScreen): assert 0 <= led <= 3 assert rg in (0, 1) assert 0 <= value <= 100 - self.queue_command(self.CMD_GPO, chr(12 - 2 * led - rg) + + self.queue_command(self.CMD_GPO, chr(12 - 2 * led - rg) + chr(value)) diff --git a/urwid/main_loop.py b/urwid/main_loop.py index cfc8f20..0a93b5e 100755 --- a/urwid/main_loop.py +++ b/urwid/main_loop.py @@ -381,12 +381,12 @@ class MainLoop(object): self._input_timeout = None max_wait, keys, raw = self.screen.get_input_nonblocking() - + if max_wait is not None: # if get_input_nonblocking wants to be called back # make sure it happens with an alarm - self._input_timeout = self.event_loop.alarm(max_wait, - lambda: self._update(timeout=True)) + self._input_timeout = self.event_loop.alarm(max_wait, + lambda: self._update(timeout=True)) keys = self.input_filter(keys, raw) @@ -419,7 +419,7 @@ class MainLoop(object): else: self.screen.set_input_timeouts(None) keys, raw = self.screen.get_input(True) - if not keys and next_alarm: + if not keys and next_alarm: sec = next_alarm[0] - time.time() if sec <= 0: break @@ -687,7 +687,7 @@ class SelectEventLoop(object): if self._alarms: tm = self._alarms[0][0] timeout = max(0, tm - time.time()) - if self._did_something and (not self._alarms or + if self._did_something and (not self._alarms or (self._alarms and timeout > 0)): timeout = 0 tm = 'idle' diff --git a/urwid/old_str_util.py b/urwid/old_str_util.py index bb993f6..04594ec 100755 --- a/urwid/old_str_util.py +++ b/urwid/old_str_util.py @@ -30,7 +30,7 @@ SAFE_ASCII_BYTES_RE = re.compile(B("^[ -~]*$")) _byte_encoding = None # GENERATED DATA -# generated from +# generated from # http://www.unicode.org/Public/4.0-Update/EastAsianWidth-4.0.0.txt widths = [ @@ -92,7 +92,7 @@ def decode_one( text, pos ): """ assert isinstance(text, bytes), text b1 = ord2(text[pos]) - if not b1 & 0x80: + if not b1 & 0x80: return b1, pos+1 error = ord("?"), pos+1 lt = len(text) @@ -189,7 +189,7 @@ def calc_text_pos(text, start_offs, end_offs, pref_col): while i < end_offs: o, n = decode(text, i) w = get_width(o) - if w+sc > pref_col: + if w+sc > pref_col: return i, sc i = n sc += w @@ -350,7 +350,7 @@ def process_east_asian_width(): if last is None: out.append((0, l)) last = l - + if last == l: out[-1] = (num, l) else: @@ -361,7 +361,7 @@ def process_east_asian_width(): for o in out[1:]: # treat control characters same as ascii print "\t%r," % (o,) print "]" - + if __name__ == "__main__": process_east_asian_width() diff --git a/urwid/raw_display.py b/urwid/raw_display.py index 58b3112..185f1ab 100644 --- a/urwid/raw_display.py +++ b/urwid/raw_display.py @@ -55,7 +55,7 @@ class Screen(BaseScreen, RealTerminal): super(Screen, self).__init__() self._pal_escape = {} self._pal_attrspec = {} - signals.connect_signal(self, UPDATE_PALETTE_ENTRY, + signals.connect_signal(self, UPDATE_PALETTE_ENTRY, self._on_update_palette_entry) self.colors = 16 # FIXME: detect this self.has_underline = True # FIXME: detect this @@ -90,12 +90,12 @@ class Screen(BaseScreen, RealTerminal): self._pal_attrspec[name] = a self._pal_escape[name] = self._attrspec_to_escape(a) - def set_input_timeouts(self, max_wait=None, complete_wait=0.125, + def set_input_timeouts(self, max_wait=None, complete_wait=0.125, resize_wait=0.125): """ Set the get_input timeout values. All values are in floating point numbers of seconds. - + max_wait -- amount of time in seconds to wait for input when there is no input pending, wait forever if None complete_wait -- amount of time in seconds to wait when @@ -289,7 +289,7 @@ class Screen(BaseScreen, RealTerminal): Examples of keys returned: - * ASCII printable characters: " ", "a", "0", "A", "-", "/" + * ASCII printable characters: " ", "a", "0", "A", "-", "/" * ASCII control characters: "tab", "enter" * Escape sequences: "up", "page up", "home", "insert", "f1" * Key combinations: "shift f1", "meta a", "ctrl b" @@ -309,7 +309,7 @@ class Screen(BaseScreen, RealTerminal): Examples of mouse events returned: - * Mouse button press: ('mouse press', 1, 15, 13), + * Mouse button press: ('mouse press', 1, 15, 13), ('meta mouse press', 2, 17, 23) * Mouse drag: ('mouse drag', 1, 16, 13), ('mouse drag', 1, 17, 13), @@ -330,7 +330,7 @@ class Screen(BaseScreen, RealTerminal): self._input_iter.next() raw += raw2 #if not keys: - # keys, raw2 = self._get_input( + # keys, raw2 = self._get_input( # self.resize_wait) # raw += raw2 if keys!=['window resize']: @@ -414,7 +414,7 @@ class Screen(BaseScreen, RealTerminal): run, codes = escape.process_keyqueue( codes, False) processed.extend(run) - + if self._resized: processed.append('window resize') self._resized = False @@ -464,13 +464,13 @@ class Screen(BaseScreen, RealTerminal): fd_list,[],fd_list, timeout) break except select.error, e: - if e.args[0] != 4: + if e.args[0] != 4: raise if self._resized: ready = [] break - return ready - + return ready + def _getch(self, timeout): ready = self._wait_for_input_ready(timeout) if self.gpm_mev is not None: @@ -479,7 +479,7 @@ class Screen(BaseScreen, RealTerminal): if self._term_input_file.fileno() in ready: return ord(os.read(self._term_input_file.fileno(), 1)) return -1 - + def _encode_gpm_event( self ): self.gpm_event_pending = False s = self.gpm_mev.stdout.readline().decode('ascii') @@ -500,7 +500,7 @@ class Screen(BaseScreen, RealTerminal): last = next = self.last_bstate l = [] - + mod = 0 if m & 1: mod |= 4 # shift if m & 10: mod |= 8 # alt @@ -565,11 +565,11 @@ class Screen(BaseScreen, RealTerminal): self.last_bstate = next return l - + def _getch_nodelay(self): return self._getch(0) - - + + def get_cols_rows(self): """Return the terminal dimensions (num columns, num rows).""" y, x = 80, 24 @@ -589,7 +589,7 @@ class Screen(BaseScreen, RealTerminal): """ if self._setup_G1_done: return - + while True: try: self._term_output_file.write(escape.DESIGNATE_G1_SPECIAL) @@ -599,7 +599,7 @@ class Screen(BaseScreen, RealTerminal): pass self._setup_G1_done = True - + def draw_screen(self, (maxcol, maxrow), r ): """Paint screen with rendered canvas.""" assert self._started @@ -611,13 +611,13 @@ class Screen(BaseScreen, RealTerminal): return self._setup_G1() - - if self._resized: + + if self._resized: # handle resize before trying to draw screen return - + o = [escape.HIDE_CURSOR, self._attrspec_to_escape(AttrSpec('',''))] - + def partial_display(): # returns True if the screen is in partial display mode # ie. only some rows belong to the display @@ -637,9 +637,9 @@ class Screen(BaseScreen, RealTerminal): def set_cursor_home(): if not partial_display(): return escape.set_cursor_position(0, 0) - return (escape.CURSOR_HOME_COL + + return (escape.CURSOR_HOME_COL + escape.move_cursor_up(cy)) - + def set_cursor_row(y): if not partial_display(): return escape.set_cursor_position(0, y) @@ -655,7 +655,7 @@ class Screen(BaseScreen, RealTerminal): return ('\b' + escape.CURSOR_HOME_COL + escape.move_cursor_down(y - cy) + escape.move_cursor_right(x)) - + def is_blank_row(row): if len(row) > 1: return False @@ -747,7 +747,7 @@ class Screen(BaseScreen, RealTerminal): icss = escape.IBMPC_ON else: icss = escape.SO - o += [ "\x08"*back, + o += [ "\x08"*back, ias, icss, escape.INSERT_ON, inserttext, escape.INSERT_OFF ] @@ -795,21 +795,21 @@ class Screen(BaseScreen, RealTerminal): new_row = row[:-1] z_attr, z_cs, last_text = row[-1] last_cols = util.calc_width(last_text, 0, len(last_text)) - last_offs, z_col = util.calc_text_pos(last_text, 0, + last_offs, z_col = util.calc_text_pos(last_text, 0, len(last_text), last_cols-1) if last_offs == 0: z_text = last_text del new_row[-1] # we need another segment y_attr, y_cs, nlast_text = row[-2] - nlast_cols = util.calc_width(nlast_text, 0, + nlast_cols = util.calc_width(nlast_text, 0, len(nlast_text)) z_col += nlast_cols nlast_offs, y_col = util.calc_text_pos(nlast_text, 0, len(nlast_text), nlast_cols-1) y_text = nlast_text[nlast_offs:] if nlast_offs: - new_row.append((y_attr, y_cs, + new_row.append((y_attr, y_cs, nlast_text[:nlast_offs])) else: z_text = last_text[last_offs:] @@ -822,12 +822,12 @@ class Screen(BaseScreen, RealTerminal): if nlast_offs: new_row.append((y_attr, y_cs, last_text[:nlast_offs])) - + new_row.append((z_attr, z_cs, z_text)) return new_row, z_col-y_col, (y_attr, y_cs, y_text) - - + + def clear(self): """ Force the screen to be completely repainted on the next @@ -836,7 +836,7 @@ class Screen(BaseScreen, RealTerminal): self.screen_buf = None self.setup_G1 = True - + def _attrspec_to_escape(self, a): """ Convert AttrSpec instance a to an escape sequence for the terminal @@ -881,7 +881,7 @@ class Screen(BaseScreen, RealTerminal): """ colors -- number of colors terminal supports (1, 16, 88 or 256) or None to leave unchanged - bright_is_bold -- set to True if this terminal uses the bold + bright_is_bold -- set to True if this terminal uses the bold setting to create bright colors (numbers 8-15), set to False if this Terminal can create bright colors without bold or None to leave unchanged @@ -903,7 +903,7 @@ class Screen(BaseScreen, RealTerminal): self.colors = colors self.bright_is_bold = bright_is_bold self.has_underline = has_underline - + self.clear() self._pal_escape = {} for p,v in self._palette.items(): @@ -914,7 +914,7 @@ class Screen(BaseScreen, RealTerminal): def reset_default_terminal_palette(self): """ Attempt to set the terminal palette to default values as taken - from xterm. Uses number of colors from current + from xterm. Uses number of colors from current set_terminal_properties() screen setting. """ if self.colors == 1: @@ -938,7 +938,7 @@ class Screen(BaseScreen, RealTerminal): Attempt to set part of the terminal palette (this does not work on all terminals.) The changes are sent as a single escape sequence so they should all take effect at the same time. - + 0 <= index < 256 (some terminals will only have 16 or 88 colors) 0 <= red, green, blue < 256 """ @@ -952,7 +952,7 @@ class Screen(BaseScreen, RealTerminal): # shortcut for creating an AttrSpec with this screen object's # number of colors AttrSpec = lambda self, fg, bg: AttrSpec(fg, bg, self.colors) - + def _test(): import doctest diff --git a/urwid/split_repr.py b/urwid/split_repr.py index 8b5e24c..fb108b5 100755 --- a/urwid/split_repr.py +++ b/urwid/split_repr.py @@ -97,9 +97,9 @@ def python3_repr(v): def remove_defaults(d, fn): """ Remove keys in d that are set to the default values from - fn. This method is used to unclutter the _repr_attrs() + fn. This method is used to unclutter the _repr_attrs() return value. - + d will be modified by this function. Returns d. diff --git a/urwid/text_layout.py b/urwid/text_layout.py index 302c504..f09372b 100644 --- a/urwid/text_layout.py +++ b/urwid/text_layout.py @@ -97,7 +97,7 @@ class StandardTextLayout(TextLayout): if lw >= maxcol: return maxcol maxwidth = max(maxwidth, lw) - return maxwidth + return maxwidth def align_layout( self, text, width, segs, wrap, align ): """Convert the layout segs to an aligned layout.""" @@ -210,7 +210,7 @@ class StandardTextLayout(TextLayout): else: # unwrap previous line space if possible to # fit more text (we're breaking a word anyway) - if b and (len(b[-1]) == 2 or ( len(b[-1])==1 + if b and (len(b[-1]) == 2 or ( len(b[-1])==1 and len(b[-1][0])==2 )): # look for removed space above if len(b[-1]) == 1: @@ -225,7 +225,7 @@ class StandardTextLayout(TextLayout): # combine with previous line del b[-1] p = p_off - pos, sc = calc_text_pos( + pos, sc = calc_text_pos( text, p, n_cr, width ) b.append([(sc,p,pos)]) # check for trailing " " or "\n" @@ -250,18 +250,18 @@ class StandardTextLayout(TextLayout): default_layout = StandardTextLayout() ###################################### - + class LayoutSegment: def __init__(self, seg): """Create object from line layout segment structure""" - + assert type(seg) == tuple, repr(seg) assert len(seg) in (2,3), repr(seg) - + self.sc, self.offs = seg[:2] - + assert type(self.sc) == int, repr(self.sc) - + if len(seg)==3: assert type(self.offs) == int, repr(self.offs) assert self.sc > 0, repr(seg) @@ -279,10 +279,10 @@ class LayoutSegment: assert self.sc >= 0, repr(seg) assert type(self.offs)==int self.text = self.end = None - + def subseg(self, text, start, end): """ - Return a "sub-segment" list containing segment structures + Return a "sub-segment" list containing segment structures that make up a portion of this segment. A list is returned to handle cases where wide characters @@ -337,18 +337,18 @@ def shift_line( segs, amount ): amount -- screen columns to shift right (+ve) or left (-ve) """ assert type(amount)==int, repr(amount) - + if segs and len(segs[0])==2 and segs[0][1]==None: # existing shift amount += segs[0][0] if amount: return [(amount,None)]+segs[1:] return segs[1:] - + if amount: return [(amount,None)]+segs return segs - + def trim_line( segs, text, start, end ): """ @@ -416,16 +416,16 @@ def calc_line_pos( text, line_layout, pref_col ): s = LayoutSegment(seg) if s.offs is not None: if s.end is not None: - if (current_sc <= pref_col and + if (current_sc <= pref_col and pref_col < current_sc + s.sc): # exact match within this segment - return calc_text_pos( text, + return calc_text_pos( text, s.offs, s.end, pref_col - current_sc )[0] elif current_sc <= pref_col: closest_sc = current_sc + s.sc - 1 closest_pos = s - + if closest_sc is None or ( abs(pref_col-current_sc) < abs(pref_col-closest_sc) ): # this screen column is closer @@ -435,7 +435,7 @@ def calc_line_pos( text, line_layout, pref_col ): # we're moving past break current_sc += s.sc - + if closest_pos is None or type(closest_pos) == int: return closest_pos @@ -451,19 +451,19 @@ def calc_pos( text, layout, pref_col, row ): if row < 0 or row >= len(layout): raise Exception("calculate_pos: out of layout row range") - + pos = calc_line_pos( text, layout[row], pref_col ) if pos is not None: return pos - + rows_above = range(row-1,-1,-1) rows_below = range(row+1,len(layout)) while rows_above and rows_below: - if rows_above: + if rows_above: r = rows_above.pop(0) pos = calc_line_pos(text, layout[r], pref_col) if pos is not None: return pos - if rows_below: + if rows_below: r = rows_below.pop(0) pos = calc_line_pos(text, layout[r], pref_col) if pos is not None: return pos @@ -473,7 +473,7 @@ def calc_pos( text, layout, pref_col, row ): def calc_coords( text, layout, pos, clamp=1 ): """ Calculate the coordinates closest to position pos in text with layout. - + text -- raw string or unicode string layout -- layout structure applied to text pos -- integer position into text @@ -500,7 +500,7 @@ def calc_coords( text, layout, pos, clamp=1 ): closest = distance, (x,y) x += s.sc y += 1 - + if closest: return closest[1] return 0,0 diff --git a/urwid/treetools.py b/urwid/treetools.py index 26f0914..5b56d52 100644 --- a/urwid/treetools.py +++ b/urwid/treetools.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -# Generic TreeWidget/TreeWalker class +# Generic TreeWidget/TreeWalker class # Copyright (c) 2010 Rob Lanphier # Copyright (C) 2004-2010 Ian Ward # @@ -50,13 +50,13 @@ class TreeWidget(urwid.WidgetWrap): self.expanded = True widget = self.get_indented_widget() self.__super.__init__(widget) - + def selectable(self): """ Allow selection of non-leaf nodes so children may be (un)expanded """ return not self.is_leaf - + def get_indented_widget(self): widget = self.get_inner_widget() if not self.is_leaf: @@ -64,9 +64,9 @@ class TreeWidget(urwid.WidgetWrap): [self.unexpanded_icon, self.expanded_icon][self.expanded]), widget], dividechars=1) indent_cols = self.get_indent_cols() - return urwid.Padding(widget, + return urwid.Padding(widget, width=('relative', 100), left=indent_cols) - + def update_expanded_icon(self): """Update display widget text for parent widgets""" # icon is first element in columns indented widget @@ -83,12 +83,12 @@ class TreeWidget(urwid.WidgetWrap): def load_inner_widget(self): return urwid.Text(self.get_display_text()) - + def get_node(self): return self._node def get_display_text(self): - return (self.get_node().get_key() + ": " + + return (self.get_node().get_key() + ": " + str(self.get_node().get_value())) def next_inorder(self): @@ -140,7 +140,7 @@ class TreeWidget(urwid.WidgetWrap): """Handle expand & collapse requests (non-leaf nodes)""" if self.is_leaf: return key - + if key in ("+", "right"): self.expanded = True self.update_expanded_icon() @@ -151,7 +151,7 @@ class TreeWidget(urwid.WidgetWrap): return self.__super.keypress(size, key) else: return key - + def mouse_event(self, size, event, button, col, row, focus): if self.is_leaf or event != 'mouse press' or button!=1: return False @@ -160,12 +160,12 @@ class TreeWidget(urwid.WidgetWrap): self.expanded = not self.expanded self.update_expanded_icon() return True - + return False def first_child(self): """Return first child if expanded.""" - if self.is_leaf or not self.expanded: + if self.is_leaf or not self.expanded: return None else: if self._node.has_children(): @@ -193,7 +193,7 @@ class TreeWidget(urwid.WidgetWrap): class TreeNode(object): """ - Store tree contents and cache TreeWidget objects. + Store tree contents and cache TreeWidget objects. A TreeNode consists of the following elements: * key: accessor token for parent nodes * value: subclass-specific data @@ -215,14 +215,14 @@ class TreeNode(object): def load_widget(self): return TreeWidget(self) - + def get_depth(self): if self._depth is None and self._parent is None: self._depth = 0 elif self._depth is None: self._depth = self._parent.get_depth() + 1 return self._depth - + def get_index(self): if self.get_depth() == 0: return None @@ -244,19 +244,19 @@ class TreeNode(object): if self._parent == None and self.get_depth() > 0: self._parent = self.load_parent() return self._parent - + def load_parent(self): """Provide TreeNode with a parent for the current node. This function is only required if the tree was instantiated from a child node (virtual function)""" raise TreeWidgetError("virtual function. Implement in subclass") - + def get_value(self): return self._value def is_root(self): return self.get_depth() == 0 - + def next_sibling(self): if self.get_depth() > 0: return self.get_parent().next_child(self.get_key()) @@ -274,8 +274,8 @@ class TreeNode(object): while root.get_parent() is not None: root = root.get_parent() return root - - + + class ParentNode(TreeNode): """Maintain sort order for TreeNodes.""" def __init__(self, value, parent=None, key=None, depth=None): @@ -297,7 +297,7 @@ class ParentNode(TreeNode): def get_child_widget(self, key): """Return the widget for a given key. Create if necessary.""" - + child = self.get_child_node(key) return child.get_widget() @@ -312,10 +312,10 @@ class ParentNode(TreeNode): raise TreeWidgetError("virtual function. Implement in subclass") def set_child_node(self, key, node): - """Set the child node for a given key. Useful for bottom-up, lazy + """Set the child node for a given key. Useful for bottom-up, lazy population of a tree..""" self._children[key]=node - + def change_child_key(self, oldkey, newkey): if newkey in self._children: raise TreeWidgetError("%s is already in use" % newkey) @@ -328,7 +328,7 @@ class ParentNode(TreeNode): except ValueError: errorstring = ("Can't find key %s in ParentNode %s\n" + "ParentNode items: %s") - raise TreeWidgetError(errorstring % (key, self.get_key(), + raise TreeWidgetError(errorstring % (key, self.get_key(), str(self.get_child_keys()))) def next_child(self, key): @@ -339,7 +339,7 @@ class ParentNode(TreeNode): if index is None: return None index += 1 - + child_keys = self.get_child_keys() if index < len(child_keys): # get the next item at same level @@ -355,7 +355,7 @@ class ParentNode(TreeNode): child_keys = self.get_child_keys() index -= 1 - + if index >= 0: # get the previous item at same level return self.get_child_node(child_keys[index]) @@ -366,12 +366,12 @@ class ParentNode(TreeNode): """Return the first TreeNode in the directory.""" child_keys = self.get_child_keys() return self.get_child_node(child_keys[0]) - + def get_last_child(self): """Return the last TreeNode in the directory.""" child_keys = self.get_child_keys() return self.get_child_node(child_keys[-1]) - + def has_children(self): """Does this node have any children?""" return len(self.get_child_keys())>0 @@ -379,9 +379,9 @@ class ParentNode(TreeNode): class TreeWalker(urwid.ListWalker): """ListWalker-compatible class for displaying TreeWidgets - + positions are TreeNodes.""" - + def __init__(self, start_from): """start_from: TreeNode with the initial focus.""" self.focus = start_from @@ -389,7 +389,7 @@ class TreeWalker(urwid.ListWalker): def get_focus(self): widget = self.focus.get_widget() return widget, self.focus - + def set_focus(self, focus): self.focus = focus self._modified() @@ -431,13 +431,13 @@ class TreeListBox(urwid.ListBox): self.focus_end(size) else: return input - + def collapse_focus_parent(self, size): """Collapse parent directory.""" widget, pos = self.body.get_focus() self.move_focus_to_parent(size) - + pwidget, ppos = self.body.get_focus() if pos != ppos: self.keypress(size, "-") @@ -446,12 +446,12 @@ class TreeListBox(urwid.ListBox): """Move focus to parent of widget in focus.""" widget, pos = self.body.get_focus() - + parentpos = pos.get_parent() - + if parentpos is None: return - + middle, top, bottom = self.calculate_visible( size ) row_offset, focus_widget, focus_pos, focus_rows, cursor = middle @@ -464,7 +464,7 @@ class TreeListBox(urwid.ListBox): return self.change_focus(size, pos.get_parent()) - + def focus_home(self, size): """Move focus to very top.""" diff --git a/urwid/util.py b/urwid/util.py index 12becca..ced247e 100644 --- a/urwid/util.py +++ b/urwid/util.py @@ -72,7 +72,7 @@ def set_encoding( encoding ): if encoding in ( 'utf-8', 'utf8', 'utf' ): str_util.set_byte_encoding("utf8") - + _use_dec_special = False elif encoding in ( 'euc-jp' # JISX 0208 only , 'euc-kr', 'euc-cn', 'euc-tw' # CNS 11643 plain 1 only @@ -80,7 +80,7 @@ def set_encoding( encoding ): # these shouldn't happen, should they? , 'eucjp', 'euckr', 'euccn', 'euctw', 'cncb' ): str_util.set_byte_encoding("wide") - + _use_dec_special = True else: str_util.set_byte_encoding("narrow") @@ -88,7 +88,7 @@ def set_encoding( encoding ): # if encoding is valid for conversion from unicode, remember it _target_encoding = 'ascii' - try: + try: if encoding: u"".encode(encoding) _target_encoding = encoding @@ -114,7 +114,7 @@ def apply_target_encoding( s ): s = s.translate( escape.DEC_SPECIAL_CHARMAP ) except NotImplementedError: # python < 2.4 needs to do this the hard way.. - for c, alt in zip(escape.DEC_SPECIAL_CHARS, + for c, alt in zip(escape.DEC_SPECIAL_CHARS, escape.ALT_DEC_SPECIAL_CHARS): s = s.replace( c, escape.SO+alt+escape.SI ) @@ -136,10 +136,10 @@ def apply_target_encoding( s ): if sis0: sout.append( sis0 ) cout.append( (None,len(sis0)) ) - + if len(sis)==1: return sis0, cout - + for sn in sis[1:]: assert isinstance(sn, bytes) assert isinstance(SI, bytes) @@ -200,7 +200,7 @@ def calc_trim_text( text, start_offs, end_offs, start_col, end_col ): spos, sc = calc_text_pos( text, spos, end_offs, start_col ) if sc < start_col: pad_left = 1 - spos, sc = calc_text_pos( text, start_offs, + spos, sc = calc_text_pos( text, start_offs, end_offs, start_col+1 ) run = end_col - start_col - pad_left pos, sc = calc_text_pos( text, spos, end_offs, run ) @@ -215,7 +215,7 @@ def trim_text_attr_cs( text, attr, cs, start_col, end_col ): """ Return ( trimmed text, trimmed attr, trimmed cs ). """ - spos, epos, pad_left, pad_right = calc_trim_text( + spos, epos, pad_left, pad_right = calc_trim_text( text, 0, len(text), start_col, end_col ) attrtr = rle_subseg( attr, spos, epos ) cstr = rle_subseg( cs, spos, epos ) @@ -263,7 +263,7 @@ def rle_subseg( rle, start, end ): break if x+run > end: run = end-x - x += run + x += run l.append( (a, run) ) return l @@ -273,7 +273,7 @@ def rle_len( rle ): Return the number of characters covered by a run length encoded attribute list. """ - + run = 0 for v in rle: assert type(v) == tuple, repr(rle) @@ -290,19 +290,19 @@ def rle_append_beginning_modify( rle, (a, r) ): """ if not rle: rle[:] = [(a, r)] - else: + else: al, run = rle[0] if a == al: rle[0] = (a,run+r) else: rle[0:0] = [(al, r)] - - + + def rle_append_modify( rle, (a, r) ): """ Append (a,r) to the rle list rle. Merge with last run when possible. - + MODIFIES rle parameter contents. Returns None. """ if not rle or rle[-1][0] != a: @@ -322,7 +322,7 @@ def rle_join_modify( rle, rle2 ): return rle_append_modify(rle, rle2[0]) rle += rle2[1:] - + def rle_product( rle1, rle2 ): """ Merge the runs of rle1 and rle2 like this: @@ -337,7 +337,7 @@ def rle_product( rle1, rle2 ): if not rle1 or not rle2: return [] a1, r1 = rle1[0] a2, r2 = rle2[0] - + l = [] while r1 and r2: r = min(r1, r2) @@ -350,7 +350,7 @@ def rle_product( rle1, rle2 ): if r2 == 0 and i2< len(rle2): a2, r2 = rle2[i2] i2 += 1 - return l + return l def rle_factor( rle ): @@ -381,13 +381,13 @@ def decompose_tagmarkup(tm): def _tagmarkup_recurse( tm, attr ): """Return (text list, attribute list) for tagmarkup passed. - + tm -- tagmarkup attr -- current attribute or None""" - + if type(tm) == list: # for lists recurse to process each subelement - rtl = [] + rtl = [] ral = [] for element in tm: tl, al = _tagmarkup_recurse( element, attr ) @@ -401,18 +401,18 @@ def _tagmarkup_recurse( tm, attr ): rtl += tl ral += al return rtl, ral - + if type(tm) == tuple: # tuples mark a new attribute boundary - if len(tm) != 2: + if len(tm) != 2: raise TagMarkupException, "Tuples must be in the form (attribute, tagmarkup): %r" % (tm,) attr, element = tm return _tagmarkup_recurse( element, attr ) - + if not isinstance(tm,(basestring, bytes)): raise TagMarkupException, "Invalid markup element: %r" % tm - + # text return [tm], [(attr, len(tm))] @@ -435,11 +435,11 @@ class MetaSuper(type): setattr(cls, "_%s__super" % name, super(cls)) - + def int_scale(val, val_range, out_range): """ - Scale val in the range [0, val_range-1] to an integer in the range - [0, out_range-1]. This implementation uses the "round-half-up" rounding + Scale val in the range [0, val_range-1] to an integer in the range + [0, out_range-1]. This implementation uses the "round-half-up" rounding method. >>> "%x" % int_scale(0x7, 0x10, 0x10000) diff --git a/urwid/web_display.py b/urwid/web_display.py index 69aa1ad..e18555e 100755 --- a/urwid/web_display.py +++ b/urwid/web_display.py @@ -77,8 +77,8 @@ keycodes = { 33: "page up", 34: "page down", 35: "end", 36: "home", 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "delete", - 112: "f1", 113: "f2", 114: "f3", 115: "f4", - 116: "f5", 117: "f6", 118: "f7", 119: "f8", + 112: "f1", 113: "f2", 114: "f3", 115: "f4", + 116: "f5", 117: "f6", 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11", 123: "f12" }; @@ -179,16 +179,16 @@ function handle_recv() { urwid_id = conn.getResponseHeader("X-Urwid-ID"); if( send_queue_in != send_queue_out ){ // keys waiting - do_send(); + do_send(); } if(update_method=="polling"){ set_status("Polling"); }else if(update_method=="multipart"){ set_status("Connected"); } - + } - + if( conn.responseText == "" ){ if(update_method=="polling"){ poll_again(); @@ -200,14 +200,14 @@ function handle_recv() { update_method = null; return; } - + var text = document.getElementById('text'); - + var last_screen = Array(text.childNodes.length); for( var i=0; i<text.childNodes.length; i++ ){ last_screen[i] = text.childNodes[i]; } - + var frags = conn.responseText.split("\n"); var ln = document.createElement('span'); var k = 0; @@ -244,7 +244,7 @@ function handle_recv() { for( var i=k; i < text.childNodes.length; i++ ){ text.removeChild(last_screen[i]); } - + if(update_method=="polling"){ poll_again(); } @@ -263,17 +263,17 @@ function load_web_display(){ }else{ document_location = document.location; } - + document.onkeypress = body_keypress; document.onkeydown = body_keydown; document.onresize = body_resize; - + body_resize(); send_queue_out = send_queue_in; // don't queue the first resize set_status("Connecting"); setup_connection(); - + setTimeout("check_fontsize();",check_font_delay); } @@ -288,7 +288,7 @@ function make_span(s, fg, bg){ d.style.backgroundColor = colours[bg]; d.style.color = colours[fg]; d.appendChild(document.createTextNode(s)); - + return d; } @@ -308,7 +308,7 @@ function body_keydown(e){ if( e.shiftKey && e.charCode == 0 ){ mod = "shift " + mod; } key = keycodes[code]; - + if( key != undefined ){ lastkeydown = key; send_key( mod + key ); @@ -332,7 +332,7 @@ function body_keypress(e){ if( e.ctrlKey ){ mod = "ctrl " + mod; } if( e.altKey || e.metaKey ){ mod = "meta " + mod; } if( e.shiftKey && e.charCode == 0 ){ mod = "shift " + mod; } - + if( e.charCode != null && e.charCode != 0 ){ key = String.fromCharCode(e.charCode); }else if( e.charCode == null ){ @@ -345,7 +345,7 @@ function body_keypress(e){ return false; } } - + send_key( mod + key ); stop_key_event(e); return false; @@ -382,11 +382,11 @@ function do_send() { if( ! urwid_id ){ return; } if( ! update_method ){ return; } // connection closed if( send_queue_in == send_queue_out ){ return; } - if( sending ){ + if( sending ){ //var queue_delta = send_queue_in - send_queue_out; //if( queue_delta < 0 ){ queue_delta += send_queue_max; } - //set_status("Sending (queued "+queue_delta+")"); - return; + //set_status("Sending (queued "+queue_delta+")"); + return; } try{ sending = true; @@ -442,9 +442,9 @@ function send_handle_recv() { alert("Error from server: "+send_conn.statusText); return; } - + sending = false; - + if( send_queue_out != send_queue_in ){ send_more(); } @@ -479,12 +479,12 @@ function body_resize(){ var avail_width = window_width-18; var avail_width_mod = avail_width % char_width; var x_size = (avail_width - avail_width_mod)/char_width; - + char_height = t2.offsetTop - t.offsetTop; var avail_height = window_height-text.offsetTop-10; var avail_height_mod = avail_height % char_height; var y_size = (avail_height - avail_height_mod)/char_height; - + text.style.width = x_size*char_width+"px"; text.style.height = y_size*char_height+"px"; @@ -527,7 +527,7 @@ _code_colours = { _trans_table = "?" * 32 + "".join([chr(x) for x in range(32, 256)]) _css_style = """ -body { margin: 8px 8px 8px 8px; border: 0; +body { margin: 8px 8px 8px 8px; border: 0; color: black; background-color: silver; font-family: fixed; overflow: hidden; } @@ -554,7 +554,7 @@ _html_page = [ </head> <body id="body" onload="load_web_display()"> <div style="position:absolute; visibility:hidden;"> -<br id="br"\> +<br id="br"\> <pre>The quick brown fox jumps over the lazy dog.<span id="testchar">X</span> <span id="testchar2">Y</span></pre> </div> @@ -575,9 +575,9 @@ class Screen: self.palette = {} self.has_color = True self._started = False - + started = property(lambda self: self._started) - + def register_palette( self, l ): """Register a list of palette entries. @@ -586,7 +586,7 @@ class Screen: calls self.register_palette_entry for each item in l """ - + for item in l: if len(item) in (3,4): self.register_palette_entry( *item ) @@ -597,7 +597,7 @@ class Screen: raise Exception("palette entry '%s' doesn't exist"%like_name) self.palette[name] = self.palette[like_name] - def register_palette_entry( self, name, foreground, background, + def register_palette_entry( self, name, foreground, background, mono=None): """Register a single palette entry. @@ -623,17 +623,17 @@ class Screen: pass def start(self): - """ + """ This function reads the initial screen size, generates a unique id and handles cleanup when fn exits. - + web_display.set_preferences(..) must be called before calling this function for the preferences to take effect """ global _prefs assert not self._started - + client_init = sys.stdin.read(50) assert client_init.startswith("window resize "),client_init ignore1,ignore2,x,y = client_init.split(" ",3) @@ -642,26 +642,26 @@ class Screen: self._set_screen_size( x, y ) self.last_screen = {} self.last_screen_width = 0 - + self.update_method = os.environ["HTTP_X_URWID_METHOD"] assert self.update_method in ("multipart","polling") - + if self.update_method == "polling" and not _prefs.allow_polling: sys.stdout.write("Status: 403 Forbidden\r\n\r\n") sys.exit(0) - + clients = glob.glob(os.path.join(_prefs.pipe_dir,"urwid*.in")) if len(clients) >= _prefs.max_clients: sys.stdout.write("Status: 503 Sever Busy\r\n\r\n") sys.exit(0) - + urwid_id = "%09d%09d"%(random.randrange(10**9), random.randrange(10**9)) self.pipe_name = os.path.join(_prefs.pipe_dir,"urwid"+urwid_id) os.mkfifo(self.pipe_name+".in",0600) signal.signal(signal.SIGTERM,self._cleanup_pipe) - - self.input_fd = os.open(self.pipe_name+".in", + + self.input_fd = os.open(self.pipe_name+".in", os.O_NONBLOCK | os.O_RDONLY) self.input_tail = "" self.content_head = ("Content-type: " @@ -674,14 +674,14 @@ class Screen: "Content-type: text/plain\r\n" "X-Urwid-ID: "+urwid_id+"\r\n" "\r\n\r\n") - + signal.signal(signal.SIGALRM,self._handle_alarm) signal.alarm( ALARM_DELAY ) self._started = True def stop(self): """ - Restore settings and clean up. + Restore settings and clean up. """ assert self._started # XXX which exceptions does this actually raise? EnvironmentError? @@ -692,7 +692,7 @@ class Screen: signal.signal(signal.SIGTERM,signal.SIG_DFL) self._cleanup_pipe() self._started = False - + def set_input_timeouts(self, *args): pass @@ -731,21 +731,21 @@ class Screen: def _set_screen_size(self, cols, rows ): """Set the screen size (within max size).""" - + if cols > MAX_COLS: cols = MAX_COLS if rows > MAX_ROWS: rows = MAX_ROWS self.screen_size = cols, rows - + def draw_screen(self, (cols, rows), r ): """Send a screen update to the client.""" - + if cols != self.last_screen_width: self.last_screen = {} - + sendq = [self.content_head] - + if self.update_method == "polling": send = sendq.append elif self.update_method == "polling child": @@ -760,23 +760,23 @@ class Screen: send = sendq.append send("\r\n") self.content_head = "" - + assert r.rows() == rows - + if r.cursor is not None: cx, cy = r.cursor else: cx = cy = None - + new_screen = {} - + y = -1 for row in r.content(): y += 1 row = list(row) - + l = [] - + sig = tuple(row) if y == cy: sig = sig + (cx,) new_screen[sig] = new_screen.get(sig,[]) + [y] @@ -788,7 +788,7 @@ class Screen: old_line = old_line_numbers[0] send( "<%d\n"%old_line ) continue - + col = 0 for (a, cs, run) in row: run = run.translate(_trans_table) @@ -797,7 +797,7 @@ class Screen: else: fg,bg,mono = self.palette[a] if y == cy and col <= cx: - run_width = util.calc_width(run, 0, + run_width = util.calc_width(run, 0, len(run)) if col+run_width > cx: l.append(code_span(run, fg, bg, @@ -811,7 +811,7 @@ class Screen: send("".join(l)+"\n") self.last_screen = new_screen self.last_screen_width = cols - + if self.update_method == "polling": sys.stdout.write("".join(sendq)) sys.stdout.flush() @@ -823,9 +823,9 @@ class Screen: send("\r\n--ZZ\r\n") sys.stdout.write("".join(sendq)) sys.stdout.flush() - + signal.alarm( ALARM_DELAY ) - + def clear(self): """ @@ -843,7 +843,7 @@ class Screen: Force parent process to exit. """ daemonize( self.pipe_name +".err" ) - self.input_fd = os.open(self.pipe_name+".in", + self.input_fd = os.open(self.pipe_name+".in", os.O_NONBLOCK | os.O_RDONLY) self.update_method = "polling child" s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -851,7 +851,7 @@ class Screen: s.listen(1) s.settimeout(POLL_CONNECT) self.server_socket = s - + def _handle_alarm(self, sig, frame): assert self.update_method in ("multipart","polling child") if self.update_method == "polling child": @@ -866,8 +866,8 @@ class Screen: sys.stdout.write("\r\n\r\n--ZZ\r\n") sys.stdout.flush() signal.alarm( ALARM_DELAY ) - - + + def get_cols_rows(self): """Return the screen size.""" return self.screen_size @@ -876,13 +876,13 @@ class Screen: """Return pending input as a list.""" l = [] resized = False - + try: iready,oready,eready = select.select( [self.input_fd],[],[],0.5) except select.error, e: # return on interruptions - if e.args[0] == 4: + if e.args[0] == 4: if raw_keys: return [],[] return [] @@ -892,16 +892,16 @@ class Screen: if raw_keys: return [],[] return [] - + keydata = os.read(self.input_fd, MAX_READ) os.close(self.input_fd) - self.input_fd = os.open(self.pipe_name+".in", + self.input_fd = os.open(self.pipe_name+".in", os.O_NONBLOCK | os.O_RDONLY) #sys.stderr.write( repr((keydata,self.input_tail))+"\n" ) keys = keydata.split("\n") keys[0] = self.input_tail + keys[0] self.input_tail = keys[-1] - + for k in keys[:-1]: if k.startswith("window resize "): ign1,ign2,x,y = k.split(" ",3) @@ -913,16 +913,16 @@ class Screen: l.append(k) if resized: l.append("window resize") - + if raw_keys: return l, [] return l - + def code_span( s, fg, bg, cursor = -1): code_fg = _code_colours[ fg ] code_bg = _code_colours[ bg ] - + if cursor >= 0: c_off, _ign = util.calc_text_pos(s, 0, len(s), cursor) c2_off = util.move_next_char(s, c_off, len(s)) @@ -941,7 +941,7 @@ def html_escape(text): text = text.replace('>','>') return text - + def is_web_request(): """ Return True if this is a CGI web request. @@ -959,20 +959,20 @@ def handle_short_request(): function for the preferences to take effect """ global _prefs - + if not is_web_request(): return False - + if os.environ['REQUEST_METHOD'] == "GET": # Initial request, send the HTML and javascript. sys.stdout.write("Content-type: text/html\r\n\r\n" + html_escape(_prefs.app_name).join(_html_page)) return True - + if os.environ['REQUEST_METHOD'] != "POST": # Don't know what to do with head requests etc. return False - + if not os.environ.has_key('HTTP_X_URWID_ID'): # If no urwid id, then the application should be started. return False @@ -989,7 +989,7 @@ def handle_short_request(): #assert 0, "invalid chars in id!" sys.stdout.write("Status: 403 Forbidden\r\n\r\n") return True - + if os.environ.get('HTTP_X_URWID_METHOD',None) == "polling": # this is a screen update request s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -1030,16 +1030,16 @@ class _Preferences: _prefs = _Preferences() -def set_preferences( app_name, pipe_dir="/tmp", allow_polling=True, +def set_preferences( app_name, pipe_dir="/tmp", allow_polling=True, max_clients=20 ): """ Set web_display preferences. - + app_name -- application name to appear in html interface - pipe_dir -- directory for input pipes, daemon update sockets + pipe_dir -- directory for input pipes, daemon update sockets and daemon error logs - allow_polling -- allow creation of daemon processes for - browsers without multipart support + allow_polling -- allow creation of daemon processes for + browsers without multipart support max_clients -- maximum concurrent client connections. This pool is shared by all urwid applications using the same pipe_dir diff --git a/urwid/widget.py b/urwid/widget.py index 44abd2c..661e7ed 100644 --- a/urwid/widget.py +++ b/urwid/widget.py @@ -171,7 +171,7 @@ def nocache_widget_render(cls): def nocache_widget_render_instance(self): """ Return a function that wraps the cls.render() method - and finalizes the canvas that it returns, but does not + and finalizes the canvas that it returns, but does not cache the canvas. """ fn = self.render.original_fn @@ -852,10 +852,10 @@ class Text(Widget): def _repr_attrs(self): attrs = dict(self.__super._repr_attrs(), - align=self._align_mode, + align=self._align_mode, wrap=self._wrap_mode) return remove_defaults(attrs, Text.__init__) - + def _invalidate(self): self._cache_maxcol = None self.__super._invalidate() @@ -1497,7 +1497,7 @@ class Edit(Text): x,y = self.get_cursor_coords((maxcol,)) pref_col = self.get_pref_col((maxcol,)) assert pref_col is not None - #if pref_col is None: + #if pref_col is None: # pref_col = x if self._command_map[key] == CURSOR_UP: y -= 1 @@ -1511,7 +1511,7 @@ class Edit(Text): if not self._delete_highlighted(): if p == 0: return key p = move_prev_char(self.edit_text,0,p) - self.set_edit_text( self.edit_text[:p] + + self.set_edit_text( self.edit_text[:p] + self.edit_text[self.edit_pos:] ) self.set_edit_pos( p ) |