Author Topic: Hey gang, fun little scrollbar demo routine...  (Read 3393 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Hey gang, fun little scrollbar demo routine...
« on: October 30, 2020, 07:42:27 pm »
Code: QB64: [Select]
  1. DIM scrn AS my_scrn
  2. DIM page AS my_page
  3. DIM margin AS my_margin
  4. DIM scrb AS my_scrb
  5. DIM cursor AS my_cursor
  6. DIM mb AS my_mb
  7.  
  8.  
  9. TYPE my_scrn
  10.     w AS INTEGER
  11.     h AS INTEGER
  12.  
  13. TYPE my_page
  14.     w AS INTEGER
  15.     h AS INTEGER
  16.     c AS INTEGER
  17.  
  18. TYPE my_margin
  19.     t AS INTEGER
  20.     b AS INTEGER
  21.     l AS INTEGER
  22.     r AS INTEGER
  23.  
  24. TYPE my_scrb
  25.     t AS INTEGER
  26.     b AS INTEGER
  27.     l AS INTEGER
  28.     x AS INTEGER
  29.     i AS INTEGER
  30.     d AS INTEGER
  31.     h AS INTEGER
  32.     s AS INTEGER
  33.     opt AS INTEGER
  34.     adjust AS INTEGER
  35.  
  36. TYPE my_cursor
  37.     find AS INTEGER
  38.     scbrrow AS INTEGER ' row + scr
  39.     scbrcol AS INTEGER ' POS(0)
  40.     holdscr AS INTEGER ' Holds scr
  41.     holdrow AS INTEGER ' Holds row
  42.     holdscrbx AS INTEGER ' Holds scrb.x
  43.  
  44. TYPE my_mb
  45.     l AS INTEGER
  46.     r AS INTEGER
  47.     m AS INTEGER
  48.     drag AS INTEGER
  49.     dragon AS INTEGER
  50.  
  51. ' DEMO -----------------------------------------------------------------
  52. DIM SHARED debug%
  53. DO: PRINT "Input screen width: 60 - 140, blank for default or -1 for debug mode: ";: INPUT screen_width%
  54.     IF screen_width% = -1 THEN debug% = -1: margin.t = 1: margin.b = 1: margin.l = 127: margin.r = 5: screen_width% = 150: noe = 99: GOTO make_fake_text ' Debug mode.
  55.     IF screen_width% = 0 THEN margin.t = 1: margin.b = 1: margin.l = 10: margin.r = 12: screen_width% = 80: noe = 40: GOTO make_fake_text ' Use defaults for demo.
  56.     IF screen_width% >= 60 AND screen_width% <= 140 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  57. DO: PRINT "Input number of text entries 10 - 99: ";: INPUT noe
  58.     IF noe >= 10 AND noe <= 99 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  59. DO: PRINT "Input margin top 0 to 10: ";: INPUT margin.t
  60.     IF margin.t >= 0 AND margin.t <= 10 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  61. DO: PRINT "Input margin bottom 0 to 10: ";: INPUT margin.b
  62.     IF margin.b >= 0 AND margin.b <= 10 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  63. DO: PRINT "Input margin left 0 to 20: ";: INPUT margin.l
  64.     IF margin.l >= 0 AND margin.l <= 20 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  65. DO: PRINT "Input margin right 2 to 20: ";: INPUT margin.r
  66.     IF margin.r >= 2 AND margin.r <= 20 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  67. DO: PRINT "Input scrollbar indicator type 1 single 0 Expands per elements: ";: INPUT scrb.opt
  68.     IF scrb.opt >= 0 AND scrb.opt <= 1 THEN EXIT DO ELSE PRINT: PRINT "Redo...": PRINT
  69.  
  70. make_fake_text:
  71. CLS: REDIM x$(noe)
  72. FOR i% = 1 TO noe
  73.     FOR j% = 1 TO screen_width% - (margin.l + margin.r) - 3
  74.         k% = (RND * 24) + 97 + 8
  75.         IF k% > 122 THEN
  76.             IF RIGHT$(x$(i%), 1) <> " " AND LEN(x$(i%)) THEN a$ = " " ELSE a$ = CHR$((RND * 24) + 97)
  77.         ELSE
  78.             a$ = CHR$(k%)
  79.         END IF
  80.         x$(i%) = x$(i%) + a$
  81.     NEXT j%
  82.     x$(i%) = STRING$(2 - LEN(LTRIM$(STR$(i%))), "0") + LTRIM$(STR$(i%)) + " " + x$(i%)
  83. NEXT i%
  84.  
  85. WIDTH screen_width%, 25
  86. IF screen_width% > 90 THEN _SCREENMOVE 0, 0
  87. ' End Demo ------------------------------------------------------------------
  88.  
  89. GOSUB getvar_setscrn
  90.  
  91.     IF debug% THEN GOSUB debugger ' Debug only.
  92.  
  93.     GOSUB displayscrn
  94.  
  95.     GOSUB makescrb
  96.  
  97.     GOSUB getkey
  98.  
  99. getvar_setscrn:
  100. scrn.w = _WIDTH
  101. scrn.h = _HEIGHT
  102. scrb.x = 0 ' Relative position of the scrollbar cursor from top of scrb.h. 0 Off / 1 to
  103. page.w = scrn.w - (margin.l + margin.r)
  104. page.h = scrn.h - (margin.t + margin.b)
  105. scrb.t = margin.t + 1
  106. scrb.b = margin.t + page.h
  107. scrb.l = margin.l + page.w + 2
  108. page.w = scrn.w - (margin.l + margin.r)
  109. page.h = scrn.h - (margin.t + margin.b)
  110. scrb.d = scrb.b - scrb.t + 1
  111. scrb.h = scrb.b - scrb.t - 1 ' Max. vertical scroll. Bar minus the top and bottom arrow symbols.
  112. IF scrb.opt = 0 THEN
  113.     scrb.s = (scrb.h + 1) * 2 - noe: IF scrb.s <= 0 THEN scrb.s = 1
  114.     scrb.s = 1
  115.  
  116. IF row = 0 THEN row = 1
  117. IF page.c = 0 THEN page.c = 7 ' Cursor apearance as underline.
  118. LOCATE margin.t + row, margin.l + 1, 1, 7, page.c
  119. GOSUB getcurrow: cursor.find = -1
  120.  
  121. displayscrn:
  122. yy% = CSRLIN: xx% = POS(0)
  123. LOCATE , , 0: ' Cursor hide.
  124. j% = 0
  125. DO ' page.h determines how mnay rows of text are displayed.
  126.     j% = j% + 1
  127.     LOCATE margin.t + j%, margin.l + 1
  128.     PRINT x$(scr + j%);
  129.     IF j% = page.h OR j% = noe THEN EXIT DO
  130. LOCATE yy%, xx%
  131. IF cursor.find THEN
  132.     cursor.find = 0
  133.     IF cursor.scbrrow > scr AND cursor.scbrrow <= scr + page.h THEN
  134.         LOCATE margin.t + cursor.scbrrow - scr, cursor.scbrcol, 1 ' Cursor show.
  135.     END IF
  136.     LOCATE , , 1 ' Show cursor.
  137.  
  138. makescrb:
  139. yy% = CSRLIN: xx% = POS(0)
  140. LOCATE scrb.t, scrb.l
  141. COLOR 0, 7
  142. PRINT CHR$(24);
  143. COLOR 7, 0
  144. FOR i% = 1 TO scrb.h
  145.     LOCATE scrb.t + i%, scrb.l
  146.     PRINT CHR$(177);
  147. NEXT i%
  148. LOCATE scrb.b, scrb.l
  149. COLOR 0, 7
  150. PRINT CHR$(25);
  151. COLOR 7, 0
  152.  
  153. IF noe > scrb.h + 2 THEN
  154.     FOR i% = 1 TO scrb.s
  155.         LOCATE scrb.t + scrb.x + i%, scrb.l
  156.         COLOR 1, 0
  157.         PRINT CHR$(176); ' Scrollbar index cursor.
  158.     NEXT
  159.     COLOR 7, 0
  160. LOCATE yy%, xx%
  161.  
  162. getkey:
  163. row = CSRLIN - margin.t
  164.     _LIMIT 60
  165.     b$ = INKEY$
  166.     IF LEN(b$) THEN
  167.         SELECT CASE b$
  168.             CASE CHR$(0) + "R"
  169.                 IF page.c = 7 THEN page.c = 30 ELSE page.c = 7
  170.                 LOCATE , , 1, 7, page.c
  171.             CASE CHR$(0) + "H"
  172.                 GOSUB backtocursor
  173.                 IF row + scr > 0 THEN
  174.                     IF row = 1 THEN
  175.                         IF scr > 0 THEN
  176.                             scr = scr - 1
  177.                             GOSUB displayscrn
  178.                         END IF
  179.                     ELSE
  180.                         row = row - 1
  181.                     END IF
  182.                     LOCATE row + margin.t, margin.l + 1
  183.                     GOSUB getcurrow
  184.                 END IF
  185.             CASE CHR$(0) + "P"
  186.                 GOSUB backtocursor
  187.                 IF row + scr < noe THEN
  188.                     IF row = page.h THEN
  189.                         scr = scr + 1
  190.                         GOSUB displayscrn
  191.                     ELSE
  192.                         row = row + 1
  193.                     END IF
  194.                     LOCATE row + margin.t, margin.l + 1
  195.                     GOSUB getcurrow
  196.                 END IF
  197.             CASE CHR$(9)
  198.                 RUN
  199.             CASE CHR$(27)
  200.                 SYSTEM
  201.         END SELECT
  202.  
  203.         ' Reverse algorithm. Not needed for this routine. scrb.x = scrb.i / ((noe - scrb.d) / (scrb.h - scrb.s))
  204.  
  205.         IF row + scr >= INT((scrb.x + 1) * ((noe - scrb.d) / (scrb.h - scrb.s))) + page.h THEN
  206.             scrb.x = scrb.x + 1
  207.  
  208.             GOSUB makescrb
  209.  
  210.             scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  211.         ELSEIF row + scr <= scrb.i THEN
  212.             scrb.x = scrb.x - 1
  213.  
  214.             GOSUB makescrb
  215.  
  216.             scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  217.         END IF
  218.     END IF
  219.  
  220.     IF delay.on! THEN ' Scrollbar delay.
  221.         _DELAY delay.on!
  222.         delay.on! = 0 ' Toggle off.
  223.     END IF
  224.  
  225.     mb.m = 0
  226.         mb.l = _MOUSEBUTTON(1)
  227.         mb.m = mb.m + _MOUSEWHEEL
  228.     WEND
  229.  
  230.     IF mb.l OR mb.m THEN
  231.         mx% = _MOUSEX ' Mouse column.
  232.         my% = _MOUSEY ' Mouse row.
  233.  
  234.         IF mx% = scrb.l AND scrb.s AND my% >= scrb.t AND my% <= scrb.b OR scrbardrag% AND my% > scrb.t AND my% < scrb.b OR mb.m > 0 AND scrb.x + scrb.s < scrb.h OR mb.m < 0 AND scrb.x <> 0 THEN ' Mouse on scrollbar or doing a bar cursor drag or using the scroll wheel.
  235.             IF my% = scrb.t AND scrb.x > 0 OR my% = scrb.b AND scrb.x + scrb.s < scrb.h OR mb.m THEN ' Mouse on a scrollbar arrow.
  236.                 IF my% = scrb.t OR mb.m < 0 THEN scrb.x = scrb.x - 1 ELSE scrb.x = scrb.x + 1 ' Top or bottom arrow.
  237.                 IF mb.m = 0 THEN delay.on! = .15
  238.                 scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  239.                 scr = scrb.i
  240.                 cursor.find = -1
  241.                 EXIT DO
  242.             ELSEIF my% - (scrb.t + 1) >= scrb.x AND my% - (scrb.t + 1) <= scrb.x + scrb.s - 1 AND scrbardrag% = 0 THEN ' Mouse on scrollbar cursor.
  243.                 scrbardrag% = -1: scrb.adjust = (my% - (scrb.t + 1)) - scrb.x
  244.             ELSEIF my% > scrb.t AND my% < scrb.b THEN ' Mouse on scrollbar between scrollbar arrow and cursor.
  245.                 IF my% - (scrb.t + 1) - scrb.adjust >= 0 AND my% - (scrb.t + 1) + scrb.s - scrb.adjust <= scrb.h OR scrbardrag% = 0 THEN
  246.                     IF scrbardrag% = 0 THEN ' NO drag, so adjust for cursor length for a click inside the scrollbar above or below the current scrollbar cursor position.
  247.                         IF my% - (scrb.t + 1) > scrb.x THEN
  248.                             scrb.adjust = (my% - (scrb.t + 1)) - scrb.x - 1
  249.                         ELSE
  250.                             scrb.adjust = (my% - (scrb.t + 1)) - scrb.x + 1
  251.                         END IF
  252.                     END IF
  253.                     scrb.x = my% - (scrb.t + 1) - scrb.adjust
  254.                     scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  255.                     scr = scrb.i
  256.                     cursor.find = -1
  257.                     EXIT DO
  258.                 ELSE ' Scrollbar is at top or bottom and mouse cursor is moving vertically along the scrollbar cursor. This allows the variable to readjust.
  259.                     IF mx% = scrb.l THEN scrbardrag% = 0: scrb.adjust = 0
  260.                 END IF
  261.             END IF
  262.         ELSEIF my% >= margin.t + 1 AND my% <= margin.t + page.h THEN
  263.             IF mx% >= margin.l + 1 AND mx% <= scrn.w - margin.r THEN
  264.                 LOCATE my%, mx%, 1 ' Locate by left mouse click and show cursor.
  265.                 GOSUB getcurrow
  266.             END IF
  267.         END IF
  268.     ELSE
  269.         scrbardrag% = 0: scrb.adjust = 0
  270.     END IF
  271.  
  272. getcurrow:
  273. row = CSRLIN - margin.t
  274. cursor.scbrrow = row + scr
  275. cursor.scbrcol = POS(0)
  276. cursor.holdscr = scr
  277. cursor.holdrow = row
  278. cursor.holdscrbx = scrb.x
  279.  
  280. backtocursor:
  281. IF cursor.scbrrow > scr AND cursor.scbrrow <= scr + page.h THEN
  282.     ' Display region does not contain cursor. Do nothing.
  283. ELSE ' Display region contains the cursor.
  284.     scr = cursor.holdscr
  285.     row = cursor.holdrow
  286.     scrb.x = cursor.holdscrbx
  287.     scrb.i = scr
  288.     GOSUB makescrb
  289.     GOSUB displayscrn
  290.  
  291. debugger:
  292. ss% = CSRLIN: tt% = POS(0)
  293. LOCATE 2, 1
  294. PRINT " initiate_scrb% ="; initiate_scrb%
  295. PRINT " scrn.w ="; scrn.w; " scrn.h ="; scrn.h; scrb.s; "     "
  296. PRINT " margin.t ="; margin.t; " margin.b ="; margin.b; " margin.l ="; margin.l; " margin.r ="; margin.r; scrb.s; "     "
  297. 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; "     "
  298. PRINT " cursor.find ="; cursor.find; " cursor.scbrrow ="; cursor.scbrrow; " cursor.scbrcol = "; cursor.scbrcol; scrb.s; "     "
  299. PRINT " cursor.holdscr ="; cursor.holdscr; " cursor.holdrow ="; cursor.holdrow; " cursor.holdscrbx ="; cursor.holdscrbx
  300. 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; "   "
  301. LOCATE ss%, tt%
  302. _DELAY .05

Now I have a library version, but I'm skeptical of being able to use it. Between the need for a display and key input, you just cannot easily make this routine into a separate drag and drop library. I'll probably just marry it to an editor routine, anyway.

I now need to go through the code and start renaming variables, refining, etc. For instance, apparently the little square in the scrollbar is called a "box" or "thumb" and I have to change that in some remarks. Any other comments as to better names, etc. are welcome.

I'm done with all the algorithms. I refined those from the library ones I posted a couple of days ago in a different thread, and I have to say they are pretty tight.

Try it for fun, and make use of it if you need to put a scrollbar routine in any of your SCREEN ZERO programs.

Note: The demo may not be 100% goof proof, but I don't care. It's only included so folks can fiddle with different set ups.

Pete

Edited to include mouse wheel scrolling.
« Last Edit: October 31, 2020, 05:45:15 am by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Hey gang, fun little scrollbar demo routine...
« Reply #1 on: October 31, 2020, 02:44:25 am »
@Pete, sorry I have to say, all those lines of code and you can't scroll with mouse wheel? I was kind of surprised.

Scrollbar looks and works fine though, I guess with screen 0 you have to put up with those narrow bars with the funny dots ;-))

« Last Edit: October 31, 2020, 02:51:13 am by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey gang, fun little scrollbar demo routine...
« Reply #2 on: October 31, 2020, 04:37:26 am »
You can drag it, even if you move off the bar, but keepthe mouse button down (drag) or you can click off the box in the bar, but no, I didn't add a wheel function... well, not yet. That's an easy add though. What's not so easy is incorporating this into an editor, which is why I punted on it as a library. I've got the arrow keys working in an editor, but I have to fiddle a little more to get the mouse routine working properly. After I fix that, I'll add a mouse wheel.

Narrow? Who in the hell wants a big fat scroll bar? They are a drain on our health care system, and look awful in a speedo. I bet those dots don't look so bad after saying that!

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Hey gang, fun little scrollbar demo routine...
« Reply #3 on: October 31, 2020, 06:15:09 am »

@Pete

Quote
SCREEN ZERO programs.

I make sure i use it in all of mine pete i promise! :)

Unseen

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Hey gang, fun little scrollbar demo routine...
« Reply #4 on: October 31, 2020, 06:29:11 am »
Nicely done, Pete.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Hey gang, fun little scrollbar demo routine...
« Reply #5 on: October 31, 2020, 06:34:55 am »
@Pete

I make sure i use it in all of mine pete i promise! :)

Unseen

Are you saying you have NO SCREEN ZERO programs? You are DEAD to me... Oh wait, you think FB sucks. Consider yourself resurrected, and officially off my non-screen zero smite list.  Sorry for being a smite ASCII.

@ Petr, thanks! :)

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/