(* Roy Harvey 1988 (bix id "royharv") *)
(* Placed in the public domain - good luck *)
Scroll is written to work with the Window MODULE that comes with
JPI TopSpeed Modula-2. Suppose you have something like a list or array
that you wish to display in a window. If you can display each entry on
one window line, you can probably use some parts of Scroll to do it.
The two main types of Scrolling are with and without a Highlight
line. With a Highlight line, one line of the window is highlighted, and
the scrolling commands move that line around, along with paging the
data. This is useful when you want to use the window to display a
selection list. When HighOn is "off", you get a simple "browsing" sort
of scrolling, without any selection option.
The main limit using Scroll is that the items must be displayed one
per window line.
To use scroll, you have to:
1) Set up the Window. Set CursorOn to FALSE. Set WrapOn to FALSE.
If you want a selection list, using a highlighted line, it should
be a Palette window. See the TopSpeed User's Manual for an
explanation of Palette windows.
2) Write a PROCEDURE of TYPE WrLnProc. This should take the
CARDINAL parameter, which specifies an item in the list being
displayed, and write it using the routines in MODULE IO.
DO NOT USE WrLn! Cursor positioning is done by Scroll!
3) Set up a record variable of type Scroll.ScrollData.
The fields you must initialize are:
- NumberOfScrollableEntries - How many items are in your list?
- HighOn - A BOOLEAN, are you using a Highlight line or not?
- WriteOneProc - The PROCEDURE defined above.
If HighOn is TRUE, you also have to initialize the two fields that
tell what palette entries to use for the normal and highlighted
lines. Defaults are provided in the DEFINITION MODULE.
Also of interest in the record, but not requiring initialization:
- High - A Cardinal, identifying which item in your list is
displayed as highlighted. This is where you identify what
is selected from a selection list.
- First - A CARDINAL, whatever record of the list is first
on the screen.
Of no interest at all, and no concern either, is:
- TopToBottom, which was put here for convenience. It is
just a work field for Scroll, and changes by the main
MODULE will have no affect.
4) Call Scroll.ScrollInit, passing the WinType of the window, and
the ScrollData record. You will pass these same two items
each time you call a Scroll PROCEDURE.
5) Note that all the PROCEDUREs in Scroll return a BOOLEAN, intended
to signal success or failure of the process. I have never found
it necessary to check the returned value, might consider changing
from functions to proper procedures if I had the time.
6) You can scroll the window to a specific line with ScrollTo, or
give a general scroll command to GeneralScroll. ScrHome goes to
the beginning of your list (First = 1). ScrEnd goes to the
bottom. ScrUp and ScrDown move up and down by one line, while
ScrPgUp and ScrPgDown move by a full window's amount.
Note that scrolling can act differently, depending upon whether
HighOn is TRUE or FALSE. For instance, if HighON is TRUE,
ScrUp first tries to move the highlight line. If it can move up
WITHIN the window, that is all that happens. If it is already
at the top, then the lines scroll. If HighOn were FALSE, ScrUp
would always scroll the screen up, unless already at the top.
7) ScrollReset simply re-displays the window. I use it after
deleting an entry from my list (and updating the fields
NumberOfScrollableEntries). It is the only way to guarantee a
full re-display of the window, rather than a shifting of what is
there. It would also be useful after changes to the list data.
8) GeneralHighlight and HighAt are for changing the position of
the highlight on the screen, without scrolling the screen itself.
9) No attempt was made to interface these commands with the keyboard,
but they were designed to correspond with the Home, End, Up, Down,
Page Up, and Page Down keys. I have also used CtlPageUp and
CtlPageDown to move the highlight to the line at the top or
bottom of the display.
The code has been used enough to be reasonably stable, with the
possible exception of the HighAt PROCEDURE, which I just haven't needed
yet. I make no claim to overwhelming efficiency, nor is the code
especially clever. It is an interesting example of what sort of generic
software can be written by passing in procedures for the specialized
work. QSort and HSort, both in MODULE Lib from JPI, are what inspired
this module. Other "generic" processes should be adaptable to this
approach, such as a binary search.