[REBOL] Re: draw has no access to the current face
From: brett:codeconscious at: 1-Oct-2002 9:19
regarding my last post on this thread - Oops wrong button....
Looking at this 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
> Quoting Romano the with "magically binds the effect block words to the
face
> objects words".
>
> I have some questions about this:
>
> Could someone tell me more about this "magic" with ?
...
> why effect is now a set-word! ?
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"
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.