Rebol-View-GTK

Author: pat665
Date: 30-juin-2004

Contents

1. Introduction

2. 3002-As-pair and to-pair

3. 3004-An example of using the alpha chanel from Cyphre

4. 3005-How to change the aspect of a box with effect?

5. 3006-How to change the font of a button?

6. 3007-How to change the style of a button?

7. 3008-How to change the windows title

8. 3009-How to create draw buttons?

8.1. Creating a draw button

8.2. Adding action

8.3. Multi-colored buttons

9. 3011-How to hide a face when view is called?

10. 3012-How to make a full screen, not a window?

10.1. Pre-requisites

10.2. Yes by Anton

10.3. Yes by Ashley

11. 3013-How to navigate through window-pane?

11.1. From Romano

11.2. From Brett

12. 3014-How to simulate action on one button?

12.1. Other solutions...

13. 3015-Iterate through the faces of a layout

14. 3016-VID styles

15. 3017-Keyboard shortcuts

16. 3018-Resizing an image

17. 3019-Screen size

18. 3020-How to create a bmp file from an image

19. 3021-Selections with list

20. 3022-Stylize/master

21. 3023-Text list with no wrap

22. 3024-Usage of with in VID

22.1. Answer from Brett

22.2. Answer from Romano

23. 3025-[VID] How to reset guide?

24. 3001-Clear-fields - how to improve it?

25. 3003-Button with on-off texts

26. 3010-How to get to a field variable by its string name?


1. Introduction

This is a collection of "good-to-know" information about Rebol/View and VID. Some are mine, most are from the Rebol-List, books or articles about Rebol.

2. 3002-As-pair and to-pair

INFO

To-pair as a new friend: As-pair. Reading the new document about the Draw dialect, I found a new function 'as-pair.

>> help as-pair
USAGE:
    AS-PAIR x y

DESCRIPTION:
     Combine X and Y values into a pair.
     AS-PAIR is a function value.

ARGUMENTS:
     x -- (Type: number)
     y -- (Type: number)

This seems to be more usefull than to-pair. It is simpler to work with:

; direct value
>> as-pair 2 5
== 2x5
; variables
>> x: 3
== 3
>> as-pair x x * 2
== 3x6
>> as-pair x 2 * x
== 3x6
>> to-pair 2 5
== 5
>> to-pair [2 5]
== 2x5
>> to-pair reduce [x x * 2]
== 3x6

3. 3004-An example of using the alpha chanel from Cyphre

INFO

An example of using the alpha chanel from Cyphre.

Rebol[]

site: http://www.rebol.cz/~cyphre/
x: 0
d: 5
view center-face layout [
 origin 0x0
 image load-thru/binary site/city.jpg 320x240
 at 0x0
 image load-thru/binary site/bay.jpg 320x240 with [
  rate: 30
  effect: compose [fit alphamul (x)]
  feel: make feel [
   engage: func [f a e][
    x: x + d
    if x > 250 [d: -5]
    if x < 5 [d: 5]
    f/effect: compose [fit  alphamul (x)]
    show f
   ]
  ]
 ]
]

Here is a simple example how to use DRAW dialect for "painting" into alpha channel of the image. I think with the function make-alpha (bellow in the example) you can draw almost any kind of transparent shape though it is not the fastest method....IMO the possibility to use DRAW pens for alpha channel should be done at Rebol's native level...

make-alpha: func [fx img /local idx][
 append fx 'grayscale
 fx: to-block mold to-image make face [
  size: img/size
  effect: fx
  edge: none
 ]
 fx: fx/3/2
 img: to-block mold img
 idx: 0
 remove-each i fx [
  idx: idx + 1
  either idx > 1 [
   if idx = 3 [idx: 0]
   true
  ][
   false
  ]
 ]
 append img/3 fx
 return do load img
]

pic: load-thru/binary http://www.rebol.cz/~cyphre/bay.jpg

view center-face layout [
 backdrop effect reduce ['gradient red orange]
 image make-alpha [
  gradient 1x1 0.0.0 255.255.255
  draw [
   pen 0.0.0
   fill-pen 200.200.200
   circle 100x80 50
   fill-pen 0.0.0
   box 80x80 125x125
  ]
 ] pic
]

Note from Cyphre

Hello to myself, just little correction: You can use the make-alpha function not only with DRAW but with any other effect-block command (like the transparent gradient in the example) ..and little

note: this script need at least Rebol/View version 1.2.5 and up or Rebol/Link from the version where alpha-channel support was added.

4. 3005-How to change the aspect of a box with effect?

How to change the aspect of a box with effect?

ANSWER

Rebol []
luma-fxblock: [luma 80]

view center-face layout [
    b1: box 100x100 %nyc.jpg  effect []
    b2: box 100x100 %nyc.jpg  effect []
    btn 100 "luma" [
        insert b2/effect copy luma-fxblock
        show b2
    ]
    btn 100 "reset" [
        remove b2/effect 
        remove b2/effect 
        show b2
    ]
]

grey-fxblock: [grayscale]

view center-face layout [
    b1: box 100x100 %nyc.jpg  effect []
    b2: box 100x100 %nyc.jpg  effect []
    btn 100 "greyscale" [
        insert b2/effect copy grey-fxblock
        show b2
    ]
    btn 100 "reset" [
        remove b2/effect 
        show b2
    ]
]

color-fxblock: reduce ['colorize yellow]

view center-face layout [
    b1: box 100x100 %nyc.jpg  effect []
    b2: box 100x100 %nyc.jpg  effect []
    btn 100 "colorize" [
        insert b2/effect copy color-fxblock
        show b2
    ]
    btn 100 "reset" [
        remove b2/effect 
        remove b2/effect 
        show b2
    ]
    btn "halt" [halt]
]

5. 3006-How to change the font of a button?

How to change the font of a button ?

ANSWER

view center-face layout [
    b: button "Font Test" font [name: "Arial" size: 12]
    button "Change" [
        b/font/name: "Times"
        b/font/size: 18
        show b
    ]
]

gui: layout [
 abutton: button "rebol est cool" 150x30 [face/font: either ((face/font) = font-a) [:font-b][:font-a] show face]
]

font-a: make abutton/font [
   size: 12
]

font-b: make font-a [
   size: 18
]

abutton/font: font-a
view center-face gui

6. 3007-How to change the style of a button?

How to change the style of a button?

ANSWER

f: layout [ 
    style btn1 button green 
    style btn2 button red
    b: btn1 "ok" [b/style: 'btn2]
]
view center-face f

7. 3008-How to change the windows title

How to change the windows title?

ANSWER

Rebol[]

lay: layout/size [
        btn "Title 1" [set-face lay "Bye everybody !"]
        btn "Title 2" [set-face lay "Ok I stay here"]
] 300x100

lay/access: make lay/access [
        set-face*: func [face value] [
            face/text: value
            face/changes: 'text
        ]
]

view/title center-face lay "Hello world"

8. 3009-How to create draw buttons?

How to create draw buttons?

ANSWER

8.1. Creating a draw button

Simple shaped buttons can be designed with the draw dialect.

view center-face layout [ box 24x24 effect [draw [pen black fill-pen red circle 12x12 10]]]

This code produce a red filled circle. However this is more an image than a button because there is no action.

8.2. Adding action

As for any face, action for the right clic is provided in a block, example: [ print "hey, I'm clicked!"]. Defining a draw-button style helps us to save typing.

draw-layout: [
    h2 "Draw buttons"

    style draw-button box 24x24 effect [draw [pen black fill-pen red circle 12x12 10]]

    across
    draw-button [ print "hey, I'm clicked!"]
    draw-button [ print "hey, I'm clicked!"]
    draw-button [ print "hey, I'm clicked!"]
    draw-button [ print "hey, I'm clicked!"]
]

view center-face layout draw-layout

8.3. Multi-colored buttons

A first approach is to defined a style for each color.

draw-layout: [
    h2 "Draw buttons"

    style red-draw-button box 24x24 effect [draw [pen black fill-pen red circle 12x12 10]]
    style blue-draw-button box 24x24 effect [draw [pen black fill-pen blue circle 12x12 10]]
    style yellow-draw-button box 24x24 effect [draw [pen black fill-pen yellow circle 12x12 10]]
    style green-draw-button box 24x24 effect [draw [pen black fill-pen green circle 12x12 10]]

    across
    red-draw-button [ print "hey, I'm red"]
    blue-draw-button [ print "hey, I'm blue"]
    yellow-draw-button [ print "hey, I'm yellow!"]
    green-draw-button [ print "hey, I'm green!"]
]

view center-face layout draw-layout

Another way is to act directly on the draw block, changing only the color name. Each button is defined with an empty draw block, then a copy of the draw is inserted in the face/effect block, and finally the word 'color is replaced by the desired color.

fx-block: [pen black fill-pen color circle 12x12 10]

draw-layout: [
    h2 "Draw buttons"

    style draw-button box 24x24 effect [draw []]

    across
    red-button: draw-button [ print "hey, I'm red"]
    blue-button: draw-button [ print "hey, I'm blue"]
    yellow-button: draw-button [ print "hey, I'm yellow!"]
    green-button: draw-button [ print "hey, I'm green!"]

    do [
        insert red-button/effect/2 copy fx-block
        replace red-button/effect/2 'color 'red
        insert blue-button/effect/2 copy fx-block
        replace blue-button/effect/2 'color 'blue
        insert yellow-button/effect/2 copy fx-block
        replace yellow-button/effect/2 'color 'yellow
        insert green-button/effect/2 copy fx-block
        replace green-button/effect/2 'color 'green
    ]
]

view center-face layout draw-layout

9. 3011-How to hide a face when view is called?

How to hide a face when view is called?

ANSWER

The purpose here is to have a face invisible when the layout is displayed the first time by view. The answer is to set face/show? to false. Use show to set the face visible again

An example:

favorite: layout [
    style fv text 200 "?" with [user-data: 'fav]

    across
    fv return
    fv return
    fv return
    fv return
    fv return
    fv return
    fv return
    fv return
    fv return

    below

    btn-enter 60 "test" [f: my-favorite/6 show f]

    btn-cancel 60 "Ok" [unview favorite]

]

my-favorite: copy []

foreach face favorite/pane [
    if 'fav = face/user-data [ append my-favorite :face ]
]

lines: ["pat 11-1-1959" "annie 19-5-1959" "marc 17-12-1984" "ophélie 5-3-1983"]

i: 1
foreach line lines [
    f: my-favorite/:i
    f/text: line
    ; show f
    i: i + 1
] ;for

while [i <= length? my-favorite][
    f: my-favorite/:i
    f/text: "hidden"
    f/show?: false
    i: i + 1    
] ; w

view center-face favorite

10. 3012-How to make a full screen, not a window?

How to make a full screen, not a window?

ANSWER

10.1. Pre-requisites

  1. an offset of 0x0
  2. no-title
  3. a size get from system/view/screen-face/size

Example

view/options/offset layout [
    size system/view/screen-face/size button "Unview" [unview]
] 'no-title 0x0

Unwanted message in the top left corner

Curiously, when inserted in a program, I observe a message in the top left corner. This message is either "no title" or the title given in the header program. Can we remove this message?

10.2. Yes by Anton

The text is added by VIEW, unfortunately. But you can work around it by doing:

view/new lay: layout [...]
lay/text: none
show lay
wait none

10.3. Yes by Ashley

Just use title: ""

11. 3013-How to navigate through window-pane?

How to navigate through window/pane?

What I am looking for is a way to navigate through window/pane to change some faces without the need of a variable. For example, with a layout composed of a,b,c,d,e I would like that a click on b will change c. In other words, knowing one face, being able to move to the next or the previous face.

ANSWER

; a simple layout
lay: layout [
        text "Hello"
        button "Test" [mytest face]
]

; explore lay/pane
mytest: func [
        f [object!]
        /local f2
][
        ; here an object
        foreach face lay/pane [
                print [face/style type? face]
        ]

        ; here a block
        f2: find lay/pane f ; <----- WRONG because it is a serie
        print type? f2

]

view center-face lay

CORRECT VERSION

; a simple layout
lay: layout [
        text "Hello"
        button "Test" [mytest face]
]

; explore lay/pane
mytest: func [
        f [object!]
        /local f2
][
        ; here an object
        foreach face lay/pane [
                print [face/style type? face]
        ]

        ; here a block
        f2: first find lay/pane f
        print [f2/style type? f2]

]

view center-face lay

11.1. From Romano

view layout [
    style bt button [
        value: next find face/parent-face/pane face
        face: first either tail? value [head value][value]
        print face/offset
    ]
    bt bt bt bt bt
]

The parent-face is set only after view function has been called (= the layout function does not set it).

11.2. From Brett

In face, the Pane of a face can be one of three types:

  1. face/pane can be set to Object! - In this case the pane contains a single face. A face inside a face.
  2. face/pane can be set to Block! - In this case the pane is a collection of faces. More than one face inside a face.
  3. face/pane can be a Function! - In this case the face is iterated. "Virtual" faces that are calculated dynamically. Examples of this last one in VID is List and Text-list.

You need something to identify the face in the layout. One way is by position. If the faces are A, B, C then B would be the second face in the layout.

view lay: layout [
    text "A"
    text "B"
    text "C"
    button "Second face" [print lay/pane/2/text]
]

Or instead of navigating when you need to change, you set up a reference early - assuming your layout does not change:

lay: layout [
    across
    box "A"
    box "B"
    box "C"
    return
    button "Change" [
        if face/user-data [
            face/user-data/color: get first head reverse [blue green]
            show face/user-data
        ]
    ]
]

; Make the user-data field of button refer to the "B" text face.
lay/pane/4/user-data: lay/pane/2

view center-face lay

The third way is to search through every time looking for some identifying information. Remember though that if you have things like panels you will have a tree of faces with the top layout being the root. So you might need to search recursively. I made some functions to do this searching. Note that they cannot find the "iterated" faces.

cc: http://www.codeconscious.com/rebsite/rebol-library/face-searches.r
do load-thru cc

change-color: func [face] [
    face/color: random 255.255.255
    face
]

view/new lay1: layout [
    style box box 50x50
    across
    text "A" box "B" box "C" text "D"
    panel orange [box "E"]
    return
    button "Change D" [
        show change-color find-face [face/text = "D"]
    ]
    button "Change E" [
        show change-color find-face [face/text = "E"]
    ]
]

view/new lay2: layout/offset [
    box "D"
    button "Change Boxes" [
        repeat face find-faces [
            all [in face 'style face/style = 'box]
        ] [change-color face]
        show lay1
        show lay2
    ]
    button "Close All" [unview/all]
] add 2x1 * lay1/offset 1x0 * lay1/size

do-events

These are some ways to avoid using variables. A lot of the time variables are very useful and make understanding the code easier. You can variables in their own contexts to avoid cluttering up the global context or clashes between windows if you have more than one. Here is an example wishes uses this concept.

; Create a template spec
spec: [
    box-face: none
    lay: layout [
        box-face: box gray
        button "Change" [
            box-face/color: random 255.10.10 show box-face
        ]
    ]
]

; Create multiple layout faces in their own contexts.
context-collection: copy []
current-offset: 50x150
repeat i 5 [

    ; Create a new layout face
    ctx: context spec

    ; Add it to our collection
    append context-collection ctx

    ; Reposition it.
    ctx/lay/offset: current-offset

    ; Move our offset ready for the next
    current-offset/x: current-offset/x + 20 + ctx/lay/size/x

    ; View it
    view/new ctx/lay
]

; Close and Change all.
view/new layout/offset [
    space 0x0 origin 0x0
    button "Change All" [
        repeat ctx context-collection [
            ctx/box-face/color: random 10.255.10
            show ctx/lay
        ]
    ]
    button "Close All" [unview/all]
] 50x50

; Process events
do-events

12. 3014-How to simulate action on one button?

How to simulate action on one button?

I'd like to get the same effect as if I had done a mouse click on one button, but this "action" is originated from script itself.

ANSWER

If you create a reference to the face (e.g. my-btn: button), then you can do this:

click-face: func [face][
    face/feel/engage face 'down none
]

12.1. Other solutions...

view layout [
b: button "Test" [print "Test pressed"]
button "Action 2" [b/action b none]
]
view layout [
    b: button "Test" [print "Test pressed"]
    button "In" [b/state: true show b]
    button "Out" [b/state: false show b]
    a: button "Action" [
        b/feel/engage :b 'down none
        b/feel/engage :b 'up none
        a/state: false show a ; Not sure why this line is needed...
    ]
]

The "Action" button probably gives you the effect you want, but I'm not sure if it's the best way to do it. If the final line is missing the "Action" button itself stays down for reasons I don't understand, though it's maybe because it's sharing the engage function.

13. 3015-Iterate through the faces of a layout

How to iterate through the faces of a layout?

When you create a layout such as layout puts the set words into face/var So you can iterate through the pane faces and find them out.

lay: layout [
    my-button: button
    my-field: field
]

foreach face lay/pane [
    print [face/var face/style face/offset face/size]
]

If you want to see the words inside a face, use:

print mold first face

Anton.

Every face (like a radio) added to a window is appended to the block window/pane. The group is in the field 'related of the radio face. The variable name is in the field 'var of the radio face.

w: layout [r1: radio of 'groupe1 r2: radio of 'groupe1 r3: radio of 'groupe1]
foreach x w/pane [print [x/var x/related]]
r1 groupe1
r2 groupe1
r3 groupe1

lay: layout [
    my-button: button
    my-field: field
]

foreach face lay/pane [
    print [type? face face/var face/style face/offset face/size]
]

14. 3016-VID styles

How to get all the VID styles?

vid-styles: copy []
pad-string: "               "
cpt: 0

foreach [style x] system/view/vid/vid-styles [append vid-styles style]
sort vid-styles

foreach v vid-styles [
    style: mold v
    cpt: cpt + 1
    either cpt < 6 [
        prin [style copy/part pad-string (15 - length? style)]
    ][
        print style
        cpt: 0
    ]
]

print " "

15. 3017-Keyboard shortcuts

How to use keyboard shortcuts?

I want to put up a dialog box and press Escape to cancel it or Enter to confirm it.

hotkeys are evaluated in system/view/window-feel. and that is set automatic by 'view only for the first window. one can set it by hand. try:

lay: layout [
    tf: title "press control-t" 400
    button "test" #"^t" [
        tf/text: "you pressed the button or the key"
        show tf
    ]
]
lay/feel: system/view/window-feel
inform lay

l: layout [
    text "Press Return or Escape"
    key keycode #"^M" [
        t/text: "Return"
        show t
        unview l
    ]
    key keycode escape [
        t/text: "Escape"
        show t
        unview l
    ]
]

view center-face layout [
    t: text 100x16 "none"
    button "Get Dialog" [
    view/new/offset l 100x100
    do-events
    ]
]

inform-kb: func [ip-text /local lay lv-ok] [
    lay: layout [
        space 5
        origin 5x5
        at 5x5
        vtext ip-text bold 300x24
        return
        across
        button "OK" #"^M" [lv-ok: true hide-popup]
        button "Cancel" #"^[" [lv-ok: false hide-popup]
    ]

lay/feel: system/view/window-feel

inform lay [system/view/screen-face/size - lay/size / 2]
lv-ok
]

print inform-kb "This is a dialog box - Escape = Cancel     Enter = OK"

16. 3018-Resizing an image

The trick is to use 'layout to perform the resizing.

Example:

img: load %my-image.png
img2: to-image layout [origin 0 image 50x50 img]
save/png %my-image2.png img2

17. 3019-Screen size

How to get the screen size?

>> system/view/screen-face/size
== 1024x768

Tip!

Cette information a été découverte dans le source de la fonction center-face. This information comes from the center-face function source.

>> source center-face
center-face: func [
    {Center a face on screen or relative to another face.}
    obj [object!]
    /with "Center relative to a face." face [object!]
][
    if none? face [face: system/view/screen-face]
    obj/offset: max 0x0 face/size - obj/size / 2 + face/offset
    obj
]

18. 3020-How to create a bmp file from an image

How to create a bmp file from an image?

view center-face layout [

    x: box snow 201x201 effect reduce [
                                    'gradient 0x1 164.200.255
                                    'grid 8x8 0x0 0.0.0
    ]

    button "save" [save/bmp %grid.bmp to-image x]
] ;lay

19. 3021-Selections with list

How to get the selected items of a list?

; multi-selection
mydata: ["Red" "Green" "blue"]

view center-face layout [
    mylist: list 200x100 [
        across
        text 200 [
            either none = lv-temp: find mylist/picked to-integer rec-no/text
            [mylist/picked: append mylist/picked to-integer rec-no/text]
            [remove lv-temp]
            print mold mylist/picked
        ]
        rec-no: text 1
    ]
    with [picked: copy []]
    supply [
        face/text: either count > length? mydata [""][pick mydata count]
        rec-no/text: count
        either (find mylist/picked count) <> none 
            [face/color: brick]
            [face/color: none]
    ]
]
; mono-selection
mydata: ["Red" "Green" "blue"]

view center-face layout [
    mylist: list 200x100 [
        across
        text 200 [
            either mylist/picked = v-temp: to-integer rec-no/text
            [mylist/picked: 0]
            [mylist/picked: v-temp]

            either mylist/picked <> 0 [
                face/color: brick ][
                face/color: none
            ]
            show mylist
            print mold mylist/picked
        ]
        rec-no: text 1
    ]
    with [picked: to-integer 0]
    supply [
        face/text: either count > length? mydata [""][pick mydata count]
        rec-no/text: count
        either mylist/picked = count [
            face/color: brick ][
            face/color: none
        ]
    ]
]

20. 3022-Stylize/master

An example using stylize/master.

to-width: func [x] [
     75 + 8 * x - 8
]

stylize/master [
     ;    VID types
     lbl: lbl blue to-width 1
     field: field to-width 1
     date-field: field [
          if not empty? face/text [
               either none? attempt [to-date face/text] [
                    clear face/text
               ][
                    face/text: form to-date face/text
                    show face
               ]
          ]
     ]
     ;    Derived types
     lab-address: lbl "Address:"
     fld-address: field to-width 3
     lab-date:    lbl "Date:"
     fld-date:    date-field
     lab-code:    lbl "Code:"
     fld-code:    field
]

view center-face layout [
     across lab-address fld-address
     return lab-date    fld-date
            lab-code    fld-code
]

21. 3023-Text list with no wrap

QUESTION

Is there a way to not have the text list drop the last word on the line if it doesn't fit but instead just don't show the characters that don't fit?

view center-face layout [
        t: text-list "my really long entry is bigger than yours" 
]

ANSWER

view center-face layout [
        t: text-list "my really long entry is bigger than yours" do [
                t/iter/para/wrap?: no
        ]
]

Tip

Just type this code to display the text-list init function.

layout [text-list with [probe init]]

22. 3024-Usage of with in VID

Answers to a post of mine regarding 'with. Here is the test code:

draw-layout: [
 h2 "Draw buttons"

 style draw-button box 24x24 with [
  effect:  [draw [pen black fill-pen user-data circle 12x12 10]]
 ]

 across

 r-btn: draw-button user-data red    [ print "hey, I'm red"]
 b-btn: draw-button user-data blue   [ print "hey, I'm blue"]
 y-btn: draw-button user-data yellow [ print "hey, I'm yellow!"]
 g-btn: draw-button user-data green  [ print "hey, I'm green!"]
]

view center-face layout draw-layout

22.1. Answer from Brett

> Could someone tell me more about this "magic" with ?...

All REBOL/View faces are objects. VID and LAYOUT are used to create this object but using a simpler more powerful way to express how to create them.

So LAYOUT [ button ] will create an object for the button (it will also create another for the window but lets ignore that for the moment). When you use LAYOUT [button red] an object is created but this time with a colour of Red. The VID language and LAYOUT translate the "red" into an action of setting the face's colour facet to red.

WITH is part of the VID language that allows you to specify the facets using a normal REBOL object specification. So the object that is created has this specification applied to it.

For example, instead of LAYOUT [button red] you could write

layout [button with [color: red] ]

As you can see [button red] is easier, but the advantage of WITH is that you can create entirely new facets using it.

For example,

>> layout [btn: button with [my-special-facet: "Brett"]]
>> btn/my-special-facet
== "Brett"

> Why effect is now a set-word! ?

Vid styles are objects too. When you use

layout [style draw-button box 24x24]

You are creating another style object, one which is based on the box style. When Romano used WITH in creating a style he was using a normal REBOL object specification to change the facets (object fields) of the style. This is why EFFECT became a set-word.

> Why is it no more needed in "user-data red"?

The style that was created now has this EFFECT. Every face based on that style will have the same EFFECT by default. The EFFECT block refers to USER-DATA which is a built-in facet of every VID style. USER-DATA is a VID keyword and built-in facet. For example

>> layout [btn: button user-data "Brett"]
>> btn/user-data
== "Brett"

As you can see just like setting the colour we can set USER-DATA just as easily.

> I was asking myself the same questions, when Anton stabbed me in the back > with an even more puzzling code with a "little dialect using the words > facet". ... > As it seems to me, words is a face/facet used to define a face behaviour in > the form of a function. In this function, new is the object face, while args > is a block like [fill 255.0.0 [print "hey, I'm red"]]. The "next args" part > is a bit of a puzzle, because it cannot be removed or the face is not > displayed correctly.

Pretty close. Yes WORDS is a facet, but it is used during LAYOUT *only* not during the display of the face. It is a way that more keywords can be added to VID so that your custom styles can have their own specific VID keywords. So what Anton has done is to create a new keyword FILL that is valid for the DRAW-BUTTON style. When LAYOUT processes this specification [draw-button fill red ] it executes the WORDS of DRAW-BUTTON to process the FILL keyword.

> Its goal seems to return whatever is left to be processed to finish the face display.

Yes whatever is left needs to be given back so that LAYOUT can process other attributes and facets after the FILL (and its data).

This is an advanced technique. But as you can see it is very powerful. Using WITH to make custom facets and WORDS to add custom VID keywords you can create altogether new VID styles that are very easy to specify.

I hope this helps. Brett.

22.2. Answer from Romano

> Could someone tell me more about this "magic" with ? why is it no more > needed in "user-data red"? why effect is now a set-word! ?

All the magic is relative to object and binding of words. When you define an object starting from a previous object:

ob: make object! [a: 1]
make ob [a: 2]

you assign a new value (2) to the word 'a of the object: this can happen because the word 'a in the block is bound to the word 'a in the object before executing the block. The sequence of operations is:

1) duplicate object ob and its context 2) bind the block [a: 2] to the new context 3) evaluate the block [a: 2]

Now in 3) when you change the value of 'a in the block, you really change the value of 'a in the object.

The point is that words are not variable, they have not a value, they are alphanumeric pointers to context, which are "invisible" structure created by make object! (not only).

The 'with word of Vid is a shortcut for something like this, only 'ob is the style face and the block is the 'with block.

The 'effect word of Vid, instead, does not bind the block to the object context, only assign the block to the effect field.

Effect [draw [pen user-data]] is like:

new-face: make face []
new-face/effect: [draw [pen user-data]]

instead:

with [effect: [draw [pen user-data]]] is like

new-face: make face [effect: [draw [pen user-data]]]

only in the latter case the block is bound to the face object before executing.

Ciao Romano

23. 3025-[VID] How to reset guide?

How to reset guide?

QUESTION

>Hi, I have the following layout:

view layout [
       across
       a: txt "test1"
       guide b: txt "test2" return
       c: txt "test3" return
       d: txt "test4"
]

>And I want to be 'd in line with 'a. How do I get rid of the 'guide once >set? I just want to disable it until the next 'guide happens. Robert

ANSWER

I never actually use guide, but this seems to give you what you want...

view layout [
        across
        a: txt "test1"
        guide b: txt "test2" return
        c: txt "test3" return
      guide a/offset
        d: txt "test4" return
      e: txt "test5"
]

Hope that helps.

24. 3001-Clear-fields - how to improve it?

Clear-fields - how to improve it?

Hi All,

CLEAR-FIELDS is one of those really handy functions that annoys me. :\

It's very useful, but also problematic in that it only clears FIELD faces, not AREAs; much less CHECK, RADIO, etc. *and* it only works if a field contains a SERIES! value.

Admittedly, coming up with a completely general solution would probably add lots of code, but can it be made better without too much effort and added code? I think so, but I'm not sure how far to go, assuming we want to submit the improved version to RT for future inclusion.

Here's the standard version:

clear-fields: func [
    "Clear all text fields faces of a layout."
    panel [object!]
][
    if not all [in panel 'type panel/type = 'face] [exit]
    unfocus
    foreach face panel/pane [
        if all [series? face/text flag-face? face field] [
            clear face/text
            face/line-list: none
        ]
    ]
]

This one works for AREAs as well, and sets non-series values to NONE:

clear-fields: func [
    "Clear all text fields faces of a layout."
    panel [object!]
][
    if not all [in panel 'type panel/type = 'face] [exit]
    unfocus
    foreach face panel/pane [
        if any [flag-face? face field  flag-face? face area][
            either series? face/text [
                clear face/text
                face/line-list: none
            ][
                face/text: none
            ]
        ]
    ]
]

This one does the same as above, but tries to MAKE the type of value that's in the field. E.g. numeric fields would reset to 0:

clear-fields: func [
    "Clear all text fields faces of a layout."
    panel [object!]
][
    if not all [in panel 'type panel/type = 'face] [exit]
    unfocus
    foreach face panel/pane [
        if any [flag-face? face field  flag-face? face area][
            either series? face/text [
                clear face/text
                face/line-list: none
            ][
                face/text: attempt [make face/text none]
            ]
        ]
    ]
]

Beyond these simple kinds of changes, should we directly add support for CHECK, RADIO, etc. or is it better to adopt a more general approach, e.g. using a dialected block as a parameter, that you use to reset the display in your app? The latter approach makes it more effort to use, but potentially much more useful as well.

Any thoughts, or other implementations would be welcome.

-- Gregg

25. 3003-Button with on-off texts

How to change a button text depending on the on/off state?

ANSWER

view layout [
    b: button "Button"
    button "Change" [
        b/texts: ["Out" "In"]
        show b
    ]
]

26. 3010-How to get to a field variable by its string name?

How to get to a field variable by its string name?

; Here we have 4 fields 'fv1, 'fv2, 'fv3, 'fv4
; The idea is to get one by its number
; building the litteral name, like "fv1"

change-fv: func [
    /local i n s w f
][
    n: random 4
    ; build a word from the string "fv" + n
    w: to-word rejoin ["fv" n]

    ; get the global variable attached/bind the w
    f: get :w

    ; it works ! ! !
    f/text: "Changed"
    show f
] ;cf

fav: layout [
    style fv text 200 "text"

    fv1: fv "A"
    fv2: fv "B"
    fv3: fv "C"
    fv4: fv "D"

    btn-enter 60 "test" [change-fv]

] ; layout

view center-face fav

Document generated with Rebol.
Original code from Carl Sassenrat modified by pat665,
REBOL and the REBOL logo are trademarks of REBOL Technologies.