[Back to OOP SWAG index] [Back to Main SWAG index] [Original]
{
I recently made a SCROLLBAR object. it's pretty good and draws it's strings
directly to videomemory so no flashing etc.
}
UNIT scroller;
{ scrolbar.init(left, top, maxright, maxbottom, startvalue)
if maxright and maxbottom are high enough
the windowsize will be adjusted automatically to
the longest string in the data-array.
Mind that the scroller stops counting as soon as
an empty string is encountered, and everything below
it will not be displayed.
in order to save memory your application may write
directly to scrollbar.data.
scrollbar.return contains the return value, i.e. the index
of the chosen element in the data-array.
scroll.bar.incr/decr take an integer and increases/decreases
scrollbar.return
scrollbar.update should be called after each scrollbar.incr/decr
to display the changes.
scrollbar.borderhit is a boolean that becomes true
when the user attempts to go past the first/last item in
the list. This should be used BEFORE scrollbar.update, as
that procedure sets both booleans to False.
scrollbar.stop closes the window and restores the screen.
willem van de vis
s0730076@let.rug.nl
}
Interface
const max = 200;
maxwidth = 20;
type
scrolldata = array[1..max] of string[maxwidth];
type Scrollbar =
object
private {erase private and public for tp6.0}
top,
bottom,
left,
right,
total,
width,
len,
y,
b : integer;
public
data : scrolldata;
return : integer;
borderhit: boolean;
constructor init(ileft,itop, iright,ibottom,iq: integer);
destructor stop;
procedure update;
procedure incr(i : integer);
procedure decr(d : integer);
end;
Implementation
uses win, crt;
constructor scrollbar.init;
var q : integer;
begin
if ibottom > 24 then ibottom := 24;
if itop < 2 then itop := 1;
if ileft < 2 then ileft := 1;
if iright > 78 then iright := 78;
return := 1;
b := 1;
y := 1;
bottom := ibottom;
top := itop;
len := (bottom - top)+1;
left := ileft-1;
right := iright;
borderhit := false;
total := 1;
width := 1;
while (total <= max) and (data[total] <> '') do
begin
if length(data[total]) > width then width := length(data[total]);
data[total] := data[total] +
' ';
inc(total);
end;
dec(total);
if total = 0 then total := 1;
if width < right - ileft then right := left + width
else width := right-ileft;
dec(right);
if total < bottom - itop then bottom := itop + total-1;
open_win(ileft, itop, right, bottom, lightgray, blue);
if iq > 1 then
scrollbar.incr(iq-1);
end;
destructor scrollbar.stop;
begin
close_win;
end;
procedure scrollbar.decr;
begin
if return - d < 1 then
d := return-1;
dec(return,d);
if (y - d < 1) then
begin
b := return;
y := 1;
end
else
dec(y,d);
if d = 0 then borderhit := true;
end;
procedure scrollbar.incr;
begin
if return + i > total then
i := total - return;
inc(return,i);
if (y + i > len) then
begin
b := 1 + return - len;
y := len;
end
else
inc(y,i);
if i = 0 then borderhit := true;
end;
procedure scrollbar.update;
var i : integer;
begin
borderhit := false;
for i := b to b + len-1 do
if i <= total then
if i - b + 1 = y then
writeline(data[i],left, top+i-b, width, white,black)
else
writeline(data[i],left, top+i-b, width, lightgray,blue);
end;
end.
Mind that no pointers are used so there IS a max to the number of lines
displayed. It may be neccesary to adjust width en right etc.
an example of an application:
uses scroller,ill,crt,win;
var scrol : scrollbar;
r : char;
chosen : string;
F : TEXT;
q : integer;
begin
assign(f, paramstr(1));
reset(f);
q := 1;
while (not eof(f)) and (q < 500) do
begin
readln(f,scrol.data[q]);
if scrol.data[q] <> '' then
inc(q);
end;
close(f);
ini_win;
scrol.init(2,2,80,18,1);
r := '!';
while (r <> chr(13)) and (r <> chr(27)) do
begin
if scrol.borderhit then brom;
scrol.update;
r := readkey;
case r of
chr(72) : scrol.decr(1);
chr(80) : scrol.incr(1);
chr(73) : scrol.decr(10);
chr(81) : scrol.incr(10);
end;
end;
chosen := scrol.data[scrol.return];
scrol.stop;
if r <> chr(27) then
begin
writeln(chosen);
end;
end.
[Back to OOP SWAG index] [Back to Main SWAG index] [Original]