Version 1.0.0 Copyright (C) 2002-2003 Romano Paolo Tenca
Table of Contents
1. Introduction
2. Use
3. The VID dialect
3.1. Facets
3.1.1. RESIZE
3.1.2. ALONE
3.1.3. USER DEFINED GROUPS
3.1.4. ANCHOR
3.1.5. CODE
3.2. Defaults
4. Resize-dump
5. How does auto-resize work?
6. Adding and removing faces
7. Hints
8. Do-resize
9. Technical Notes
10. View Dialect
10.1. Layout-resize
11. License
12. Aknowledgements
Resize-vid makes creating resizable windows easy; with automatic resizing of the faces they contain. This document will outline its use, but looking at the examples included with resize-vid will help to answer a lot of the "How do I...?" questions that always come up when you are learning to use a new tool or library.It consists of a View dialect and VID extensions (auto-resize system).
The dialect is intended to be used by style programmers; that is, people creating new VID styles. The VID extensions are used in Layout spec blocks, used by anybody creating a GUI with VID.
The code requires Rebol View (1.2.1 or later) or Rebol Link (IOS).
To use the auto-resize system, you must do two things:1) DO the resize-vid.r script, or include its code directly in your script.
2) Call the AUTO-RESIZE function, passing the face you want it to act on. Generally, the face will be the result of a call to the standard LAYOUT function.do %resize-vid.r
view/options auto-resize layout [field "try"] 'resize
The following words can be used as word facets (like feel, edge, font-size...), when defining a face in a layout block; many of these words will be used as standard face flags. They affect the default resize behaviour.
3.1.1. RESIZE
Change the size of the face (mutually exclusive)
resize-xy (default) resize the face in both axes resize-x resize only in the x axis resize-y resize only in the y axis resize-none do not resize
3.1.2. ALONE
Do not insert this face in any group (by default any face will be put in a group)
resize-alone do not compose groups with this face
3.1.3. USER DEFINED GROUPS
Force a group of faces to be resized like a group (mutually exclusive)
resize-next force a group with the following face (can be concatenated) resize-of 'name insert this face in the group called 'name
3.1.4. ANCHOR
Change the offset of a face. Cannot be used with resize-next and resize-of. An anchored face is like a resize-alone face.
anchor-x target corner anchor the x offset anchor-y target corner anchor the y offset anchor-xy target corner anchor both the x and y offset
target - can be the lit-word name of a face or the keyword 'panel to refer to the containing panelExamples:corner - must be a pair which refers to one of corners of target:
left-top 0x0 1x0 right-top left-bottom 0x1 1x1 right-bottom
field anchor-x 'panel 1x1 ; x offset of field will follow ; the right-bottom corner of panelfield anchor-xy 'but 1x0 ; x and y offset of field will follow ; the right-top corner of the 'but face3.1.5. CODE
Execute some code after the resize operation
resize-do execute the block
after the resize, execute this block of code as if it were called like this:Examples:
delta is the change in size, delta-offset is the change of offset, pay attention can be called many times in a resize session with different args (for size, for offset...)func [face delta delta-offset] <block>
text "Resize the font" resize-do [ if delta <> 0x0 [ face/font/size: face/size/y * 0.5 ] ]
resize-xy is the default for all faces.Many styles have a custom default flag that overrides the general default.
RESIZE FLAG STYLES resize-xy (default) face image box icon area panel list text-list anim resize-alone backdrop backtile sensor key resize-none arrow sensor key button toggle check radio btn btn-cancel btn-help btn-enter tog led resize-x field choice info text vtext txt body banner vh1 vh2 vh3 vh4 label lbl title rotary h1 h2 h3 h4 h5 tt code drop-down resize-y logo-bar (Link) Some styles have custom code to handle the resize:
- Slider and progress make a check on horizontal or vertical shape.
- Text-list adapts the dragger size to the new size of text-list.
- List calls auto-resize on the row layout and resizes it horizontally.
The file resize-dump.r contains a function (resize-dump) which prints on the console the resize-layout tree with all flags for debugging purposes. Example:
do %resize-vid.r do %resize-dump.r view resize-dump auto-resize layout [ across L1: label 50 "Label 1" A1: area 50x50 "Area 1" return L2: label 50 "Label 2" A2: area 50x50 "Area 2" ]
The auto-resize engine tries to find groups of vertical and horizontal faces; i.e. columns and rows. When a face is in a group and it is resized, the offset of the other faces in the same group will be changed so that they are still aligned visually.Important: vertical groups (columns) have priority over horizontal (rows).
Once a layout is created, it doesn't store the orientation facets (ACROSS and BELOW) that were used to create it, so resize-vid has to figure things out for itself, with help from you. Here's an example:
across L1: label 50 "Label 1" A1: area 50x50 "Area 1" return L2: label 50 "Label 2" A2: area 50x50 "Area 2"What do you see? A vertical group and, inside, two horizontal groups of faces (a column with two rows)?
Or a horizontal group and, inside, two vertical groups of faces (a row with two columns)?a) | L1 A1 | | ----- | | L2 A2 |
Auto-resize sees the it the second way.b) ------- L1 | A1 L2 | A2 -------As I said, vertical groups (columns) have precedence, so b) is the option auto-resize "sees". This is obviously important because the resize behaviour depends on it. The two labels (L1 and L2) do not resize vertically, so in the b) case, the label (L2) will not be pushed down by the upper label (L1); it will be always at the same position.
Instead, the area faces (A1 A2) will extend vertically and the second one (A2) will be pushed down by the upper area (A1). The result is that the label (L2) will lose its horizontal alignment with the area (A2).
How can you tell auto-resize to give precedence to horizontal groups? You need to use the 'resize-next or the 'resize-of facets to create user defined groups of faces to tell auto-resize how to group things.
The simpler of the two is 'resize-next, which means:
"Create a group between the current face and the following one in the layout definition"So the code:
will result in the a) case:auto-resize layout [ across L1: label "Name" resize-x RESIZE-NEXT A1: area "Area 1" resize-xy return L2: label "Adress" resize-x RESIZE-NEXT A2: area "Area 2" resize-xy return ]
a) L1 A1 ----- L2 A2The area (A1) expands its y axis and BOTH (L2) and (A2) are pushed down the same amount of space, because they are in the same horizontal group (row). Thus (L2) and (b2) will still line up with each other.
The second facet you can use is 'resize-of. This is useful when the faces you want to group are not consecutive in the layout definition:
RESIZE-OF must be followed by a lit-word! atttribute that is used as the group identifier; it is used like the 'of facet for radio buttons.auto-resize layout [ L1: label 100x20 "Label 1" resize-x RESIZE-OF 'G1 L2: label 100x20 "Label 2" resize-x RESIZE-OF 'G2 return A1: area 100x20 "Area 1" resize-xy RESIZE-OF 'G1 A2: area 100x20 "Area 2" resize-xy RESIZE-OF 'G2 ]In both examples only the first resize-next and the first resize-of are really useful, auto-resize can figure, by itself, that the other faces form a horizontal group.
'resize-next and 'resize-of are not limited to two faces, nor are they limited to horizontal groups. Any combination of faces which form complex nested groups can be coerced with 'resize-next or 'resize-of (this can, however, lead to effects that are hard to visualize, so it's nice that you can run things so easily to see the results :-).
If you add or remove a face from a layout auto-resize is acting on, you must call auto-resize again to update the internal representation of the layout. You can call auto-resize with the window, panel, or face from which you have removed a face:
Hint: when you recall auto-resize, all the resize layout will be rebuilt, so you must be sure that the window is in a consistent state: for example if the window is too small, some faces may have a size of 0 (or a negative value) and auto-resize will be confused by this. Select a good min-size with View/options (under new View betas and Link), and call auto-resize on the window after adding or removing faces.main: layout [ f: field "try" button "remove" [ remove find main f auto-resize main show main ] ] auto-resize main view/options main 'resize
To resize a complex layout, try auto-resize without any resize flags and see what happens. Then:1) Add Resize-none, Resize-x, Resize-y, Resize-xy to the faces which do not suit your needs.
2) If a face overlaps other faces in the same pane, try adding Resize-alone ('backdrop 'backtile 'sensor and 'key styles have it by default)
3) If two consecutives faces must be kept together, add Resize-next to the first of the two.
4) If a face must always be at the same distance from the lower-right corner of a panel/window, add Anchor-xy 'panel 1x1 to it.
5) If a face, called for example 'but, must be always at the same distance from the lower-right corner of another face, and for some reason the auto-resize system cannot figure it out by itself, add Anchor-xy 'ar 1x1 to the 'but face:
the button will then follow the lower-right corner of the area.ar: area 100x50 "Hello" pad 50x0 but: button "OK" anchor-x 'ar 1x1Hint: Anchors are useful in some cases but often a little set of Resize-next facets can do all the work. So use it only as as last resort.
6) If you want to execute some code after the resize of a face, add Resize-do. This can be useful for slider and scroller faces to sync them visually them with another face like a list:
Hint: Normal faces are resized in the order given by their y and x offset, so in this case, first the list and then the slider. Anchored and Resize-alone faces are resized without ANY ORDER.across lst: list 54x100 data [["1"] ["2"]][text 50x15] sld: sld 16x100 resize-do [ print "Time to do some calculation and then call sld/redrag" ]7) To help see how faces are resized, set the background color of some faces to a visible color.
8) Use resize-dump to understand the layout resize tree.
9) Ask if you have problems, but with a working example :-)
Sometimes this can be useful, to activate the resize manually, for example to adapt the layout to user preferences before displaying it. This can be done calling do-resize. The template is:
USAGE: DO-RESIZE face size offset /nosizeDESCRIPTION: Execute the resize DO-RESIZE is a function value.ARGUMENTS: face -- "Face to resize" (Type: object) size -- "Size to add" (Type: pair number) offset -- "Offset to add" (Type: pair number)where size and offset are the values to add to the face's size and offset.REFINEMENTS: /nosize -- The size of face is already setExample:
You can also change the size of the face and then call do-resize with /nosize:ly: auto-resize layout [area 100x100] do-resize ly 50x25 0
Hint: If the face is a window already displayed by View/options 'resize, changing the window size forces a standard View resize event which calls the auto-resize event handler. This can lead to some side effects - like recursive resizing calls. It is safe to use do-resize on a window face that is not displayed.ly: auto-resize layout [area 100x100] ly/size: ly/size + 50x25 do-resize/nosize ly 0 0
All the functions of the resize system are stored in an object called ctx-resize.The resize system adds an event-func to the screen to handle the resize events.
Parameters used by the resize code for a single face are stored in a Rebol object (prototype: ctx-resize/resize-ob).
To get the object relative to a face, you must call ctx-resize/get-rd with the face parameter:
This object is stored as the value of the flag word 'resize-d, to avoid adding a new field to the standard face object.ly: auto-resize layout [ar: area 100x100] probe ctx-resize/get-rd arResize-vid supports the standard facet 'resize in styles: if defined, it will be called to execute the resize operations.
Undocumented.
This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. This notice may not be removed or altered. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
Thanks to Petr Krenzelok for his deep beta testing and all his support.Thanks to Gregg Irwin for his deep revision of this doc.
I must also thank all the people on the IOS Developer server for the useful discussions in the Vid Group.
Enjoy!
Romano Paolo Tenca
Email me for bugs or requests for feature
Web site with the latest version