Question

I know how to build a pictures gallery dynamically, how do I now allow to trigger an event when the user clicks on a picture ?

I don't want to have the engage function inside the layout but outside: is it possible ?

Not sure I am clear so tell me.

Was it helpful?

Solution

A pretty easy trick is to set up a style with the action you want, and have it look at a user-data value you set when you generate the face if necessary.

lay: [
    across
    style my-box box [print [face/user-data face/color]]
]
repeat i 4 [
    repeat j 4 [
        repend lay [
            'my-box 50x50 get random/only [red green blue yellow] 
            'user-data to pair! reduce [i j]
        ]
    ]
    append lay 'return
]
view layout lay

OTHER TIPS

As said, the best is to create a style to minimized the code in the layout. So the style is already configured for the actions you want.

For a picture gallery, I would create a thumb style with my requirements.

But you do not need to use an 'engage func for simple things! If what you need is left/right click handling, then one or two actions blocks are enough and much simpler.

Here is a full example:

Rebol [
    title: "Basic image gallery"
]

thumb-size: 100x100 ; size of the thumbnails
thumbs-per-row: 6   ; number of thumbs per row

; Here is the actions I want to use when clicking/right clicking the image face.
; It's just a block: it's the 'layout function that will make it a function
; with 'face and 'value arguments
thumb-action: [
    ; left click: show full size image
    view/new layout [
        origin 2 space 2
        vh3 form (either any [file? face/user-data url? face/user-data text? face/user-data] [face/user-data] ["An image without reference"])
        image face/image
    ]
]
thumb-alt-action: [
    ; right click: open up the folder/web site where the file is
    switch/default type?/word face/user-data [
        file! [call/shell join "explorer " to-local-file first split-path face/user-data]
        url! [browse face/user-data]
    ] [alert rejoin ["Can't do anything with " type? face/user-data " type of value ! Sorry."]]
]

; Our styles for the gallery
gallery-styles: probe stylize [
    ; Here is a style for the thumbnails, with the actions wanted
    thumb: image thumb-size effect [aspect] thumb-action thumb-alt-action
]

; Some samples images
imgs: [
    ; This paths are for a typical Windows7 installation
    %/c/windows/web/wallpaper/nature/img1.jpg
    %/c/windows/web/wallpaper/nature/img2.jpg
    %/c/windows/web/wallpaper/nature/img3.jpg
    %/c/windows/web/wallpaper/nature/img4.jpg
    ; URLs as examples
    http://www.rebol.com/graphics/reb-logo.gif
    http://www.rebol.com/graphics/ref-card.jpg
]

; Base for your gallery layout
gallery-lay: copy [
    origin 2 space 2 across
    styles gallery-styles
    vh2 "Image gallery"
]

; Builds the final layout
count: 0
foreach img imgs [
    ; This for handling only a defined number of thumbs per row
    if 0 = (count // thumbs-per-row) [append gallery-lay 'return]
    count: count + 1
    ; Here you add the layout code for the current image
    append gallery-lay compose [thumb (img) user-data (img)]
]

; Here we are: the result
view layout gallery-lay

There are many ways to do this. You don't specify how you are building the picture gallery, but I'm assuming that you are building a layout of IMAGE styles and then displaying that layout.

It sounds also like you want freedom to do specific things with each image, so I suggest you build a separate style, possibly derived from IMAGE. You can do that like this:

stylize/master [
    image: image with [
        feel: make feel [
            engage: func [face act event] [
                ; do my custom engage function
            ]
        ]
    ]
]

Put the code before the layout. This way, you can keep complex code for the behavior of IMAGE outside of the layout block. When you work this way, the style is globally changed.

You can also just create a new style, by altering the name:

stylize/master [
    image2: image with [
        ...
    ]
]

IMAGE will be left untouched, while you can use IMAGE2 in your layout.

Why STYLIZE/MASTER? I use STYLIZE/MASTER out of habit, so I don't have to specify a specific style list in the layout and I can shave off a line of code for each layout.

Let's try that again:

lay: [
    across
    style my-box box [print [face/user-data face/color]]
]
repeat i 4 [
    repeat j 4 [
        repend lay [
            'my-box 50x50 get random/only [red green blue yellow] 
            'user-data to pair! reduce [i j]
        ]
    ]
    append lay 'return
]
view layout lay
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top