[REBOL] Re: Block or Object
From: brett:codeconscious at: 27-Oct-2003 0:39
Hi Patrick,
I got a little carried away with some examples :^)
Anyway...
> How can the same thing be an object or a block ? See an example:
...
> foreach face lay/pane [
> print [face/style type? face]
At this point your example prints:
text object
button object
This is because lay/pane is a block containing two faces - faces are always
of type Object!.
> ; here a block
> f2: find lay/pane f
> print type? f2
lay/pane is a block, find returns a block in this case e.g
>> find [x y z] 'y
== [y z]
> Is this normal?
Absolutely. Your example misses it, but you may have seen that Pane can an
object or a block. 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.
> 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.
>
> Is this possible?
Yes. But without a variable, you still 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.
; -------------------------------------------------------------------
; Example 1
; -------------------------------------------------------------------
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:
; -------------------------------------------------------------------
; Example 2
; -------------------------------------------------------------------
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 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.
; -------------------------------------------------------------------
; Example 3
; -------------------------------------------------------------------
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.
; -------------------------------------------------------------------
; Example 4
; -------------------------------------------------------------------
; 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
; ...................................................................
Brett.