Home   Archive   Permalink



VID - create runtime variables

I compose a layout at runtime. When I attempt to add a variable, I get:
    
** Script Error: grid5 word has no context
** Where: forever
** Near: new/var: bind to-word :var :var
    
b: 5
block-middle: to-block rejoin [ "grid" (b) ": text "]
append block-middle ["Test"]
    
probe block-middle ; [grid5: text "Test"]
    
view/new layout block-middle
    
Is there a solution besides recreating the entire block to update it?

posted by:   VIDpuzzle     9-Jan-2019/7:35:21-8:00



The problem here is that when TO-BLOCK is used to turn a string into values, the words contained within are unbound. This behaviour differs from LOAD (or LOAD/ALL which is close to equivalent in Rebol 2) which binds words to the 'global' context, as with TO-*-WORD functions:
    
b: 5
    
view/new layout probe collect [
     keep to set-word! rejoin ["grid" b]
     keep 'text
     keep "Test"
]
    
; do-events

posted by:   Chris     9-Jan-2019/10:12:05-8:00



Just to note that with this type of loose layout, you may be better off referring to generated faces by their position relative to their parent. For example:
    
parent: layout collect [
     keep [
         across
         button "Summarize" [
             probe collect [
                 ; use 'next here to skip this button
                 foreach face next parent/pane [
                     keep get-face face
                 ]
             ]
         ]
         return
     ]
     loop 5 [
         loop 3 [
             keep reduce ['field copy "" 200]
         ]
         keep 'return
     ]
]

posted by:   Chris     9-Jan-2019/10:55:29-8:00



This is the above with a PANEL in place of scouring the window face:
    
    
view layout [
     button "Summarize" [
         probe new-line/all/skip collect [
             foreach face parent/pane [
                 keep get-face face
             ]
         ] true 3
     ]
     parent: panel collect [
         keep [origin 0 space 0 across]
         loop 5 [
             loop 3 [
                 keep reduce ['field copy "" 200]
             ]
             keep 'return
         ]
     ]
]

posted by:   Chris     9-Jan-2019/12:16:27-8:00



Thanks, so helpful!
    
This tip makes for a bright day.
    
I can touch the beauty of Rebol.
    
Thanks to the handful of people who keep R2 alive.

posted by:   VIDpuzzle     9-Jan-2019/12:35:39-8:00



I'll need to ponder over your code.
    
I intend to emulate a listbox for which each line contains several colored columns and several variable length colored text.
    
I want to update one line or even one text chunk at a time.
    
Thanks for the sample code!
    
    


posted by:   VIDpuzzle     9-Jan-2019/12:54:06-8:00



Thanks for the idea of cycling through the faces.
    
When I try
    
button "Summarize" [
                 foreach face block2 [
                     if set-word? face
                        [
                        ? face
                        set-face face "Text-change"
                        ]
                 ]
             ]
]
    
I get
    
FACE is a set-word of value: grid1:
** Script Error: in expected object argument of type: object port
** Where: set-face
** Near: if all [
     access: get in face 'access
     in access 'set-face*
] [
     access/set-face* face value
]
if
    
    
Although
    
set-face face "Text"
    
works from the CLI

posted by:   VIDpuzzle     19-Jan-2019/17:10:12-8:00



It's not clear here what BLOCK2 is. Do you have a broader example that reproduces this error?

posted by:   Chris     26-Jan-2019/16:05:09-8:00



I amended your example. I had to remove the collect structure as new-line was conflicting with the increment i.
    
This solution works for everything but for button "Update 7" where I attempt a
    
set in pick (pick parent/pane 7 'font) 'color red
    
Is there a way I can set font/color when accessing through pick?
    
Is there also a way to select a face and then write generic code such as
    
select pick parent/pane n
face/font/color: red
    
Thanks
    
    
i: 0
    
view layout [
     across
     button "Summarize" [
        
             foreach face parent/pane [
                 set-face face i: i + 1
                 ; new-line/all/skip
             ]
         ]
        
     button "Update 5" [set-face pick parent/pane 5 100]
     button "Update 6" [set in pick parent/pane 6 'color red
         show pick parent/pane 6
         ]
     button "Update 7" [
     set in pick (pick parent/pane 7 'font) 'color red
         ? parent/pane/7/font
         show pick parent/pane 7
         ]
     button "Halt" [halt]
     button "Quit" [quit]
        
        
     below
     parent: panel collect [
         keep [origin 0 space 0 across]
         loop 5 [
             loop 3 [
                 keep reduce ['text 200]
             ]
             keep 'return
         ]
     ]
]

posted by:   VIDpuzzle     5-Feb-2019/22:30:38-8:00



> Is there also a way to select a face and then write generic code
    
You could just set it to a word:
    
     button "Update 7" [
         face: pick parent/pane 7
         set-font face color red
         show face
     ]
    
(Note here, though, that the action block of a button is transformed into a function by VID that is triggered when that button is clicked with that button being passed as the FACE argument)
    
Alternatively, you could work within the context of the target face object itself:
    
     button "Update 7" [
         do bind [
             font/color: red
             show self
         ] pick parent/pane 7
     ]


posted by:   Chris     6-Feb-2019/12:54:44-8:00