Hi!

I just finished two new styles for VID. The first one is a
scroller, which is a generalization of the "slider" style found in
VID. The second one is a replacement for VID's slider.

The SLIDER style is almost backward compatible with VID's slider;
only a minor change to your layouts should be needed if you add these 
styles to them: the current value of the slider is SLIDER/CURRENT
instead of SLIDER/DATA. 
    Its behaviour is different from that of VID's slider,
hopefully better; the look is the same anyway.
    This style offers more functionality wrt VID's. It is possible
to set the minimum as well as the maximum value for the slider.
Examples:

...
do %scroller-styles.r
...
view layout [
    styles scrollers
    ...
    slider ; as for VID's (from 1 to size)
    slider 310 ; range from 1 to 310
    slider minimum 5 maximum 20 ; range from 5 to 20
    ...
]
...

(SLIDER is implemented as a special case of SCROLLER, so it has
all of its features; the difference between the two is only in
default values.)

The SCROLLER style is very similar to the one found in my previous
script CID-Utils.r. It is designed to be used to scroll areas.
Other than the obvious minimum and maximum value parameters, it
has a VISIBLE parameter that is used to specify how much of the
area is visible.
    So, VISIBLE is the size of the visible area; MINIMUM is the
value the scroller should have when the top of the area is
visible; MAXIMUM is the value the scroller should have when the
bottom of the area is visible.
    By default, the scroller comes with two arrows. It is possible
to choose their position; by default they are as I like them, on
both sides of the scroller. (I know some of you DON'T like them
this way, but I repeat that this is just the default.) Pressing an
arrow will increase/decrease the scroller's value by 5 (this can
be changed too).
    Some examples:

...
do %scroller-styles.r
...
view layout [
    styles scrollers
    ...
    scroller ; just a vertical scroller with arrows, going from 0
             ; to 150, visible 50
    scroller minimum 10 maximum 100 visible 30 ; you can guess
    scroller options [without arrows] ; no arrows
    scroller options [with arrows together] ; both arrows on the
                                            ; same side
    scroller options [with arrows skipping 10] 
                    ; pressing an arrow will skip 10
    ...
]
...

For those of you who like having the arrows together, I'd suggest
defining your own style:

    ...
    styles scrollers
    style my-scroller scroller options [with arrows together]
    ...
    my-scroller ...
    ...

Ok, enough for now. I hope to put up a REB site soon with
documentation ad examples.

See ya,
    Gabriele.
-- 
Gabriele Santilli <[EMAIL PROTECTED]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
REBOL [
        Title: "Scroller and slider styles for VID"
        Author: "Gabriele Santilli"
        File: %scroller-styles.r
        Date: 13-Jun-2000
        Version: 1.3.0 ; majorv.minorv.status
        ; status: 0: alpha; 1: beta; 2: gamma
        History: [
                11-Jun-2000 1.1.0 "First version"
        13-Jun-2000 1.2.0 "Finished writing it, now going to test it..."
        13-Jun-2000 1.3.0 "(Hopefully) fixed all noticed bugs"
        ]
]

scroller-feels: make object! [
        knob-feel: make face/feel [
                engage: func [
                        face action event
                ] [
                        if zero? face/knob-span [exit]
                        if action = 'down [face/mouse-start: event/offset exit]
                        if find [over away] action [
                                face/offset: min max face/zero-offset face/offset + 
((event/offset - face/mouse-start) * face/way) face/max-offset
                                do face/action
                                show face
                        ]
                ]
        ]
        arrow-feel: make face/feel [
                engage: func [
                        face action event
                ] [
                        switch action [
                                time [
                                        if face/clicked [
                        either face/delay = 0 [do face/action] [face/delay: face/delay 
- 1]
                                        ]
                                ]
                                down [
                                        face/clicked: yes
                                        face/edge/effect: 'ibevel
                                        face/rate: 15
                    face/delay: 3
                                        show face
                                        do face/action
                                ]
                                up [
                                        if face/clicked [
                                                face/rate: none
                                                face/clicked: no
                                                face/edge/effect: 'bevel
                                                show face
                                        ]
                                ]
                                over [
                                        if not face/clicked [
                                                face/clicked: yes
                                                face/edge/effect: 'ibevel
                                                face/rate: 15
                        face/delay: 0
                                                show face
                                        ]
                                ]
                                away [
                                        if face/clicked [
                                                face/clicked: no
                                                face/edge/effect: 'bevel
                                                face/rate: none
                                                show face
                                        ]
                                ]
                        ]
                ]
        ]
        slider-feel: make face/feel [
                engage: func [
                        face action event
                        /local ofst scroller
                ] [
                        if action = 'down [
                                scroller: face/parent-face
                                either ((event/offset + face/offset) * scroller/way) < 
(scroller/knob/offset * scroller/way) [
                                        sc-set-current/do-action scroller 
scroller/current - scroller/visible
                                ] [
                                        sc-set-current/do-action scroller 
scroller/current + scroller/visible
                                ]
                        ]
                ]
        ]
]

scrollers: stylize [
        scroller face [
                color: image: effect: none
                edge: [color: image: effect: none]
                size: 17x200
                area-size:
                vis-ratio:
                space:
                invisible:
                way: none
                minimum: 0
                maximum: 100
                visible: 50
                current: 0
                pane: [slider knob arrow-up arrow-down]
                slider:
                arrow-up: arrow-down: none
                knob: make face [
                max-offset:
                        zero-offset:
                        way:
                        boundaries:
                        knob-span:
                        mouse-start: none
                        edge: make edge [size: 1x1 color: 128.128.128 effect: 'bevel]
                        feel: scroller-feels/knob-feel
                        action: none
                ]
                with-arrows?: yes
                arrows-together?: no
                arrow-skip: 5
                words: compose [
                        minimum maximum visible (func [new args] [
                                if integer? second args [set in new first args second 
args]
                                next args
                        ])
                        options (func [new args /local val] [
                if not block? second args [next args]
                                parse second args [
                                        any [
                        'without 'arrows (new/with-arrows?: no)
                                          | 'with 'arrows (new/with-arrows?: yes)
                                                opt ['together (new/arrows-together?: 
yes)]
                                                opt [
                                'skipping args: (
                                set [val args] do/next args
                                if integer? :val [new/arrow-skip: val]
                            )
                            :args
                        ]
                                          | 'horizontal (new/way: 1x0)
                                          | 'vertical (new/way: 0x1)
                                        ]
                                ]
                                next args
                        ])
                ]
                init: [
                        if not way [way: pick [1x0 0x1] size/x > size/y]
            if not maximum [maximum: any [data pick size way = 1x0]]
                        slider: make face [
                color: 100.100.100
                image: effect: none
                                edge: make edge [color: 128.128.128 effect: 'ibevel]
                                feel: scroller-feels/slider-feel
                        ]
                        slider/size: size
                        if with-arrows? [
                                arrow-up: make get-style 'arrow [clicked: no delay: 5]
                arrow-down: make arrow-up []
                                arrow-up/data: select [1x0 left 0x1 up] way
                                do arrow-up/init
                                arrow-down/data: select [1x0 right 0x1 down] way
                                do arrow-down/init
                                arrow-up/size: size * reverse way
                                arrow-up/size: arrow-up/size + reverse arrow-up/size
                                arrow-down/size: arrow-up/size
                                slider/size: slider/size - (arrow-up/size * 2 * way)
                                slider/offset: either arrows-together? [0x0] 
[arrow-up/size * way]
                                arrow-down/feel: arrow-up/feel: 
scroller-feels/arrow-feel
                                arrow-up/action: [sc-set-current/do-action self 
current - arrow-skip]
                                arrow-down/action: [sc-set-current/do-action self 
current + arrow-skip]
                                arrow-up/offset: either arrows-together? [way * 
slider/size] [0x0]
                                arrow-down/offset: way * (slider/size + arrow-up/size)
                        ]
                        space: (slider/size - (slider/edge/size * 2)) * way
                        space: space/x + space/y
                        knob: make knob []
                        knob/way: way
                        knob/zero-offset: slider/offset + slider/edge/size
                        knob/action: [
                                data: (invisible * (knob/offset - knob/zero-offset)) / 
knob/knob-span
                                sc-set-current/do-action/don't-update self minimum + 
data/x + data/y
                        ]
                        sc-set-parameters self minimum maximum visible
                ]
        ]
    slider scroller [
        minimum: 1
        maximum: none
        visible: 1
        with-arrows?: no
    ]
]


sc-set-parameters: func [
        "Set scroller parameters"
        face [object!] "Scroller face"
        minval [integer!] "Minimum value"
        maxval [integer!] "Maximum value"
        visible-area [integer!] "Size of the visible area"
] [
        do bind [
                minimum: minval
                maximum: maxval
                invisible: maximum - minimum
                current: minimum
                visible: visible-area
                area-size: visible + invisible
                vis-ratio: visible / area-size
                knob/offset: knob/zero-offset
                knob/size: size * reverse way
                knob/size: knob/size + reverse knob/size
                knob/size: max knob/size (way * to-integer vis-ratio * space) + (size 
* reverse way)
                knob/size: knob/size - (slider/edge/size * 2)
                knob/max-offset: (knob/zero-offset + (space * way)) - (knob/size * way)
                knob/knob-span: (knob/max-offset - knob/zero-offset) * way
                knob/knob-span: knob/knob-span/x + knob/knob-span/y
        ] in face 'self
]

sc-set-current: func [
        "Set a scroller's current value"
        face [object!] "Scroller face"
        value [integer!]
        /don't-update "Do not update knob position"
        /do-action "Do user specified action"
] [
        value: max min value face/maximum face/minimum
        if value <> face/current [
        face/current: value
        if all [not don't-update not zero? face/knob/knob-span] bind [
            knob/offset: knob/zero-offset + ((way * (value - minimum) * 
knob/knob-span) / invisible)
            show knob
        ] in face 'self
        if do-action [do face/action]
    ]
]

Reply via email to