1. Frames library for DOS Euphoria
- Posted by Jeff Zeitlin <jeff.zeitlin at MAIL.EXECNET.COM>
Feb 27, 1998
-
Last edited Feb 28, 1998
Herewith the code for frames.e, a library of routines that can be
used along with something like David Cuny's TextGui stuff.
Copious comments at the beginning describe the package and the
interface. Inserted as quoted text because my mailreader wraps
it otherwise.
>-- frames.e
>-- jeff.zeitlin at earth.execnet.com (Jeff Zeitlin)
>
>-- Implements core routines for a text "windowing" system.
>
>-- A frame may be identified with any unambiguous value. This value =
serves
>-- to identify which frame is being referenced; it does not contain the
>-- frame data itself. There is therefore no "frame" type needed.
>
>-- Frames act as virtual screens; that is, data written to them wraps =
and
>-- scrolls within the frame as is normally done on the full screen; =
also,
>-- text and background colors may be set independently for each frame.
>-- Procedures and functions defined for frames are analogous to the =
non-frame
>-- procedures and functions whose name they most resemble.
>
>-- Frames may overlap; calling a procedure that causes data to be =
displayed
>-- in a frame also causes that frame to move to the "front" of the group=
of
>-- overlapping frames.
>
>-- Coordinates within frames are relative to the frame itself; within a
>-- frame, the position {1,1} is the top left corner of the frame, =
regardless
>-- of where the frame actually is on the screen.
>
>-- Frames are "safe"; that is, a frames procedure can neither read data =
from
>-- outside the bounds of the frame, nor display data outside those =
bounds.
>
>-- The frames initialization creates a frame with frameid 1 (integer =
value);
>-- this frame is coincident with the standard text screen (25 rows x 80 =
cols,
>-- starting at screen coordinates {1,1}). This is to permit easy =
conversion
>-- of non-frames programs to frames programs, by simply including =
frames.e
>-- and prefixing all calls to non-frames procedures with the letter "f"
>-- (except for scroll -> fscroll and position -> fposition, both of =
which
>-- will require the addition of the frame id as the first parameter). =
This
>-- frame is in no other way "special", and may be destroyed if the user =
so
>-- desires.
>
>-- public procedures:
>
>-- create_frame(object frameid, sequence tl, sequence br)
>-- defines a frame consisting of the rectangle of screen with the =
top-
>-- left corner at tl, and the bottom right corner at br, and =
associates
>-- it with the value of frameid
>
>-- destroy_frame(object frameid)
>-- removes all information about the frame associated with the =
value
>-- frameid from the system. This does NOT "undisplay" the frame or=
its
>-- information.
>
>-- save_frame(object frameid)
>-- updates the current information for the frame associated with =
the
>-- frameid. This information is stored in the system data =
structure
>-- and overwrites any previous saved frame image. This procedure =
is
>-- also called internally by other frames procedures.
>
>-- restore_frame(object frameid)
>-- restores the frame to the state it was in at the time of the =
most
>-- recent call to save_frame for that frame - which may not have =
been
>-- made by the user program. This procedure is most useful for =
"moving"
>-- one of a set of overlapping frames to the "front".
>
>-- fscroll(object frameid, integer nlines, integer start, integer stop)
>-- analogous to scroll(), causes text in a frame to be scrolled as =
per
>-- the description of scroll(), save that only the designated frame=
is
>-- affected.
>
>-- fputs(object frameid, sequence data)
>-- analogous to puts(). The first parameter, instead of designating=
an
>-- open file, designates the frame to receive the data. Data is
>-- interpreted as for puts().
>
>-- fprint(object frameid, object data)
>-- analogous to print(). Displays the Euphoria representation of =
data
>-- in a frame.
>
>-- fprintf(object frameid, sequence formatstring, sequence data)
>-- analogous to printf(). Formats data using formatstring as per =
the
>-- description of printf().
>
>-- sequence s
>-- s =3D fsave_text_image(object frameid, sequence tl, sequence br)
>-- analogous to save_text_image(). tl and br are relative to the =
top-
>-- left corner of frame frameid.
>
>-- fdisplay_text_image(object frameid, sequence tl, sequence data)
>-- analogous to display_text_image(). tl is relative to the =
top-left
>-- corner of the target frame. data is a text image created with
>-- save_text_image() or fsave_text_image().
>
>-- fclear_screen(object frameid)
>-- analogous to clear_screen(), but clears only the specified =
frame.
>
>-- ftext_color(object frameid, integer color)
>-- analogous to text_color(), but sets the text color for the =
indicated
>-- frame only. Different frames may have different defined text =
colors;
>-- the correct color will be selected when writing to different =
frames.
>
>-- fbk_color(object frameid, integer color)
>-- analogous to bk_color(), but sets the background color for the
>-- indicated frame only. Different frames may have different =
defined
>-- background colors; the correct color will be selected when =
writing
>-- to different frames.
>
>-- fposition(object frameid, integer line, integer column)
>-- analogous to position(). Sets the cursor position within the=20
>-- indicated frame. Cursor positions are relative to the top-left
>-- corner of the frame.
>
>include 3rdparty\jz\assoc.e
>include image.e
>
>assoc_list f_sysdata
>f_sysdata =3D {}
>
>global procedure create_frame(object frameid, sequence tl, sequence br)
> assoc_list f
> sequence scrndata
> integer top
> integer left
> integer bottom
> integer right
> =20
> top =3D tl[1]
> left =3D tl[2]
> bottom =3D br[1]
> right =3D br[2]
> f =3D {}
> f =3D alist_set(f,"bounds",{top, left, bottom, right})
> f =3D alist_set(f,"colors",{7,0})
> f =3D alist_set(f,"position",{1,1})
> scrndata =3D save_text_image(tl,br)
> f =3D alist_set(f,"restore",scrndata)
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
>end procedure
>
>global procedure destroy_frame(object frameid)
> f_sysdata =3D alist_delete(f_sysdata,frameid)
>end procedure
>
>global procedure save_frame(object frameid)
> assoc_list f
> sequence bounds
> sequence data
> =20
> f =3D alist_reference(f_sysdata,frameid)
> bounds =3D alist_reference(f,"bounds")
> data =3D save_text_image(bounds[1..2],bounds[3..4])
> f =3D alist_set(f,"restore",data)
> f_sysdata =3D alist_set(f_sysdata, frameid, f)
>end procedure
>
>global procedure restore_frame(object frameid)
> assoc_list f
> sequence scrndata
> sequence coords
> sequence tl
> =20
> f =3D alist_reference(f_sysdata,frameid)
> scrndata =3D alist_reference(f,"restore")
> coords =3D alist_reference(f,"bounds")
> tl =3D coords[1..2]
> display_text_image(tl,scrndata)
>end procedure
>
>global procedure fscroll(object frameid, integer nlines, integer start, =
integer stop)
> assoc_list f
> sequence bounds
> sequence scrndata
> sequence scrnline
> sequence colors
> integer framelen
> =20
> restore_frame(frameid)
> if nlines =3D 0 then
> return
> end if
> f =3D alist_reference(f_sysdata,frameid)
> bounds =3D alist_reference(f,"bounds")
> scrndata =3D alist_reference(f,"restore")
> scrndata =3D scrndata[start..stop]
> framelen =3D length(scrndata)
> colors =3D alist_reference(f,"colors")
> scrnline =3D {}
> for i =3D 1 to length(scrndata[1])/2 do
> scrnline =3D scrnline & {' ',colors[1]+16*colors[2]}
> end for
> if nlines > length(scrndata) then
> scrndata =3D repeat(length(scrndata),scrnline)
> end if
> if nlines < 0 then
> for i =3D 1 to (-1 * nlines) do
> scrndata =3D prepend(scrndata,scrnline)
> end for
> scrndata =3D scrndata[1..framelen]
> else
> for i =3D 1 to nlines do
> scrndata =3D append(scrndata,scrnline)
> end for
> scrndata =3D scrndata[nlines + 1..length(scrndata)]
> end if
> display_text_image({bounds[1] + start - 1,bounds[2]},scrndata)
> save_frame(frameid)
>end procedure
>
>global procedure fputs(object frameid, sequence data)
> assoc_list f
> sequence colors
> sequence posn
> sequence bounds
> integer line
> integer column
> integer dlen
> =20
> restore_frame(frameid)
> f =3D alist_reference(f_sysdata,frameid)
> colors =3D alist_reference(f,"colors")
> text_color(colors[1])
> bk_color(colors[2])
> posn =3D alist_reference(f,"position")
> bounds =3D alist_reference(f,"bounds")
> line =3D bounds[1] + posn[1] - 1
> column =3D bounds[2] + posn[2] - 1
> dlen =3D bounds[4] - column + 1
> position(line,column)
> if dlen >=3Dlength(data) then
> puts(2,data)
> posn[2] =3D posn[2] + length(data)
> f =3D alist_set(f,"position",posn)
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
> save_frame(frameid)
> else
> puts(2,data[1..dlen])
> posn[2] =3D 1
> save_frame(frameid)
> if line =3D bounds[3] then
> fscroll(frameid,1,1,bounds[3]-bounds[1]+1)
> else
> posn[1] =3D posn[1] + 1
> end if
> f =3D alist_set(f,"position",posn)
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
> save_frame(frameid)
> fputs(frameid,data[dlen+1..length(data)])
> end if
> save_frame(frameid)
>end procedure
>
>function stringrep(object data)
> sequence rep
> =20
> if sequence(data) then
> rep =3D "{"
> for i =3D 1 to length(data) do
> rep =3D rep & stringrep(data[i])
> if i < length(data) then
> rep =3D rep & ','
> end if
> end for
> rep =3D rep & '}'
> elsif integer(data) then
> rep =3D sprintf("%d",data)
> else
> rep =3D sprintf("%g",data)
> end if
> return rep
>end function
>
>global procedure fprint(object frameid, object data)
> fputs(frameid,stringrep(data))
>end procedure
>
>global procedure fprintf(object frameid, sequence fmtstr, sequence vals)
> sequence outstr
> =20
> outstr =3D sprintf(fmtstr,vals)
> fputs(frameid,outstr)
>end procedure
>
>global function fsave_text_image(object frameid, sequence tl, sequence =
br)
> assoc_list f
> sequence bounds
> sequence ulc
> sequence brc
> sequence savedata
> =20
> f =3D alist_reference(f_sysdata,frameid)
> bounds =3D alist_reference(f,"bounds")
> ulc =3D bounds[1..2] + tl - 1
> brc =3D bounds[1..2] + br - 1
> if brc[1] > bounds[3] then
> brc[1] =3D bounds[3]
> end if
> if brc[2] > bounds[4] then
> brc[2] =3D bounds[4]
> end if
> savedata =3D save_text_image(ulc,brc)
> return savedata
>end function
>
>global procedure fdisplay_text_image(object frameid, sequence tl, =
sequence data)
> assoc_list f
> sequence bounds
> sequence newdata
> sequence ulc
> =20
> newdata =3D data
> f =3D alist_reference(f_sysdata,frameid)
> bounds =3D alist_reference(f,"bounds")
> ulc =3D bounds[1..2] + tl - 1
> if length(newdata) > (bounds[3] - ulc[1] + 1) then
> newdata =3D newdata[1..bounds[3] - ulc[1] + 1]
> end if
> if length(newdata[1]) > 2 * (bounds[4] - ulc[2] + 1) then
> for i =3D 1 to length(newdata) do
> newdata[i] =3D newdata[i][1..2 * bounds[4] - ulc[2] + 1]
> end for
> end if
> display_text_image(ulc,newdata)
> save_frame(frameid)
>end procedure
>
>global procedure fclear_screen(object frameid)
> assoc_list f
> sequence bounds
> =20
> f =3D alist_reference(f_sysdata,frameid)
> bounds =3D alist_reference(f,"bounds")
> fscroll(frameid,bounds[3]-bounds[1]+1,1,bounds[3]-bounds[1]+1)
> f =3D alist_set(f,"position",{1,1})
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
> save_frame(frameid)
>end procedure
>
>global procedure ftext_color(object frameid, integer color)
> assoc_list f
> sequence colors
> =20
> f =3D alist_reference(f_sysdata,frameid)
> colors =3D alist_reference(f,"colors")
> colors[1] =3D color
> f =3D alist_set(f,"colors",colors)
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
>end procedure
>
>global procedure fbk_color(object frameid, integer color)
> assoc_list f
> sequence colors
> =20
> f =3D alist_reference(f_sysdata,frameid)
> colors =3D alist_reference(f,"colors")
> colors[2] =3D color
> f =3D alist_set(f,"colors",colors)
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
>end procedure
>
>global procedure fposition(object frameid, integer line, integer column)
> assoc_list f
> =20
> f =3D alist_reference(f_sysdata,frameid)
> f =3D alist_set(f,"position",{line,column})
> f_sysdata =3D alist_set(f_sysdata,frameid,f)
>end procedure
>
>create_frame(1,{1,1},{25,80})
>
--
Jeff Zeitlin
jeff.zeitlin at mail.execnet.com