Canvas Classes
Parts of this page marked NEW have not been implemented yet.
canvases should only be modified immediately after they are created inside the function that creates them. Canvas objects are cached for later use and the cache assumes that they won't change once they're stored.
Canvas Hierarchy Changes
- Rename Canvas to TextCanvas NEW
- Create new base class called Canvas for all the canvas classes. NEW
Canvas NEW
This is the new base class of all canvas classes, for the old Canvas class see TextCanvas below.
- .cursor -- (x, y) cursor location relative to top left or None. this will look for a "cursor" in .coords
- .widget_info -- (widget, size, focus) values when creating this canvas or None if this canvas is a smaller part of a larger canvas being rendered by a widget.
- .shortcuts -- {shortcut key: None} dictionary. Shortcut keys that are handled by this widget
- .coords -- {coordinate name: (x, y, data)} dictionary. coordinates that may be used by parents of this widget. coordinate_name is a key for this coordinate, "cursor" is reserved. (x, y) is relative to top left of this canvas. data is extra data associated with this coordinate or None.
TextCanvas NEW
A canvas that stores text, attributes and character set information, typically rendered by a Text widget.
BlankCanvas
A canvas that is used by CompositeCanvas to pad other canvases. This canvas doesn't know its own size, so it can only be used as part of a CompositeCanvas.
blank_canvas is a global, shared, instance of BlankCanvas.
SolidCanvas
A canvas that is filled with a single character.
CompositeCanvas
- .shards -- flat content of this canvas (see below)
- .children -- list of (x, y, canvas, position) tuples. (x,y) is the top-left corner of canvas. position is the value to pass to widget.set_focus to make this child the one in focus, or None if that can't be done. If this widget is in focus the first item in .children is the child in focus. NEW
- .shortcuts -- {shortcut key: position} dictionary. inherited from children, storing child position for setting focus. NEW
shards
shards store a flat representation of the text, attributes and character set information to be displayed from a number of Canvas objects.
a "shard" is a (num_rows, list of cviews) tuple, one for each cview starting in this shard
- num_rows -- screen rows covered by this shard
- list of cviews -- cviews whose top-left corner is aligned with this shard in order from left to right
cviews
a "cview" is a tuple that defines a view of a Canvas: (trim_left, trim_top, cols, rows, def_attr, canv)
- trim_left -- number of screen columns to trim from left
- trim_top -- number of screen columns to trim from top
- cols -- number of screen columns to display
- rows -- number of screen rows to display
- def_attr -- default attribute for this canvas (replaces None attributes)
- canv -- a Canvas, BlankCanvas or SolidCanvas object
shards, cviews example
A CompositeCanvas that represents three canvases (A, B and C) rendered as follows:
AAAABBBBBBBBBB AAAABBBBBBBBBB AAAACCCCCCCCCC AAAACCCCCCCCCC AAAACCCCCCCCCC
would have a .shards value like:
[(2, # num_rows of first shard
[(0, 0, 4, 5, None, canvas_A), # first cview in first shard
(0, 0, 10, 2, None, canvas_B), # second cview in first shard
]
),
(3, # num_rows of second shard
[(0, 0, 10, 3, None, canvas_C), # first cview in second shard
]
),
]
coords example
The coords dictionary stored in each canvas is meant to be used for passing information from a child to a parent widget. The parent need not be the immediate parent, and it could even be the program itself that pulls the information from the topmost rendered canvas.
An example would be a select box that displays a window containing options for the user when activated. The select box would be a small widget, possibly displayed in a ListBox. The window it displays shouldn't expand the select box in the ListBox because that will move all the other content in the list box on screen. What we want is a window to appear aligned just below the select box, overlapping other content when it is active.
+ Frame (top-most widget)
+ ListBox
+ select box
We can insert another widget into this widget layout that will be used to display the select window:
+ Frame (top-most widget)
+ pop-up overlay
+ ListBox
+ select box
The pop-up overlay would typically do nothing, but when the select box is in focus and activated it adds an item to the coords dictionary in the canvas it returns:
canvas.coords["pop-up"] = (0, 1, select_callback_fn)
which says "record the coordinates (0, 1) relative to the select box's canvas with some data (in this case a callback function) as a 'pop-up'".
When the pop-up overlay checks for a "pop-up" coordinate in its child's canvas, it will get the coordinates relative to its child (the ListBox). If the select box is 10 rows down from the top of the ListBox this value will be in the ListBox's coords dictionary:
(0, 11, select_callback_fn)
The pop-up overlay can then call the callback function, passing in the size of the pop-up overlay (the same size as the ListBox) and the new coordinates which represent the position the select box wanted to display its window at.
The callback function can calculate if the window it wants to display will fit at the desired location (if not it might choose to place the window above the select box instead). The callback function will return a rendered canvas containing the window to display and the location to display it.
The pop-up overlay will then overlay the canvas on top of the ListBox as specified, using it as the focus.
Notice that the location of the pop-up overlay determines the screen area that pop-ups may occupy. A pop-up in this example widget layout would not be able to cover anything in the header or footer of the Frame (top-most widget)
