' MAIN DEMO -----------------------------------------------------------------
DO:
PRINT "Input screen width: 60 - 140, blank for default demo or -1 for debug mode: ";:
INPUT screen_width%
IF screen_width%
= -1 THEN debug%
= -1: m_top%
= 1: m_bottom%
= 5: m_left%
= 124: m_right%
= 8: screen_width%
= 150: text_lines%
= 99:
GOTO make_fake_text
' Debug mode. IF screen_width%
= 0 THEN m_top%
= 0: m_bottom%
= 0: m_left%
= 10: m_right%
= 12: screen_width%
= 80: text_lines%
= 99:
GOTO make_fake_text
' Use defaults for demo. DO:
PRINT "Input number of text entries 10 - 99: ";:
INPUT text_lines%
make_fake_text:
FOR i%
= 1 TO text_lines%
FOR j%
= 1 TO screen_width%
- (m_left%
+ m_right%
) - 3 mytext$(i%) = mytext$(i%) + a$
CALL scrollbar_library
(mytext$
(), text_lines%
, m_top%
, m_bottom%
, m_left%
, m_right%
, text_row%
, text_scrolled%
) END ' -----------------------------------------------------------------------
SUB scrollbar_library
(x$
(), noe%
, margin.t
, margin.b
, margin.l
, margin.r
, row%
, scr%
)
STATIC initiate_scrb%
, debug%
, page.h%
, delay_on!
STATIC scrn
AS my_scrn
, scrb
AS my_scrb
, cursor
AS my_cursor
, mb
AS my_mb
debug% = 0 ' Set to non-zero for debug data.
initiate_scrb% = -1
getvar_setscrn:
scrb.x = 0 ' Relative position of the scrollbar cursor from top of scrb.h. 0 Off / 1 to
' Calculations
page.w% = scrn.w - (margin.l + margin.r)
page.h% = scrn.h - (margin.t + margin.b)
scrb.t = margin.t + 1
scrb.b = margin.t + page.h%
scrb.l = margin.l + page.w% + 2
scrb.d = scrb.b - scrb.t + 1
scrb.h = scrb.b - scrb.t - 1 ' Max. vertical scroll. Bar minus the top and bottom arrow symbols.
LOCATE margin.t
+ row%
, margin.l
+ 1, 1 cursor.scbrrow
= row%
+ scr%: cursor.scbrcol
= POS(0)
displayscrn:
j% = 0
DO ' page.h% determines how mnay rows of text are displayed. j% = j% + 1
LOCATE margin.t
+ j%
, margin.l
+ 1 cursor.find = 0
IF cursor.scbrrow
> scr%
AND cursor.scbrrow
<= scr%
+ page.h%
THEN LOCATE margin.t
+ cursor.scbrrow
- scr%
, cursor.scbrcol
, 1 ' Cursor show.
makescrb:
scrb.s = (scrb.h + 1) * 2 - noe%
IF scrb.s
<= 0 THEN scrb.s
= 1 LOCATE scrb.t
+ i%
+ scrb.x
, scrb.l
getkey:
_LIMIT 60 ' Can be reduced or removed. Since this is a flow-through library, this limit will affect the entire program. IF b$
= "" THEN b$
= INKEY$ ' Since library is flow-through b$ might be initiated by another routine. scr% = scr% - 1
row% = row% - 1
LOCATE row%
+ margin.t
, margin.l
+ 1 scr% = scr% + 1
row% = row% + 1
LOCATE row%
+ margin.t
, margin.l
+ 1
' Reverse algorithm. Not needed for this routine. scrb.x = scrb.i / ((noe% - scrb.d) / (scrb.h - scrb.s))
IF row%
+ scr%
>= INT((scrb.x
+ 1) * ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) + page.h%
THEN scrb.x = scrb.x + 1
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) scrb.x = scrb.x - 1
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) b$ = ""
IF delay_on!
THEN ' Scrollbar delay. delay_on! = 0 ' Toggle off.
IF mx%
= scrb.l
AND scrb.s
AND my%
>= scrb.t
AND my%
<= scrb.b
OR mb.dragon
THEN ' Mouse on scrollbar or doing a bar cursor drag. IF my%
= scrb.t
AND scrb.x
> 0 OR my%
= scrb.b
AND scrb.x
+ scrb.s
< scrb.h
THEN ' Mouse on a scrollbar arrow. IF my%
= scrb.t
THEN scrb.x
= scrb.x
- 1 ELSE scrb.x
= scrb.x
+ 1 ' Top or bottom arrow. delay_on! = .15
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) scr% = scrb.i
cursor.find = -1
ELSEIF my%
- (scrb.t
+ 1) >= scrb.x
AND my%
- (scrb.t
+ 1) <= scrb.x
+ scrb.s
- 1 THEN ' Mouse on scrollbar cursor. mb.drag = my% - (scrb.t + 1)
mb.dragon = -1
ELSEIF my%
> scrb.t
AND my%
< scrb.b
OR mb.dragon
THEN ' Mouse on scrollbar between scrollbar arrow and cursor. IF my%
- (scrb.t
+ 1) < scrb.x
THEN scrb.x = my% - (scrb.t + 1)
scrb.x = my% - (scrb.t + 1) - (scrb.s - 1) ' The second argument compensates for large scroll cursors with fewer elements to scroll. Example: 15 elements in a 10 height scrollbar has a 3-space scrollbar cursor.
delay_on! = .15
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) scr% = scrb.i
cursor.find = -1
IF my%
- (scrb.t
+ 1) < mb.drag
AND my%
- (scrb.t
+ 1) - (mb.drag
- scrb.x
) >= 0 THEN i% = mb.drag - scrb.x
scrb.x = my% - (scrb.t + 1) - i%
mb.drag = scrb.x + i%
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) scr% = scrb.i
cursor.find = -1
ELSEIF my%
- (scrb.t
+ 1) > mb.drag
AND my%
- (scrb.t
+ 1) + (scrb.x
- mb.drag
) < scrb.h
- (scrb.s
- 1) THEN i% = scrb.x - mb.drag
scrb.x = my% - (scrb.t + 1) + i%
mb.drag = scrb.x - i%
scrb.i
= INT(scrb.x
* ((noe%
- scrb.d
) / (scrb.h
- scrb.s
))) scr% = scrb.i
cursor.find = -1
i% = my% - (scrb.t + 1)
IF i%
>= scrb.t
AND i%
<= scrb.h
THEN mb.drag
= my%
- (scrb.t
+ 1)
IF mx%
>= margin.l
+ 1 AND mx%
<= scrn.w
- margin.r
THEN LOCATE my%
, mx%
, 1 ' Locate by left mouse click and show cursor. mb.drag = 0: mb.dragon = 0
getcurrow:
cursor.scbrrow = row% + scr%
cursor.holdscr = scr%
cursor.holdrow = row%
cursor.holdscrbx = scrb.x
backtocursor:
IF cursor.scbrrow
> scr%
AND cursor.scbrrow
<= scr%
+ page.h%
THEN ' Display region does not contain cursor. Do nothing.
ELSE ' Display region contains the cursor. scr% = cursor.holdscr
row% = cursor.holdrow
scrb.x = cursor.holdscrbx
scrb.i = scr%
analize:
PRINT " initiate_scrb% ="; initiate_scrb%
PRINT " scrn.w ="; scrn.w;
" scrn.h ="; scrn.h; scrb.s;
" " PRINT " margin.t ="; margin.t;
" margin.b ="; margin.b;
" margin.l ="; margin.l;
" margin.r ="; margin.r; scrb.s;
" " PRINT " scrb.t ="; scrb.t;
" scrb.b ="; scrb.b;
" scrb.l ="; scrb.l;
" scrb.d ="; scrb.d;
" scrb.x = "; scrb.x;
" scrb.i ="; scrb.i;
" scrb.h ="; scrb.h;
" scrb.s ="; scrb.s;
" " PRINT " cursor.find ="; cursor.find;
" cursor.scbrrow ="; cursor.scbrrow;
" cursor.scbrcol = "; cursor.scbrcol; scrb.s;
" " PRINT " cursor.holdscr ="; cursor.holdscr;
" cursor.holdrow ="; cursor.holdrow;
" cursor.holdscrbx ="; cursor.holdscrbx
PRINT " page.h% ="; page.h%;
" noe% = "; noe%;
" delay_on! ="; delay_on!;
" row% = "; row%;
" scr% ="; scr%;
" mx% ="; mx%;
" my% ="; my%;
" mb.l ="; mb.l;
" mb.dragon ="; mb.dragon;
" mb.drag ="; mb.drag;
" "
DIM SHARED margin.t
, margin.b
, margin.l
, margin.r
DIM SHARED scrb.t
, scrb.b
, scrb.l
, scrb.d
, scrb.x
, scrb.i
, scrb.h
, scrb.s
DIM SHARED cursor.find
, cursor.scbrrow
, cursor.scbrcol
, cursor.holdscr
, cursor.holdrow
, cursor.holdscrbx
DIM SHARED page.h%
, noe%
, delay_on!
, row%
, scr%
, mb.l
, mb.dragon
, mb.drag