def render(self, cli, layout, style=None): """ Render the current interface to the output. """ style = style or Style output = self.output # When we render using another style, do a full repaint. (Forget about # the previous rendered screen.) if style != self._last_style: self._last_screen = None self._last_style = style # Enter alternate screen. if self.use_alternate_screen and not self._in_alternate_screen: self._in_alternate_screen = True output.enter_alternate_screen() # Create screen and write layout to it. size = output.get_size() screen = Screen(size.columns) if cli.is_done: height = 0 # When we are done, we don't necessary want to fill up until the bottom. else: height = self._last_screen.current_height if self._last_screen else 0 height = max(self._min_available_height, height) # When te size changes, don't consider the previous screen. if self._last_size != size: self._last_screen = None layout.write_to_screen( cli, screen, WritePosition( xpos=0, ypos=0, width=size.columns, height=(size.rows if self.use_alternate_screen else height), extended_height=size.rows, )) # When grayed. Replace all tokens in the new screen. if cli.is_aborting or cli.is_exiting: screen.replace_all_tokens(Token.Aborted) # Process diff and write to output. self._cursor_pos, self._last_char = output_screen_diff( output, screen, self._cursor_pos, self._last_screen, self._last_char, cli.is_done, style=style, ) self._last_screen = screen self._last_size = size output.flush()
def render(self, cli, layout, style=None, is_done=False): """ Render the current interface to the output. :param is_done: When True, put the cursor at the end of the interface. We won't print any changes to this part. """ style = style or Style output = self.output # Enter alternate screen. if self.use_alternate_screen and not self._in_alternate_screen: self._in_alternate_screen = True output.enter_alternate_screen() # Create screen and write layout to it. size = output.get_size() screen = Screen(size.columns) if is_done: height = 0 # When we are done, we don't necessary want to fill up until the bottom. else: height = self._last_screen.current_height if self._last_screen else 0 height = max(self._min_available_height, height) # When te size changes, don't consider the previous screen. if self._last_size != size: self._last_screen = None # When we render using another style, do a full repaint. (Forget about # the previous rendered screen.) # (But note that we still use _last_screen to calculate the height.) if style != self._last_style: self._last_screen = None self._last_style = style layout.write_to_screen( cli, screen, WritePosition( xpos=0, ypos=0, width=size.columns, height=(size.rows if self.use_alternate_screen else height), extended_height=size.rows, )) # When grayed. Replace all tokens in the new screen. if cli.is_aborting or cli.is_exiting: screen.replace_all_tokens(Token.Aborted) # Process diff and write to output. self._cursor_pos, self._last_char = output_screen_diff( output, screen, self._cursor_pos, self._last_screen, self._last_char, is_done, style=style, ) self._last_screen = screen self._last_size = size # Write title if it changed. new_title = cli.terminal_title if new_title != self._last_title: if new_title is None: self.output.clear_title() else: self.output.set_title(new_title) self._last_title = new_title output.flush()
def render(self, app: 'Application[Any]', layout: 'Layout', is_done: bool = False) -> None: """ Render the current interface to the output. :param is_done: When True, put the cursor at the end of the interface. We won't print any changes to this part. """ output = self.output # Enter alternate screen. if self.full_screen and not self._in_alternate_screen: self._in_alternate_screen = True output.enter_alternate_screen() # Enable bracketed paste. if not self._bracketed_paste_enabled: self.output.enable_bracketed_paste() self._bracketed_paste_enabled = True # Enable/disable mouse support. needs_mouse_support = self.mouse_support() if needs_mouse_support and not self._mouse_support_enabled: output.enable_mouse_support() self._mouse_support_enabled = True elif not needs_mouse_support and self._mouse_support_enabled: output.disable_mouse_support() self._mouse_support_enabled = False # Create screen and write layout to it. size = output.get_size() screen = Screen() screen.show_cursor = False # Hide cursor by default, unless one of the # containers decides to display it. mouse_handlers = MouseHandlers() # Calculate height. if self.full_screen: height = size.rows elif is_done: # When we are done, we don't necessary want to fill up until the bottom. height = layout.container.preferred_height(size.columns, size.rows).preferred else: last_height = self._last_screen.height if self._last_screen else 0 height = max(self._min_available_height, last_height, layout.container.preferred_height(size.columns, size.rows).preferred) height = min(height, size.rows) # When te size changes, don't consider the previous screen. if self._last_size != size: self._last_screen = None # When we render using another style or another color depth, do a full # repaint. (Forget about the previous rendered screen.) # (But note that we still use _last_screen to calculate the height.) if (self.style.invalidation_hash() != self._last_style_hash or app.style_transformation.invalidation_hash() != self._last_transformation_hash or app.color_depth != self._last_color_depth): self._last_screen = None self._attrs_for_style = None if self._attrs_for_style is None: self._attrs_for_style = _StyleStringToAttrsCache( self.style.get_attrs_for_style_str, app.style_transformation) self._last_style_hash = self.style.invalidation_hash() self._last_transformation_hash = app.style_transformation.invalidation_hash() self._last_color_depth = app.color_depth layout.container.write_to_screen(screen, mouse_handlers, WritePosition( xpos=0, ypos=0, width=size.columns, height=height, ), parent_style='', erase_bg=False, z_index=None) screen.draw_all_floats() # When grayed. Replace all styles in the new screen. if app.exit_style: screen.append_style_to_content(app.exit_style) # Process diff and write to output. self._cursor_pos, self._last_style = _output_screen_diff( app, output, screen, self._cursor_pos, app.color_depth, self._last_screen, self._last_style, is_done, full_screen=self.full_screen, attrs_for_style_string=self._attrs_for_style, size=size, previous_width=(self._last_size.columns if self._last_size else 0)) self._last_screen = screen self._last_size = size self.mouse_handlers = mouse_handlers output.flush() # Set visible windows in layout. app.layout.visible_windows = screen.visible_windows if is_done: self.reset()
def render(self, cli, layout, is_done=False): """ Render the current interface to the output. :param is_done: When True, put the cursor at the end of the interface. We won't print any changes to this part. """ output = self.output # Enter alternate screen. if self.use_alternate_screen and not self._in_alternate_screen: self._in_alternate_screen = True output.enter_alternate_screen() # Enable bracketed paste. if not self._bracketed_paste_enabled: self.output.enable_bracketed_paste() self._bracketed_paste_enabled = True # Enable/disable mouse support. needs_mouse_support = self.mouse_support(cli) if needs_mouse_support and not self._mouse_support_enabled: output.enable_mouse_support() self._mouse_support_enabled = True elif not needs_mouse_support and self._mouse_support_enabled: output.disable_mouse_support() self._mouse_support_enabled = False # Create screen and write layout to it. size = output.get_size() screen = Screen() screen.show_cursor = False # Hide cursor by default, unless one of the # containers decides to display it. mouse_handlers = MouseHandlers() if is_done: height = 0 # When we are done, we don't necessary want to fill up until the bottom. else: height = self._last_screen.height if self._last_screen else 0 height = max(self._min_available_height, height) # When te size changes, don't consider the previous screen. if self._last_size != size: self._last_screen = None # When we render using another style, do a full repaint. (Forget about # the previous rendered screen.) # (But note that we still use _last_screen to calculate the height.) if self.style.invalidation_hash() != self._last_style_hash: self._last_screen = None self._attrs_for_token = None if self._attrs_for_token is None: self._attrs_for_token = _TokenToAttrsCache( self.style.get_attrs_for_token) self._last_style_hash = self.style.invalidation_hash() layout.write_to_screen( cli, screen, mouse_handlers, WritePosition( xpos=0, ypos=0, width=size.columns, height=(size.rows if self.use_alternate_screen else height), extended_height=size.rows, )) # When grayed. Replace all tokens in the new screen. if cli.is_aborting or cli.is_exiting: screen.replace_all_tokens(Token.Aborted) # Process diff and write to output. self._cursor_pos, self._last_char = output_screen_diff( output, screen, self._cursor_pos, self._last_screen, self._last_char, is_done, attrs_for_token=self._attrs_for_token, width=size.columns, previous_width=(self._last_size.columns if self._last_size else 0)) self._last_screen = screen self._last_size = size self.mouse_handlers = mouse_handlers # Write title if it changed. new_title = cli.terminal_title if new_title != self._last_title: if new_title is None: self.output.clear_title() else: self.output.set_title(new_title) self._last_title = new_title output.flush()