Adding a Scrollbar to Text

Author: Carl Sassenrath
This example requires REBOL/View
Return to REBOL Cookbook

Here's an example that shows how to scroll one or more text faces in a REBOL/View window. This method of scrolling runs very fast on most types of systems. (By the way, a future version of REBOL/View will have this built-in.)

The code below creates a layout that contains a text face (t1) with a scroll bar (s1).

    out: layout [
        h3 "Text Scrolling Example" return
        space 0
        t1: text 600x300 wrap green black font-name font-fixed 
        s1: scroller 16x300 [scroll-tface t1 s1]
        pad 0x5 space 5
        button "Open" [open-tface t1 s1]

The text field (t1) above must have the WRAP option (or AS-IS option) in order to force the layout to copy its PARA object. If you don't, then you will end up scrolling all text faces that share the same PARA object (which you will see when they are redrawn in the window).

Scroller Style in Updated REBOL/View

Note that the scroller style used above is found in the newer versions of REBOL/View. You can obtain newer versions from the www.rebol.net developer site.

If you want to use this code with older versions of REBOL, you can replace the word SCROLLER above with the word SLIDER.

When the scroll bar is moved, the SCROLL-TFACE function is called. This function modifies the text paragraph SCROLL value, which will shift the text within its face (vertically in this case, but you could also scroll it horizontally). This function uses size information that is stored in the user-data field by the UPDATE-TFACE function below.

    scroll-tface: func [txt bar][
        txt/para/scroll/y: negate bar/data *
            (max 0 txt/user-data - txt/size/y)
        show txt

The OPEN-TFACE function reads a text file and then resets and updates the text face.

    open-tface: func [txt bar /local file][
        if file: request-file [
            txt/text: read first file
            reset-tface txt bar

The RESET-TFACE function sets the the text and the scroll bar back to the top. We also put the SHOW function here to refresh the display (but you don't have to put it here if you have a better place for it).

    reset-tface: func [txt bar][
        txt/para/scroll/y: 0
        bar/data: 0
        update-tface txt bar
        show [txt bar]

The UPDATE-TFACE function recomputes important text information whenever text is changed within the face. Setting the line list to NONE forces a face to re-render all of it's text lines. The USER-DATA field holds the new size of the text, and the REDRAG function changes the scroll bar knob (dragger) to the correct proportional size.

    update-tface: func [txt bar] [
        txt/line-list: none
        txt/user-data: second size-text txt
        bar/redrag txt/size/y / txt/user-data

If you put all these pieces together into a script file you can give it a try. At the bottom add:

    view out

Note that if an error happens, you may need to update to a newer version of REBOL/View.

You can add a horizontal scrollbar using similar code. Change the references to /Y to /X above and get the FIRST value from SIZE-TEXT rather than the second.

2006 REBOL Technologies REBOL.com REBOL.net