Rebol Talk Forum  |  Getting Started  |  Code Examples, Tips & Advice  |  Topic: Using REBOL/View Layouts
Pages: [1] Print
Author Topic: Using REBOL/View Layouts  (Read 2127 times)
CarlRead
Full Member
***
Offline Offline

Posts: 106


View Profile
Using REBOL/View Layouts
« on: April 02, 2005, 08:50:55 PM »

Opening a window with a nice GUI is a simple process with View, but new users may be tripped up when they wish to open more than one.  As an example, consider this little script...

Code:
rebol []

view/title layout [
   button "New Window" [
       view/new/title layout [
           box blue "Window 2"
       ] "Window 2"
   ]
   button "Quit" [unview/all]
] "Main"
(Note: The quickest way to run the examples here is just to copy and paste the code after the "rebol []" line into the View Console.  This gets around the hassle of having to save the code first before running it.)

With that, you can open a second window simply by clicking on the New Window button in the Main window.  There's a catch with this however, as if you move Window 2 from in front of the Main window and click again on the New Window button, a third window will appear, also called Window 2.  This may not be what you want!

Happily, there's an easy way around this - just create a permanant layout and then view/new that.  ie...

Code:
rebol []

win2: layout [
   box blue "Window 2"
]

view/title layout [
   button "New Window" [
       view/new/title win2 "Window 2"
   ]
   button "Quit" [unview/all]
] "Main"
Now when you open Window 2 you'll find you can't open any more versions of it.  This method also comes with an added bonus - if you close the window and then open it again, it'll open in the same place it was last on the screen, thus pleasing your users greatly.

That's an excellent method of window mangement for windows that are unique to your program.  There will be times though when you'll want to open any number of windows which are all much the same - such as ones displaying pictures in a graphics program for instance.  So, would a version of our first script be okay for that?  Let's see...

Code:
rebol []

view/title layout [
   button "New Window" [
       view/new/title layout [
           b: box blue "A Box"
           button "Change!" [
               b/color: random 255.255.255
               show b
           ]
       ] "A Box"
   ]
   button "Quit" [unview/all]
] "Main"
Run that and you'll find you can open any number windows with a box in, but if you click on their Change! buttons to give a box a random color you'll notice it's always the box in the most recent window you've opened that changes.  This is because the B word is global and so can only reference one box at a time - the one in the most recently opened window.

Once again there's a way around this problem (and in fact more than one), though it's not nearly as easy to solve as preventing multiple windows from opening.  How we'll do it is by using the VAR word faces in a layout contain, these being for the words (such as our B for box) that can be used as references in layouts.

A layout (which is just a standard REBOL object) has a block PANE which contains all the sub-faces that make up its layout, such as the boxes and buttons we've used so far in these examples.  This allows us to search a layout for a face referenced by a specific word and this is what the GET-PANE function in our next example does.

That's only half the problems solved though, as we still need to find the layout we're working with, (ie, the one the button we're actually clicking on is in), before we can call that function.  This happily is reasonably easy, the word FACE referencing the button's (or any other style's) face, and FACE/PARENT-FACE referencing it's layout.

With that solved, we can use GET IN face word (where word is 'text or 'color etc.) to access a value (such as B/COLOR) and SET IN face word value to change a value.  This is more long winded than just using B/TEXT or B/COLOR, but it allows you to use the same references in multiple windows which is a nice thing to be able to do.

And here it all is in use...

Code:
rebol []

get-pane: func [face [object!] word [word!]][
   foreach pane face/pane [if pane/var = word [return pane]]
   make error! rejoin ["Word '" word " not found in layout!"]
]

view/title layout [
   button "New Window" [
       view/new/title layout [
           b: box blue "A Box"
           button "Change!" [
               set in get-pane face/parent-face 'b 'color random 255.255.255
               show get-pane face/parent-face 'b
           ]
           button "Print Color" [
               print get in get-pane face/parent-face 'b 'color
           ]
       ] "A Box"
   ]
   button "Quit" [unview/all]
] "Main"
That could be simplified a bit further by writing specific functions to handle the SET, GET and SHOW bits - it's just probably best to do that on a script-by-script basis.

Comments and questions about this welcome.
Logged

- Carl Read
Brock
Guest


Email
Using REBOL/View Layouts
« Reply #1 on: April 03, 2005, 11:54:57 PM »

Thanks for the  nice article Carl.  A couple nuggets there.
Logged
Philippe
Newbie
*
Offline Offline

Posts: 34


View Profile WWW
Re: Using REBOL/View Layouts
« Reply #2 on: May 16, 2006, 03:56:03 AM »

Carl,

Are you Ok, if I translate in French your post for the Rebol Documentation Project ? (http://rebdocproj.org/)

Thx,

===Philippe
Logged

===Philippe
CarlRead
Full Member
***
Offline Offline

Posts: 106


View Profile
Re: Using REBOL/View Layouts
« Reply #3 on: May 16, 2006, 04:13:41 AM »

That's OK by me, Philippe.  Glad you think the post is worth it!
Logged

- Carl Read
Philippe
Newbie
*
Offline Offline

Posts: 34


View Profile WWW
Re: Using REBOL/View Layouts
« Reply #4 on: May 16, 2006, 04:53:19 AM »

Hi Carl,

You're welcome ;-))
The objective of the RDP project is to publish tutorials, samples, etc. around REBOL from beginner to experts. Your post is a good tutorial.
If you have other tutorials, we could make translation for French rebolers.


===Philippe
Logged

===Philippe
oyster
Newbie
*
Offline Offline

Posts: 6


View Profile
Re: Using REBOL/View Layouts
« Reply #5 on: November 26, 2006, 09:31:15 PM »

hello, everyone. I have serval questions on this code:
1. how to create a windows and let it be always-on-top
2. how to create a new window and let it be modal
3. when I close the main window by clicking the 'close window X-icon', the main window closes, but the new-created windows are still here. How to add call-back function to close all the windows or to forbide the 'close' icon on the main title-bar?
thanx
Logged
DideC
Newbie
*
Offline Offline

Posts: 23


View Profile
Re: Using REBOL/View Layouts
« Reply #6 on: November 28, 2006, 12:59:07 PM »

1. Always-on-top : you can't do it "system wide" ! I mean you can't set a Rebol window to stay on top of other non-rebol windows (like Words, notepad or anything else. The reason seems to be that it's not portable on different platforms. Maybe you can with DLL call to Win API, but it's another story.

2. To use modal windows, you need to open them with 'inform or 'show-popup rather than with 'view/new.

3. If you open new windows as modal (see 2.) then close button will be inactive in the parent window.
If you want to manage "close" of one window to close all opened windows, you need to manage it with a global event function. See 'insert-event-func and 'remove-event-func function and see page like this one http://www.rebolforces.com/view-faq.html#sect3.3. (or google ;-)
Logged
oyster
Newbie
*
Offline Offline

Posts: 6


View Profile
Re: Using REBOL/View Layouts
« Reply #7 on: November 29, 2006, 05:29:10 AM »

thanx, it works
Did I miss something? where can I get a completed VID manual, or there is not such a thing?
And one monior bug: I can't active the widget on parent window if I open a new modal window, that is right. But I can still click the parent widow and change its title bar to blue, which means an active window on my win2k, and at the same time, the modal child window title bar becomes gray which means an inactive window
Logged
DideC
Newbie
*
Offline Offline

Posts: 23


View Profile
Re: Using REBOL/View Layouts
« Reply #8 on: December 22, 2006, 03:50:49 PM »

No complete manual for VID, AFAIK !
There is other docs than RT one arround : google it (things like "REBOL window", "Rebol inform" ...)

Most of what I learned in View/VID was learned by trying script in the library and, when something they do was of interest to me, looking at their source code to see how it was done.

About Window activation, thats true!
The reason is that Rebol managed modale windows on it's own due to mutiplatform issues.
So it's not as modale as you would expect.

In fact, Windows usually make a modale window blinked (and bip) when you clicked in it's parent (inactivated) window. So in some way, the parent window reactivate the modale window.

Rebol just not do it!
Logged
Anton
Jr. Member
**
Offline Offline

Posts: 65

Rebol veteran


View Profile WWW
Re: Using REBOL/View Layouts
« Reply #9 on: January 02, 2007, 06:04:19 AM »

Using CONTEXT, you can avoid the necessity of functions like GET-PANE.
Here is my reworking of Carl Read's 4th example:

Code:
rebol []

view/new/title window: layout [
button "New Window" [

context [

; Put words ("variables") used in the LAYOUT spec here.
; CONTEXT first scans for set-words in the top level block (here)
; and adds them to the new context it is creating. Then it binds
; the whole block (recursing into subblocks) to the new context,
; so all those words used in the LAYOUT spec will refer to
; these ones:

my-box: none

view/new/title/offset window: layout [

; Here we are in the LAYOUT spec block

my-box: box blue "A Box"
button "Change!" [
my-box/color: random 255.255.255
show window
]
button "Print Color" [
print my-box/color
]

] "A Box" (200x200 + random 400x300)
]
]
button "Quit" [unview/all]
] "Main"

; Modify the window FEEL so pressing the standard window close button
; will unview all our child windows.
; (Note: VIEW sets the window FEEL so we must modify it after that
; and preferably before waiting for events.)

window/feel: make window/feel [ ; clone the FEEL
insert second :detect bind [ ; modify the DETECT function
if event/type = 'close [
unview/all
]
] first last second :detect
]

do-events ; start waiting for events

It has the benefit that words you set in the context won't overwrite global words and therefore can't interfere with anything outside your code, but you must strictly maintain the words that you wish to remain local to the context.
Logged
Pages: [1] Print 
Rebol Talk Forum  |  Getting Started  |  Code Examples, Tips & Advice  |  Topic: Using REBOL/View Layouts
Jump to:  

  
Quick Search...

Advanced search
  
Welcome, Guest. Please login or register.
Did you miss your activation email?
May 17, 2008, 06:05:59 PM
Username: Password: Session Length:
  

News: 01-09-08

Alpha version of REBOL 3 has been released!


  
2169 Posts in 562 Topics by 1224 Members
Latest Member: thyptoste

  Rebol Talk Forum | Powered by SMF 1.0.9.
© 2001-2005, Lewis Media. All Rights Reserved.

RT design by Defiant Pc