tw

Descripción del contenido de la página

Ventanas de texto para programas en X11-Basic.

Etiquetas:

tw implementa ventanas de texto en X11-Basic. Permite crear una ventana de texto en la consola, de cualquier tamaño y en cualquier posición, e imprimir en ella párafos justificados a la izquierda con desplazamiento automático. Está aún en desarrollo pero funciona bien.

tw comenzó como parte de un proyecto mayor aún en desarrollo, una aventura de texto, pero pronto fue extraído como un módulo reutilizable.

Código fuente

' tw.xbas

' tw
' Version 0.1.0+201707291351
' See change log at the end of the file

' Text windows for X11-Basic.
' <http://programandala.net/en.program.tw.html>

' Author: Marcos Cruz (programandala.net), 2013,2014,2015,2017 

' You may do whatever you want with this work, so long as you
' retain all copyright, authorship and credit notices and this
' license in all redistributed copies and derived works.  There
' is no warranty.

' ==============================================================
' Text output {{{1

procedure tw_init

  ' Init the deafult values.

  let tw_indentation%=2 ! spaces
  ! XXX FIXME 0 still prints a blank line:
  let tw_blank_lines_between_paragraphs%=0
  return

procedure tw_new(row%,col%,cols%,rows%)

  ' Define the text window.

  @tw_size(cols%,rows%)
  @tw_frame_locate(row%,col%)
  @tw_home
  return

procedure tw_home

  ' Set the text window cursor to home.

  @tw_locate(0,0)
  return

procedure tw_locate(row%,col%)

  ' Set the text window cursor coordinates.

  let tw_row%=row%
  let tw_col%=col%
  return

procedure tw_frame_locate(row%,col%)

  ' Set the text window frame coordinates.

  let tw_frame_row%=row% ! top screen row
  let tw_frame_col%=col% ! left screen col
  return

procedure tw_size(cols%,rows%)

  ' Set the size of the text window.

  let tw_cols%=cols%
  let tw_rows%=rows%
  let tw_last_row%=rows%-1
  dim tw_line$(rows%)
  @tw_wipe
  return

function tw_row_is_in_screen%(row%)

  ' Is a window row number in the screen limits?

  return row%>=0 and row%<=rows

procedure tw_dump_line(row%)

  ' Dump a line of the text window to the screen.

  local actual_row%
  local visible_len%
  local first_visible_char%
  let actual_row%=tw_frame_row%+row%
  #if @tw_row_is_in_screen%(actual_row%)
  if true ! XXX debug check
    let first_visible_char%=abs(0-tw_frame_col%)+1 ! XXX TODO
    let visible_len%=min(tw_cols%,cols-tw_frame_col%)
    ' XXX TODO check also if tw_col% is outside the screen
    #if visible_len%
    if true ! XXX debug check
      locate actual_row%,tw_frame_col%
      #print left$(tw_line$(row%),visible_len%)
      #print row% using "0#>"; ! XXX debug check
      #print "{";left$(tw_line$(row%),visible_len%);"} r=";tw_row% using "0#";" c=";tw_col% using "0#"; ! XXX debug check
      #print left$(tw_line$(row%),visible_len%);"| r=";tw_row% using "0#";" c=";tw_col% using "0#"; ! XXX debug check
      print left$(tw_line$(row%),visible_len%);
      flush
    endif
  endif
  return

procedure tw_dump

  ' Dump the content of the text window to the screen.

  local row%
  for row%=0 to tw_last_row%
    @tw_dump_line(row%)
  next
  return

procedure tw_scroll

  ' Scroll the content of the text window one line up.

  local row%
  for row%=0 to tw_last_row%-1
    let tw_line$(row%)=tw_line$(row%+1)
    @tw_dump_line(row%)
  next
  @tw_wipe_line(tw_last_row%)
  @tw_dump_line(tw_last_row%)
  return

procedure tw_wipe_line(row%)

  ' Wipe the content of a line of the text window,
  ' but do not change the screen.

  let tw_line$(row%)=space$(tw_cols%)
  return

procedure tw_wipe

  ' Wipe the content of the text window,
  ' but do not change the screen.

  local row%
  for row%=0 to tw_last_row%
    @tw_wipe_line(row%)
  next
  return

procedure tw_cls

  ' Clear the text window.

  @tw_wipe
  @tw_dump
  @tw_home
  return

function tw_cursor_is_at_the_left%

  ' Is the text window cursor at the first column?

  return tw_col%=tw_frame_col%

function tw_cursor_is_at_the_top%

  ' Is the text window cursor at the first row?

  #return tw_row%=tw_frame_row%  ! XXX old
  #print tw_row% ! XXX debug check
  #pause 3 ! XXX debug check
  return tw_row%=0

function tw_cursor_is_at_the_bottom%

  ' Is the text window cursor at the last row?

  return tw_row%=tw_last_row%

procedure tw_do_cr

  ' Do a carriage return.

  if @tw_cursor_is_at_the_bottom%
    @tw_scroll
  else
    inc tw_row%
    if tw_row%>tw_last_row%
      @tw_scroll
    endif
  endif
  let tw_col%=tw_frame_col%
  return

procedure tw_cr

  ' Do a carriage return, if needed.

  if not @tw_cursor_is_at_the_left%
    @tw_do_cr
  endif
  return

procedure tw_print(text$)

  ' Print a text at the current cursor position.
  ' The text is supposed to fit in the current row;
  ' otherwise it's truncated.

  let tw_line$(tw_row%)=\
    left$(tw_line$(tw_row%),tw_col%)+\
    text$+\
    right$(tw_line$(tw_row%),tw_cols%-tw_col%-len(text$))
  add tw_col%,len(text$)
  let tw_col%=min(tw_col%,cols-1) ! XXX FIXME
  @tw_dump_line(tw_row%)
  return

procedure tw_indent

  ' Do a carriage return and indent.
  ' XXX TODO rename

#  if not @tw_cursor_is_at_the_top%
    ' Note: an additional space will be shown before the first
    ' word of the paragraph, so x spaces here mean x+1 spaces
    ' of indentation:
    local row%
    for row%=0 to tw_blank_lines_between_paragraphs%-1
      @tw_do_cr
    next
    @tw_print(space$(max(tw_indentation%-1,0)))
#  endif
  return

function tw_free_cols%

  ' Number of free columns in the current row of the window.

  return tw_cols%-tw_col%-1

procedure tw_p(text$)

  ' Print a text, left justified, from the current cursor
  ' position.

  local a_word$
  let text$=text$+" "
  do
    split text$," ",0,a_word$,text$
    if (@tw_free_cols%-1)>=len(a_word$)
      if not @tw_cursor_is_at_the_left%
        @tw_print(" ")
      endif
    else
      @tw_cr
    endif
    @tw_print(a_word$)
    exit if text$=""
  loop
  return

procedure tw_p_(text$)

  ' Start a new paragraph.

  @tw_cr
  @tw_indent
  @tw_p(text$)
  return

' ==============================================================
' Change log {{{1

' 2013-05-22:
'
' Start, as part of a text adventure game project, Fifi.
'
' 2013-05-24:
'
' Fix: the parameters of 'tw_locate()' and 'tw_frame_locate()'
' were in wrong order.
'
' Change: 'tw_wipe_line()' factored from 'tw_wipe()'.  Fix:
' 'tw_scroll' does not empty the last line any more, but
' properly wipes it with spaces.
'
' New: one single command, 'tw_new', creates the window.
'
' Fix: 'tw_print' limits tw_row% to cols-1.
'
' Improvement: 'tw_dump_line' does nothing if the line is out of
' the screen, what (when complemented with the col check) will
' let the text window to be partially or totally out of the
' screen.
'
' Improvement: 'tw_dump_line' does not print the part of the
' line that overflows at the right of the screen.
'
' Change: the code is moved from "Fifi" to an independent file,
' in order to reuse it as a module ("tw").
'
' 2013-09-06:
'
' Fix: Some typos in the development history.
'
' 2013-09-07:
'
' Fix: The input line is cleared after every input.
'
' Fix: 'tw_scroll' decremented tw_row% at the end, what ruined
' the effect.  Change: the parameters of 'tw_locate()' and
' 'tw_frame_locate()' have been inverted, after X11-Basic's
' 'locate'.
'
' 2013-09-26:
'
' Fix: 'flush' added to 'tw_dump_line' in order to prevent the
' effects of buffered output.
'
' 2014-03-15:
'
' Some little changes in the source code layout.
'
' 2014-12-12:
'
' Some changes in the comments and credits. 'endfunction' is
' removed, since it's not mandatory.
'
' 2015-03-02:
'
' New: 'tw_blank_lines_between_paragraphs%' to separate the
' paragraphs. Not fully finished yet.
'
' 2017-07-29:
'
' Move initialization commands to new procedure `tw_init`.
' Change version numbering after Semantic Versioning
' (http://semver.org). Change license.

' vim: filetype=x11basic

Ejemplo de uso

El código siguiente consta de partes de código de un proyecto que usa tw:
  merge "tw.xbas"

  ' Window position and size:
  let frame_col%=2
  let frame_row%=2
  let frame_cols%=cols-4
  let frame_rows%=rows-6

  ' Window definition:
  @tw_new(\
    frame_col%,frame_row%,\
    frame_cols%,frame_rows%)

  ' Printing a left-justified paragraph in the window:
  @tw_p_("Suddenly, a man goes out from the house.")
  @tw_p("He locks the door behind him")
  @tw_p("and then walks away.")

Descargas

Páginas relacionadas

wt
Justificador de texto para X11-Basic y MBim.