REBOL [
    Title: "Grid layout"
    Purpose: {Take a block of data consisting of sub-blocks
    and return a layout that has a grid of the supplied data
    along with a scroller.}
]

;; [---------------------------------------------------------------------------]
;; [ This is based on an idea in Nick Antonaccio's document for creating       ]
;; [ business applications at:                                                 ]
;; [ http://business-programming.com/business_programming.html                 ]
;; [ The goal is to create a function that could be fed the results of an      ]
;; [ SQL query and poof!...up would pop a grid containing the data items       ]
;; [ from the query.                                                           ]
;; [ The result of an SQL query is a block of blocks, and each sub-block       ]
;; [ contains the data items from one row of the query.                        ]
;; [ The way this works is to generate VID code where each item of the         ]
;; [ input data has its own field on a VID layout.                             ]
;; [ Note the double loop.  For each sub-block of input, we generate a row     ]
;; [ of data fields.  For each item in the sub-block, we generate one info     ]
;; [ field on that row.                                                        ]
;; [ This was designed for quick-and-dirty viewing of small queries.           ]
;; [ It appears that the "info" style has a certain default size,              ]
;; [ and a query that produces many columns could waste a lot of horizontal    ]
;; [ space if every column got the default size.  To "fix" that the            ]
;; [ function takes a second block which is a list of column widths in         ]
;; [ pixels for each column of a data sub-block.  It is the job of the         ]
;; [ caller to make sure this block of columns sizes has the same number       ]
;; [ of items as the data sub-blocks, and the column widths are big enough.    ]
;; [ This module really should be an object, but we had a bit of trouble       ]
;; [ when we had it as an object and used a second similar module for          ]
;; [ a second similar layout.  The scroll bars were not scrolling their        ]
;; [ intended grids.  We left that problem unsolved.                           ]
;; [---------------------------------------------------------------------------]

GLO-BOXHEIGHT: 500 
GLO-BOXWIDTH: 0
GLO-BOXSIZE: none 

GLO-LAYOUT: func [
    GLOBLOCK
    GLOWIDTHS
    /local GLOGRID GLODISP GLOCOL
] [
    GLO-BOXWIDTH: 0
    foreach WIDTH GLOWIDTHS [
        GLO-BOXWIDTH: GLO-BOXWIDTH + WIDTH
    ]
    GLO-BOXSIZE: to-pair reduce [GLO-BOXWIDTH GLO-BOXHEIGHT] 
    GLOGRID: copy [across space 0]
    foreach BLK GLOBLOCK [
        GLOCOL: 0 
        foreach COL BLK [
            GLOCOL: GLOCOL + 1
            append GLOGRID compose [
                info (pick GLOWIDTHS GLOCOL) (form COL) 'bold
            ]
         ]
         append GLOGRID compose [return]
    ]
    GLODISP: layout/tight [
        across
        GLOBOX: box GLO-BOXSIZE with [ ;; "with" lets us get at internals
            pane: layout/tight GLOGRID pane/offset: 0x0
        ]
        scroller to-pair reduce [20 second GLO-BOXSIZE] [
            GLOBOX/pane/offset/y: GLOBOX/size/y - GLOBOX/pane/size/y * value
            show GLOBOX
        ]
    ]
    return GLODISP
]

;;Uncomment to test
;view center-face GLO-LAYOUT [
;    ["01" "AAAA" "1111"]
;    ["02" "BBBB" "2222"]
;    ["03" "CCCC" "3333"]
;    ["04" "DDDD" "4444"]
;    ["05" "EEEE" "5555"]
;    ["06" "FFFF" "6666"]
;    ["07" "GGGG" "7777"]
;    ["08" "HHHH" "8888"]
;    ["09" "IIII" "9999"]
;    ["10" "JJJJ" "1010"]
;    ["11" "KKKK" "1111"]
;    ["12" "LLLL" "1212"]
;    ["13" "MMMM" "1323"]
;    ["14" "NNNN" "1414"]
;    ["15" "OOOO" "1515"]
;    ["16" "PPPP" "1616"]
;    ["17" "QQQQ" "1717"]
;    ["18" "RRRR" "1818"]
;    ["19" "SSSS" "1919"]
;    ["20" "TTTT" "2020"]
;    ["21" "UUUU" "2121"]
;    ["22" "VVVV" "2222"]
;    ["23" "WWWW" "2323"]
;    ["24" "XXXX" "2424"]
;    ["25" "YYYY" "2525"]
;    ["26" "ZZZZ" "2626"]
;] [40 60 100]