frame_render Function

private function frame_render(this) result(output)

The escape sequence that brings the screen up to date.

Only rows whose text changed since the last render are emitted, each as a move, a line clear and the text. One string comes back and the caller writes it once: a single write cannot tear, where a write per row can.

Type Bound

frame_t

Arguments

Type IntentOptional Attributes Name
class(frame_t), intent(inout) :: this

Return Value character(len=:), allocatable


Calls

proc~~frame_render~~CallsGraph proc~frame_render frame_t%frame_render proc~ansi_clear_line ansi_clear_line proc~frame_render->proc~ansi_clear_line proc~ansi_move_to ansi_move_to proc~frame_render->proc~ansi_move_to interface~to_string to_string proc~ansi_move_to->interface~to_string

Variables

Type Visibility Attributes Name Initial
integer(kind=default_int), private :: i

Source Code

   function frame_render(this) result(output)
      !! The escape sequence that brings the screen up to date.
      !!
      !! Only rows whose text changed since the last render are emitted, each
      !! as a move, a line clear and the text. One string comes back and the
      !! caller writes it once: a single write cannot tear, where a write per
      !! row can.
      class(frame_t), intent(inout) :: this
      character(len=:), allocatable :: output

      integer(default_int) :: i

      output = ""
      if (this%rows == 0_default_int) then
         this%full_redraw = .false.
         return
      end if

      do i = 1_default_int, this%rows
         if (.not. this%full_redraw) then
            ! Compared through `char` with an explicit length test.
            ! `string_type`'s `==` is Fortran character comparison, which pads
            ! the shorter side with blanks, so "abc" and "abc   " compare
            ! equal. Those are the same text but not the same row: with a
            ! background colour still open at the end of the line, the three
            ! extra cells are painted.
            if (len(char(this%current(i))) == len(char(this%shown(i)))) then
               if (char(this%current(i)) == char(this%shown(i))) cycle
            end if
         end if
         output = output//ansi_move_to(i, 1_default_int)//ansi_clear_line()// &
                  char(this%current(i))
         this%shown(i) = this%current(i)
      end do
      this%full_redraw = .false.
   end function frame_render