用 Red 语言创建 gui 对象

Creating gui objects in Red language

是否可以使用 make 命令在 Red/Rebol 中创建 gui object。我试过以下:

view [
    do [guiobj: make object! [
             t: text "text"
             f: field "fld"
             b: button "button" ] ; end make object

        obj1: make guiobj
        obj2: make guiobj ]  ; end do

    below
    obj1  
    obj2 ]  ; end view

但我收到以下错误:

*** Script Error: field has no value
*** Where: f
*** Stack: view layout do-safe 
*** Script Error: VID - invalid syntax at: [obj1 obj2]
*** Where: do
*** Stack: view layout cause-error 

我知道 compose 可以使用,但是上面的代码可以使用 makeobject 命令来工作吗?

根据the documentation脸object是脸的克隆!模板 object.

可以在不使用 VID 的情况下构建 UI——了解这将帮助您理解如何操作 layout(和 view)的输出。您从头开始构建东西所失去的是 VID 提供的布局功能,但我们可以从两个方面获得最佳效果。让我们开始吧:

Window 无视频

首先我们需要一个地方来放置我们所有的元素:

our-window: make face! [
    type: 'window
    text: "Our Window"
    size: 500x500
]

现在让我们把一些东西放在那里:

our-window/pane: reduce [
    make face! [
        type: 'text
        offset: 20x20
        size: 160x28
        text: "Text"
    ]
    make face! [
        type: 'field
        offset: 200x20
        size: 160x24
        text: "Field"
    ]
    make face! [
        type: 'button
        offset: 380x20
        size: 160x28
        text: "Button"
    ]
]

现在我们可以看看它了:

view our-window

请注意 our-window/pane 中的 object 与本例中生成的 object 类似 kind-of:

our-vid-window: layout [
    text 160 "Text"
    field 160 "Field"
    button 160 "Button"
]

正如我所说,使用这种方法,您必须自己管理大小和偏移量。我们可以做的是生成我们的行,把那些面 objects 附加到我们的 window.

从 VID 窃取生成的面孔

实际上我们可以用 layout 创建这些 object 并将它们放入 our-window:

make-row: func [/local row face kid][
    row: layout copy/deep [ ; copy so the strings are unique
        text 160 "Text"
        field 160 "Field"
        button 160 "Button"
    ]

    ...
]

使用 中的技术,您甚至可以将全局词应用于这些面孔中的每一个,并且仍然有效。

在我们这样做之前,我们将检查 our-window 是否有任何 children 并调整每个新面孔的偏移量以显示在最后一个 child 下方:

if kid: last our-window/pane [
    ...

    foreach face row/pane [
        face/offset/y: face/offset/y + kid/offset/y + kid/size/y
    ]
]

为了获得正确的 window 大小,我们还将调整生成的行大小并应用:

row/size/y: row/size/y + kid/offset/y + kid/size/y

...

our-window/size: row/size

然后是有趣的部分:

append our-window/pane row/pane

将所有这些结合在一起,我们可以生成大小合适的 window。

our-window: layout [
    button "Add a Row" [make-row]
]

make-row: func [/local row face kid][
    row: layout copy/deep [
        text 160 "Text"
        field 160 "Field"
        button 160 "Button"
    ]

    if kid: last our-window/pane [
        row/size/y: row/size/y + kid/offset/y + kid/size/y

        foreach face row/pane [
            face/offset/y: face/offset/y + kid/offset/y + kid/size/y
        ]
    ]

    our-window/size: row/size

    append our-window/pane row/pane
]

make-row
make-row
make-row

view our-window