Monday, 21 January 2013

VID list

Yes, it's another post about LIST, but many people don't know how powerful LIST is; so I decided to make another post about the standard LIST in VID.
The following script author is Nick Antonaccio, a great developer. The script gives you a table that you can manipulate, changing cell value just clicking the cell self. You can sort by column, clicking no the relative column heading. You can also add and delete rows.
Be sure to try the following features:
  1. Resize the GUI window to see the list automatically adjust to fit  
  2. Click column headers to sort by field  
  3. Use the arrow keys and page-up/page-down keys to scroll  
  4. Use the Insert, Delete and "M" keys to add, remove and move rows (at the currently highlighted row) 
  5. Click the small "r" header button in the top right corner to reset the list back to its original values  
  6. Click any individual data cell to edit the selected value.
Here is the source:
REBOL [
    title: "List Widget Example"
    file: %list-widget-example.r
    date: 8-jul-2010
    author:   Nick Antonaccio
    purpose: {
        This examples demonstrates how to use REBOL's native GUI list
        widget to manage a grid of data values.   Columns can be sorted
        by clicking the headers.   Individual values at any column/row
        position can be edited by the user (just click the current value).
        Entire rows can be added, removed, or moved to/from user-selected
        positions.   The data block can be saved or loaded to/from file(s).
        Scrolling can be done with the mouse, arrow keys, or page-up/
        page-down keys.   Several resizing concepts are also demonstrated.
    }
]
x: copy []   random/seed now/time   ; generate 5000 rows of random data:
repeat i 5000 [
    append/only x reduce [random "asdfqwertyiop" form random 1000 form i]
]   y: copy x
Alert {Be sure to try the following features:   1) Resize the GUI window
    to see the list automatically adjust to fit   2) Click column headers
    to sort by field   3) Use the arrow keys and page-up/page-down keys to
    scroll   4) Use the Insert, Delete and "M" keys to add, remove and move
    rows (at the currently highlighted row)   5) Click the small "r" header
    button in the top right corner to reset the list back to its original
    values   6) Click any individual data cell to edit the selected value.}

sort-column: func [field] [
    either sort-order: not sort-order [
        sort/compare x func [a b] [(at a field) > (at b field)]
    ] [
        sort/compare x func [a b] [(at a field) < (at b field)]
    ]  
    show li
]
key-scroll: func [scroll-amount] [
    s-pos: s-pos + scroll-amount
    if s-pos > (length? x) [s-pos: length? x]
    if s-pos < 0 [s-pos: 0]
    sl/data: s-pos / (length? x)  
    show li   show sl
]
resize-grid: func [percentage] [
    gui-size: system/view/screen-face/pane/1/size ; - 10x0
    list-size/1: list-size/1 * percentage
    list-size/2: gui-size/2 - 95
    t-size: round (list-size/1 / 3)
    sl-size: as-pair 16 list-size/2
    unview/only gui view/options center-face layout gui-block [resize]
]
resize-fit: does [
    gui-size: system/view/screen-face/pane/1/size
    resize-grid (gui-size/1 / list-size/1 - .1)
]
insert-event-func [either event/type = 'resize [resize-fit none] [event]]
gui-size: system/view/screen-face/size - 0x50
list-size: gui-size - 60x95
sl-size: as-pair 16 list-size/2
t-size: round (list-size/1 / 3)
s-pos: 0   sort-order: true   ovr-cnt: none   svv/vid-face/color: white
view/options center-face gui: layout gui-block: [
    size gui-size   across
    btn "Smaller" [resize-grid .75]
    btn "Bigger" [resize-grid 1.3333]
    btn "Fit" [resize-fit]
    btn #"^~" "Remove" [attempt [
        indx: to-integer request-text/title/default "Row to remove:"
            form ovr-cnt
        if indx = 0 [return]
        if true <> request rejoin ["Remove: " pick x indx "?"] [return]
        remove (at x indx)   show li
    ]]
    insert-btn: btn "Add" [attempt [
        indx: to-integer request-text/title/default "Add values at row #:"
            form ovr-cnt
        if indx = 0 [return]
        new-values: reduce [request-text request-text (form ((length? x) + 1)) ]
        insert/only (at x indx) new-values   show li
    ]]
    btn #"m" "Move" [
        old-indx: to-integer request-text/title/default "Move from row #:"
            form ovr-cnt
        new-indx: to-integer request-text/title "Move to row #:"
        if ((new-indx = 0) or (old-indx = 0)) [return]
        if true <> request rejoin ["Move: " pick x old-indx "?"] [return]
        move/to (at x old-indx) new-indx   show li
    ]
    btn "Save" [save to-file request-file/save x]
    btn "Load" [y: copy x: copy load request-file/only   show li]
    btn "View Data" [editor x]
    return   space 0x0
    style header button as-pair t-size 20 black white bold
    header "Random Text" [sort-column 1]
    header "Random Number" [sort-column 2]
    header "Unique Key" [sort-column 3]
    button black "r" 17x20 [if true = request "Reset?"[x: copy y show li]]
    return
    li: list list-size [
        style cell text t-size feel [
            over: func [f o] [
                if all [o ovr-cnt <> f/data] [ovr-cnt: f/data show li]
            ]
            engage: func [f a e] [
                if a = 'up [
                    f/text: request-text/default f/text show li
                ]
            ]
        ]            
        across   space 0x0
        col1: cell blue
        col2: cell
        col3: cell red
    ] supply [
        either even? count [face/color: white] [face/color: 240.240.255]
        count: count + s-pos
        if none? q: pick x count [face/text: copy "" exit]
        if ovr-cnt = count [face/color: 200.200.255]
        face/data: count
        face/text: pick q index
    ]
    sl: scroller sl-size [s-pos: (length? x) * value   show li]
    key keycode [up] [key-scroll -1]
    key keycode [down] [key-scroll 1]
    key keycode [page-up] [key-scroll -20]
    key keycode [page-down] [key-scroll 20]
    key keycode [insert] [do-face insert-btn 1]
] [resize]

1 comment:

  1. Hey Max,

    I refactored this code to make is much easier to grok at first glance. The parts that don't need to be touched are compressed.

    Now you can do:

    headers: ["Numbers" "Text" "Dates"]
    x: [
    [1 "1" 1-1-2012]
    [11 "11" 1-2-2012]
    [2 "2" 1-3-2012]
    ]
    do http://re-bol.com/gridlib.r

    Check out http://re-bol.com/business_programming.html#section-8.1

    ReplyDelete