[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]