I have following simple code for a small panel:
view [
t: text "label"
f: field
button "Click here" [t/text: f/text] ]
But I have to make 2 of them and put them on one window. I want to create single object class and make 2 objects out of it. I see that objects can be created as follows:
obj: object [
view [
t: text "label"
f: field
button "Click here" [t/text: f/text] ] ]
view [
obj
obj ]
But I get following error:
*** Script Error: VID - invalid syntax at: [obj obj]
*** Where: do
*** Stack: view layout cause-error
How can this be done? Thanks for your help.
Edit: I tried with do
but could manage only with does
:
myview: object [
show: does [view[
below
t: text "1st time"
f: field "Enter value"
button "Click here" [f/text "clicked"]
area] ] ]
myview/show
print "READY TO SHOW 2nd OBJECT: "
myview2: copy myview
myview2/show
I want to create single object class and make 2 objects out of it.
There is no object class system in Red, so you should really try first to grasp the basic Red concepts before trying more complex GUI constructs. Red is a very flexible data-oriented language, so you can use that to your advantage by, for example, building parametrized block templates, and assembling them to form a correct block of VID code. Here is an example:
make-row: func [label [string!] but-label [string!]][
compose [
t: text (label)
f: field
b: button (but-label) [face/extra/1/text: face/extra/2/text]
do [b/extra: reduce [t f]]
]
]
view compose [
(make-row "label" "Click") return
(make-row "label2" "Click2")
]
Understanding the face tree (analog to the HTML DOM, just way simpler), is an important part of mastering Red's GUI system. As there is no much documentation yet (you can start with http://docs.red-lang.org), you are welcome to ask live questions on red/help Gitter room.
To work with objects instead of in the VID dialect, replace view
with layout
:
lay: layout [
t: text "label"
f: field
button "Click here" [t/text: f/text]
]
view lay
You can then inspect it like any other object: ?? lay
.
For example, to access the contents of lay
with pane
:
>> ? lay/pane/1
However, a more useful function may be dump-face
:
>> dump-face lay
Type: window Style: none Offset: 833x548 Size: 270x45 Text: "Red: untitled"
Type: text Style: text Offset: 10x10 Size: 80x24 Text: "label"
Type: field Style: field Offset: 100x10 Size: 80x24 Text: none
Type: button Style: button Offset: 190x9 Size: 70x25 Text: "Click here"
== make object! [
type: 'window
offset: 833x548
...
panel
s are useful to group objects together:
>> dump-face blay: layout [p: panel button "hi"]
Type: window Style: none Offset: none Size: 292x220 Text: none
Type: panel Style: panel Offset: 10x10 Size: 200x200 Text: none
Type: button Style: button Offset: 220x9 Size: 62x25 Text: "hi"
== make object! [
type: 'window
offset: none
...
But it's probably easier to use the VID dialect with compose
to build up stuff first.
See also this question
I guess what you are looking for are styles and not objects in order to create a layout. Until now there is no official stylize function in Red. But you can create your layout dynamically like this
view repeat i 2 [
tname: to-word rejoin ['t i]
fname: to-word rejoin ['f i]
append v: [] compose/deep [
(to-set-word tname) text "label"
(to-set-word fname) field
button "click here" [
(to-set-path compose [(tname) text])
(to-path compose [(fname) text])
]
]
]
You can just append a predefined block of words many times to the block you want to view and you will get repeated elements.
txt_btn: [
t: text "label"
f: field
button "Click here" [t/text: f/text]
]
view append append [] txt_btn txt_btn
The problem arises as you refer to a named element in your block. But a word can not point to more than one element of the repeated elements, therefore the usage of compose in the complete solution in order to create unique names.
Maybe there is a bug in Red because I thought compose/deep
would also do parentheses deep inside and not need more compose –