Tuesday, 5 February 2013

Scrolling a panel

We discovered in this post the panels, today we discover that they can be scrolled.
First of all you must notice that a standard panel like:
myp: panel [button]
it contains a block for the pane value, instead a panel like this:
myp: panel 200x200 []
myp/pane: layout/tight [button]

it contains an object (a face) as pane. A face to scroll is easier to scroll of a block...
So we need to create a function to scroll both versions. The following script scroll a panel vertically, but if you exchange all Y of the script with X, you'll obtain a function to scroll horizontally:




Rebol []
scroll-panel-y: func [
    "Scroll a panel vertically"
    panel "Panel to scroll"   [object!]
    amount "amount to scroll" [number!]
    /local
    pane delta minsizy maxsizey
    ] [
        pane: panel/pane
        either block? pane[
            ;it's a basic panel
            minsizey: maxsizey: 0
            ;so we get the maximumy y:
            forall pane [
                maxsizey: maximum maxsizey   pane/1/offset/y
                ]
            ;so we get the minimum y:
            forall pane [minsizey: minimum minsizey   pane/1/offset/y ]
            delta:   maxsizey - minsizey ; this is the real size of the pane inside the panel
            delta:   delta - panel/size/y ; this is the size of theoverflow of the pane respect the panel size
            if negative? delta [exit ] ; if pane is smaller than panel, you don't need this function
            ; we store the orginal offset in user-data field of each faces, usually user-data is never used...
            forall pane [
                if none? pane/1/user-data [pane/1/user-data: pane/1/offset]        
                ]
            forall pane [pane/1/offset: pane/1/user-data - (as-pair 0 (amount * delta)) ]
            show panel  
            ][
            ;it's a mnipulated panel, pane contain a face (object!). and its offset is 0x0
            delta:   pane/size/y - panel/size/y ; this is the size of theoverflow of the pane respect the panel size        
            if negative? delta [ exit ] ; if pane is smaller than panel, you don't need this function
            pane/offset:   0x0 - (as-pair 0 (amount * delta))
            show panel
            ]
        ]
view layout [
    text "Example"
    button "Object version" [
        myp/pane:   layout/tight [text "Object version" button button button btn btn btn btn btn btn btn btn btn btn btn btn ]
        show myp
        ]
    across
    myp: panel   120x200 [
        text "Block version"
        btn btn btn btn btn btn btn btn btn btn btn btn
        ] edge [size: 2x2]  
    scroller   [scroll-panel-y myp   face/data ]  
    ]

There is also another way, avoid to create an object in panel; this code works:
myp: panel 200x200 []
myp/pane: get 'pane layout/tight [button]

it puts a working block in myp/pane, but I prefer to have a face instead a block, it's really more easy to control.

No comments:

Post a Comment