def render(self, size, focus=False): maxcol, maxrow = size # Render complete original widget ow = self._original_widget ow_size = self._get_original_widget_size(size) canv = urwid.CompositeCanvas(ow.render(ow_size, focus)) canv_cols, canv_rows = canv.cols(), canv.rows() if canv_cols <= maxcol: pad_width = maxcol - canv_cols if pad_width > 0: # Canvas is narrower than available horizontal space canv.pad_trim_left_right(0, pad_width) if canv_rows <= maxrow: fill_height = maxrow - canv_rows if fill_height > 0: # Canvas is lower than available vertical space canv.pad_trim_top_bottom(0, fill_height) self._rows_max_displayable = maxrow if canv_cols <= maxcol and canv_rows <= maxrow: # Canvas is small enough to fit without trimming return canv self._adjust_trim_top(canv, size) # Trim canvas if necessary trim_top = self._trim_top trim_end = canv_rows - maxrow - trim_top trim_right = canv_cols - maxcol if trim_top > 0: canv.trim(trim_top) if trim_end > 0: canv.trim_end(trim_end) if trim_right > 0: canv.pad_trim_left_right(0, -trim_right) # Disable cursor display if cursor is outside of visible canvas parts if canv.cursor is not None: curscol, cursrow = canv.cursor if cursrow >= maxrow or cursrow < 0: canv.cursor = None # Let keypress() know if original_widget should get keys self._forward_keypress = bool(canv.cursor) return canv
def __init__(self, w, attr=None): self._area = ScrollArea(w) self._hscroll = HScrollBar(attr) self._vscroll = VScrollBar(attr) self._inscroll = None self._corner = urwid.CompositeCanvas( urwid.TextCanvas(u' '.encode(u'utf-8'))) self._corner.fill_attr(attr) # connect up the signals between the area and scrollbar urwid.connect_signal(self._area, u'modified', self._scroll_area_modified) urwid.connect_signal(self._hscroll, u'scroll', self._scroll_by_bar) urwid.connect_signal(self._vscroll, u'scroll', self._scroll_by_bar) # calculate scroll dir - on OSX 10.8 its reversed self._scrolldelta = 1 if platform.mac_ver()[0].startswith('10.'): if int(platform.mac_ver()[0].split('.')[1]) >= 8: self._scrolldelta = -1
def render(seld, size, focus=False): maxcol, maxrow = size ow = self._original_widget ow_size = self._get_original_widget_size(size) canv = urwid.CompositeCanvas(ow.render(ow_size, focus)) canv_cols = canv.cols() canv_rows = canv.rows() if canv_cols <= maxcol: pad_width = maxcol - canv_cols if pad_width > 0: canv.pad_trim_left_right(0, pad_width) if canv_rows <= maxrow: fill_height = maxrow - canv_rows if fill_height > 0: canv.pad_trim_top_bottom(0, fill_height) self._rows_max_displayable = maxrow if canv_cols <= maxcol and cav_rows <= maxrow: return canv self._adjust_trim_top(canv, size) trim_top = self._trim_top trim_end = canv_rows - maxrow - trip_top trim_right = canv_cols - maxcol if trim_top > 0: canv.trim(trim_top) if trim_end > 0: canv.trim_end(trim_end) if trim_right > 0: canv.pad_trim_left_right(0. - trim_right) if canv.cursor is not None: curscol, cursrow = canv.cursor if cursrow >= maxrow or cursrow < 0: canv.cursor = None self._forward_keypress = bool(canv.cursor) return canv
def render(self, size, focus=False): maxcol, maxrow = size bottom_c = self.bottom_w.render(size, focus) cursor = bottom_c.cursor if not cursor: # Hide the tooltip if there is no cursor. return bottom_c cursor_x, cursor_y = cursor if cursor_y * 2 < maxrow: # Cursor is in the top half. Tooltip goes below it: y = cursor_y + 1 rows = maxrow - y else: # Cursor is in the bottom half. Tooltip fills the area above: y = 0 rows = cursor_y # HACK: shrink-wrap the tooltip. This is ugly in multiple ways: # - It only works on a listbox. # - It assumes the wrapping LineBox eats one char on each edge. # - It is a loop. # (ideally it would check how much free space there is, # instead of repeatedly trying smaller sizes) while 'bottom' in self.listbox.ends_visible((maxcol - 2, rows - 3)): rows -= 1 # If we're displaying above the cursor move the top edge down: if not y: y = cursor_y - rows # Render *both* windows focused. This is probably not normal in urwid, # but it works nicely. top_c = self.top_w.render((maxcol, rows), focus and self.tooltip_focus) combi_c = urwid.CanvasOverlay(top_c, bottom_c, 0, y) # Use the cursor coordinates from the bottom canvas. canvas = urwid.CompositeCanvas(combi_c) canvas.cursor = cursor return canvas
def render(self, size, focus=False): size = Size(*size) map = self.world.current_map map_rect = map.rect player_position = map.find(self.world.player).position if not self.viewport: # Let's pretend the map itself is the viewport, and the below logic # can adjust it as necessary. self.viewport = self.world.current_map.rect horizontal = self._adjust_viewport( self.viewport.horizontal_span, size.width, player_position.x, map.rect.horizontal_span, ) vertical = self._adjust_viewport( self.viewport.vertical_span, size.height, player_position.y, map.rect.vertical_span, ) self.viewport = Rectangle.from_spans(horizontal=horizontal, vertical=vertical) # viewport is from the pov of the map; negate it to get how much space # is added or removed around the map pad_left = -self.viewport.left pad_top = -self.viewport.top pad_right = (size.width - pad_left) - map_rect.width pad_bottom = (size.height - pad_top) - map_rect.height # TODO it's unclear when you're near the edge of the map, which i hate. # should either show a clear border past the map edge, or show some # kinda fade or whatever along a cut-off edge map_canvas = urwid.CompositeCanvas(CellCanvas(map)) map_canvas.pad_trim_left_right(pad_left, pad_right) map_canvas.pad_trim_top_bottom(pad_top, pad_bottom) return map_canvas
def render(self, size, focus=False): """ Apply the class attr_name and focus_name on top of the widget canvas. This is an alternative way of doing AttrMap(widget, ...) without needing to wrap every instance of the class with an AttrMap. """ mode = ["FIXED", "FLOW", "BOX"][len(size)] logger.debug(f"Rendering {self} as {mode} (focus={focus})") if focus and self.focus_name is not None: attr_map = {None: self.focus_name} elif self.attr_name: attr_map = {None: self.attr_name} else: attr_map = None canvas = super().render(size, focus=focus) if attr_map is not None: canvas = urwid.CompositeCanvas(canvas) canvas.fill_attr_apply(attr_map) return canvas
def render(self, size, focus=False): (maxcol,) = size canv = self._w.render((maxcol,)) canv = urwid.CompositeCanvas(canv) canv.cursor = self.get_cursor_coords((maxcol,)) return canv
def render(self, size, focus=False): canv = super().render(size, focus) if focus: canv = urwid.CompositeCanvas(canv) canv.cursor = 1, 0 return canv
def render(self, size, focus=False): maxcol, maxrow = size # Render complete original widget ow = self._original_widget ow_size = self._get_original_widget_size(size) canv_full = ow.render(ow_size, focus) # Make full canvas editable canv = urwid.CompositeCanvas(canv_full) canv_cols, canv_rows = canv.cols(), canv.rows() if canv_cols <= maxcol: pad_width = maxcol - canv_cols if pad_width > 0: # Canvas is narrower than available horizontal space canv.pad_trim_left_right(0, pad_width) if canv_rows <= maxrow: fill_height = maxrow - canv_rows if fill_height > 0: # Canvas is lower than available vertical space canv.pad_trim_top_bottom(0, fill_height) if canv_cols <= maxcol and canv_rows <= maxrow: # Canvas is small enough to fit without trimming return canv self._adjust_trim_top(canv, size) # Trim canvas if necessary trim_top = self._trim_top trim_end = canv_rows - maxrow - trim_top trim_right = canv_cols - maxcol if trim_top > 0: canv.trim(trim_top) if trim_end > 0: canv.trim_end(trim_end) if trim_right > 0: canv.pad_trim_left_right(0, -trim_right) # Disable cursor display if cursor is outside of visible canvas parts if canv.cursor is not None: curscol, cursrow = canv.cursor if cursrow >= maxrow or cursrow < 0: canv.cursor = None # Figure out whether we should forward keypresses to original widget if canv.cursor is not None: # Trimmed canvas contains the cursor, e.g. in an Edit widget self._forward_keypress = True else: if canv_full.cursor is not None: # Full canvas contains the cursor, but scrolled out of view self._forward_keypress = False else: # Original widget does not have a cursor, but may be selectable # FIXME: Using ow.selectable() is bad because the original # widget may be selectable because it's a container widget with # a key-grabbing widget that is scrolled out of view. # ow.selectable() returns True anyway because it doesn't know # how we trimmed our canvas. # # To fix this, we need to resolve ow.focus and somehow # ask canv whether it contains bits of the focused widget. I # can't see a way to do that. if ow.selectable(): self._forward_keypress = True else: self._forward_keypress = False return canv
canv = self.__super.render((maxcol, ), focus) # The cache messes this thing up, because I am totally changing what # is displayed. self._invalidate() return canv # Else, we have a slight mess to deal with... self._shift_view_to_cursor = not not focus # force bool text, attr = self.get_text() text = text[:len(self.caption)] + self.get_masked_text() trans = self.get_line_translation(maxcol, (text, attr)) canv = urwid.canvas.apply_text_layout(text, attr, trans, maxcol) if focus: canv = urwid.CompositeCanvas(canv) canv.cursor = self.get_cursor_coords((maxcol, )) return canv class TabColumns(urwid.WidgetWrap): """ Tabbed interface, mostly for use in the Preferences Dialog titles_dict = dictionary of tab_contents (a SelText) : tab_widget (box) attr = normal attributes attrsel = attribute when active """ # FIXME Make the bottom_part optional # pylint: disable-msg=W0231
def cptest(self, desc, ct, ca, l, r, et): ct = B(ct) c = urwid.CompositeCanvas(urwid.TextCanvas([ct], [ca])) c.pad_trim_left_right(l, r) result = list(c.content()) assert result == et, "%s expected %r, got %r" % (desc, et, result)
def render(self, size, focus=False): """Render listbox and return canvas. """ (maxcol, maxrow) = size middle, top, bottom = self.calculate_visible((maxcol, maxrow), focus=focus) if middle is None: return urwid.SolidCanvas(" ", maxcol, maxrow) _ignore, focus_widget, focus_pos, focus_rows, cursor = middle trim_top, fill_above = top trim_bottom, fill_below = bottom if bottom[1]: self._bottom_pos = bottom[1][-1][1] else: self._bottom_pos = None if top[1]: self._top_pos = top[1][-1][1] else: self._top_pos = None self._focus_pos = focus_pos combinelist = [] rows = 0 fill_above.reverse() # fill_above is in bottom-up order for widget, w_pos, w_rows in fill_above: canvas = widget.render((maxcol, )) attr = self.get_row_attr(w_pos) if attr: canvas = urwid.CompositeCanvas(canvas) canvas.fill_attr(attr) if w_rows != canvas.rows(): raise urwid.ListBoxError, BADROWSMSG % ( ` widget `, ` w_pos `, w_rows, canvas.rows()) rows += w_rows combinelist.append((canvas, w_pos, False)) focus_canvas = focus_widget.render((maxcol, ), focus=focus) focus_attr = None if focus_pos in self.row_attrs: focus_attr = self.get_row_attr(focus_pos) if focus and self.focus_str: focus_attr += self.focus_str elif focus: focus_attr = self.focus_attr if focus_attr: focus_canvas = urwid.CompositeCanvas(focus_canvas) focus_canvas.fill_attr(focus_attr) if focus_canvas.rows() != focus_rows: raise ListBoxError, BADFOCUSROWSMSG % ( ` focus_widget `, ` focus_pos `, focus_rows, focus_canvas.rows()) c_cursor = focus_canvas.cursor if cursor != c_cursor: raise urwid.ListBoxError, BADCURSORMSG % ( ` focus_widget `, ` focus_pos `, ` cursor `, ` c_cursor `) rows += focus_rows combinelist.append((focus_canvas, focus_pos, True)) for widget, w_pos, w_rows in fill_below: canvas = widget.render((maxcol, )) attr = self.get_row_attr(w_pos) if attr: canvas = urwid.CompositeCanvas(canvas) canvas.fill_attr(attr) if w_rows != canvas.rows(): raise urwid.ListBoxError, BADROWSMSG % ( ` widget `, ` w_pos `, w_rows, canvas.rows()) rows += w_rows combinelist.append((canvas, w_pos, False)) final_canvas = urwid.CanvasCombine(combinelist) if trim_top: final_canvas.trim(trim_top) rows -= trim_top if trim_bottom: final_canvas.trim_end(trim_bottom) rows -= trim_bottom assert rows <= maxrow if rows < maxrow: bottom_pos = focus_pos if fill_below: bottom_pos = fill_below[-1][1] assert trim_bottom == 0 and self.body.get_next(bottom_pos) == ( None, None) final_canvas.pad_trim_top_bottom(0, maxrow - rows) return final_canvas
def render(self, size, focus=False): canvas = super(Line, self).render(size, focus=focus) if focus: canvas = urwid.CompositeCanvas(canvas) canvas.cursor = self.get_cursor_coords(size) return canvas