Alventis Designer gives you all the tools you may need to produce InfoViews that are not merely functional, but also exceptionally well laid out. In this chapter, we'll learn what these tools are and how to use them.
In Alventis, almost all essential forms are resizable. InfoViews are no exception. It is therefore very important to understand what happens to the form's contents when it gets resized. But first, we'll have to learn about Containers.
We will be saying about a Container that it is parent to the items it contains, which we will refer to as its children.
Why all this fuss about Containers? Well, for starters, because all items exist in their parent item and whatever layout-related behavior they may have is relative to their parent.
Whenever you are resizing a Container (you personally will be resizing the InfoView, but it may be resizing some child Container within it), there are two issues to consider:
A. How the Container is reacting to its contents
B. How the Container's child items are reacting
B. The possible reactions of the Container's child items to their parent's resizing vary between very simple and rather involved:
Anchors are the cornerstone of Layout, so we'll have to thoroughly familiarize ourselves with what they are and how they work. It's actually quite simple.
This essentially concludes our tests, but there remains one setup we haven't tried, so let's do it for the sake of completeness. Turn both the Left and Right Anchors Off. Did you guess what the Edit Box would do? It now seems to make a great effort to not maintain its distance on either side by moving proportionally to its parent's width. It looks rather neat but the only meaningful use we have ever found for this behavior is centering an item within its parent, which is not something you are likely to use very often.
Top/Bottom Anchors work similarly to their Left/Right counterparts – but in the vertical direction.
Now that you have seen Anchors in action, you can hopefully appreciate their importance and power. You are not likely to ever create a nicely resizable InfoView without adjusting at least some Anchors.
The correct solution to this problem... there is none. At least not without resorting to using a few more "intermediate" Containers, which is what we are going to examine shortly.
Anchor Mode. Properly setting up the items' Anchors is so important that Designer offers you an innovative method of inspecting and setting them. The basic idea is this: you temporarily put the InfoView into a special Anchor Mode that helps you adjust Anchors, you perform whatever adjustments may be necessary, and return to the normal Design Mode by deactivating the Anchor Mode.
Proportional Panels. A Panel is a Container item. As such, it can hold other items inside. Any items. A Panel can have a border – and by default it does have a thin 3D sunken one. We'll learn to adjust its appearance later. What interests us here is the Panel's layout-related behavior.
Remember the 3rd possible kind of reaction of a Container's child item to its parent's resizing:
Panels possess the unique ability to do precisely that.
By default, Panels behave (layout-wise) just like other items. They too have Anchors, and they act in accordance with how they are set up. But one flick of a switch – and all this changes. The "switch" is appropriately called Proportionality, and there are two independent switches: one for the horizontal and one for the vertical direction .
Proportionality / H, when enabled, makes the Panel resize itself proportionally to its parent Container (sorry to keep repeating ourselves) in the horizontal direction.
We should note that Anchors and Proportionality are mutually-exclusive: you can only use one or the other, but never both (which wouldn't make much sense anyway).
Why does it work now? Let's see... Each Panel maintains its size and position proportional to that of its parent (independently from one another: they know nothing about each other and the fact that they are touching edges is purely incidental). The left Panel will therefore always occupy the left half of the form, and the right one – the right half. Each Edit Box is anchored to its parent, which is now its respective Panel. So, each Edit Box will be maintaining its distance to both edges of the Panel, which corresponds to the left edge of the form (because that's where the left edge of the left Panel happens to be) and its middle (because the right edge of the left Panel makes an effort to stay there).
You can also think of it this way if you prefer: by using the Panels the way we did, we have split the whole problem in two. Each panel behaves independently from the other, so all we care about now is that one Edit Box behaves properly in one Panel. Which is real easy. Now repeat that twice – for both Panels, and we're done.
To generalize this: properly set up Proportional Panels split their Container in independent pieces, so you get a much better chance to make each individual piece work the way you want, which ends up making the whole Container work.
Some layout tasks may require just a few Proportional Panels on the form. Other, more sophisticated ones, may benefit from multi-level Panel-in-a-Panel-in-a-Panel setups. No matter how complex it gets though, the basic principle is always the same, and we've just seen it "at work".
Split Panels. A Split Panel is a Panel with a Splitter that divides it into two Sub-Panels.
You can adjust the position of the Splitter with the mouse simply by dragging it wherever you want. Technically, doing so resizes the two Sub-Panels according to the Splitter's position.
The Splitter is a RotoSplitter of course, so you can rotate it 90 degrees at any moment by Shift-double-clicking it or by clicking the little button at its right/bottom end.
Selecting Sub-Panels is no different than selecting any other item: just click them. Not so with the Split Panel itself. Since it is completely covered by the Sub-Panels, there's no place to click. One solution is to use the keyboard. The Tab and/or Arrow keys could do the job. An even better way is to select one of the Sub-Panels and hit Escape. As you might recall, Escape always attempts to select the parent Container of the currently selected item, so it will select the Split Panel. That's all very nice if all we want is to select the Split Panel, but it doesn't help much if we want to move it somewhere by dragging it with the mouse: the moment we try to click it, one of the Sub-Panels get selected. The solution is to Alt-click or Alt-drag it. Alt-clicking either Sub-Panel selects the Split Panel. Likewise, Alt-dragging will drag the entire Split Panel.
Page Control. The last of the Containers.
Placing a Page Control on an InfoView creates a default Page Control with two Tab Sheets. Manipulation of Tab Sheets is very similar to how you work with, e.g., a Radio Group: double-click the Page Control to display a mini-grid of Tab Sheets.
As far as selection goes, there are no surprises here. You can select the entire Page Control by clicking on the row of tabs at the top. You can activate individual Tab Sheets by simply clicking on the tabs – exactly as you would do in any Page Control. You can select a Tab Sheet by clicking it.
Tab Sheets always occupy the full area of the Page Control allotted to them, so you can't resize or move them. The Page Control itself can be moved/sized in the usual ways and you can set its Anchors.
Alignment. There's one more important weapon in our Layout arsenal, and it's called Alignment. The default setting for all items is "None" , i.e., no particular Alignment. This means the item can reside wherever we place it within its parent. If we take a Panel and use it for our examples, and set its Alignment to Top, the following happens: the Panel "jumps" to the top of its parent Container (we can assume it's the InfoView form for the sake of simplicity), and gets "glued" to its top, left, and right edges. Only the bottom edge is "free", so we can resize the Panel by dragging the bottom grab handle up/down.
Alignment Left, Right, and Bottom work in a similar fashion: the Panel "sticks" to the specified side of its Container.
The only remaining type of Alignment is Client. You can also toggle the Alignment between None and Client using the Toggle Client Alignment button . What it does is make the item (Panel or whatever) fill the entire client area (i.e., available/usable area) of its parent Container. The so-aligned item "sticks" to all sides of its parent. What good is that? Let's take a look at some examples.
Here's another, even simpler, example of when you might want to use Alignment. A Page Control by itself does not "know" how to behave proportionally. If you want to have a layout where a Page Control resizes itself proportionally to its Container, e.g., always occupying the left half of it, you have to use some persuasion. What you'd do is: place a Panel on the Container and make it Proportional in the right direction(s). Place the Page Control into the Panel. All we need now is to make the Page Control fill the entire area of the Panel. Sure, we could carefully resize it and set all of its Anchors to On (and yes, it would work fine), but there's a much easier way: just set the Page Control's Alignment to Client – and it does precisely what we want: covers the entire Panel. The Panel now behaves proportionally, and the Page Control within it simply keeps up with it by resizing itself to whatever the Panel decides to size itself.
Many items support the Alignment property, but not all of them would benefit from it. Items that look and essentially behave like a rectangle of no pre-set size would usually be good/sensible candidates for setting their Alignment: Panel, Split Panel, Page Control, Grid, Image, Rectangle, Memo. Everything else is probably less suitable. A top-aligned Label, for instance, is possible, but doesn't usually make much sense.
Now that we have introduced the concept of Containers, and parent and child items, it's time to examine how you place items in Containers.
Actually, there's almost nothing to it. When dragging a field from the Fields grid onto the InfoView, the procedure is exactly the same: you just drag the field and drop it into the Container you want to parent it to (i.e., the one you want to insert the field into). If you have an InfoView and a Panel in it, both of the above are Containers, so you can drag the field onto the InfoView itself or onto the Panel. In the first case, whatever item gets created will be parented to the InfoView and will hence become a sibling of the Panel. In the second case, it will be parented to the Panel and become its child. So, drag-and-drop works the same way.
With other methods of creating items – double-clicking a field or invoking a command such as "Panel" – all you need to do is indicate what your desired destination for new items is. The destination is simply the currently selected Container. If the currently selected item is not a Container (a Label or an Edit Box, for example), Designer will assume that the current destination is the item's parent Container. If nothing is selected at all, this is typically interpreted as if the InfoView itself were selected, so this is what will be the destination.
Some examples follow. Let's assume you have an InfoView with a Panel A, a Split Panel and Page Control within it, and another Panel B in the first Tab Sheet of the Page Control. Plus perhaps some Labels and similar fluff here and there.
Moving existing items from one Container into another is not very difficult either. Unfortunately, you can't just drag-and-drop them between Containers. What you can do, is use Cut-and-Paste: select the items you want to move; Cut; select the destination Container; Paste. Note that when pasted, the items attempt to maintain their original positions in the source Container. It is sometimes convenient to temporarily resize the destination Container so that the pasted items are at least visible, then move them where you want them, and resize the Container back to its original or desired size. An alternative solution is described in the topic dedicated to Cut-and-Paste. You'll quickly get a hang of it all.
There remains just one last trick we'd like to share with you. It's not a Designer feature per se, but merely a clever way of using the behavior of Containers and items we have described above.
Let's say you have an InfoView form with a relatively simple layout depicted below.
The items on the left keep their sizes and positions constant. The Memo on the other hand gets automatically resized with the form. Why? We have probably set all of its Anchors to On. Fine. But let's see what happens if you shrink the InfoView's width too much. The Memo will simply keep shrinking until there's nothing left. Keep reducing the width of the form, and when we reach the items on the left, the form finally displays a horizontal scrollbar. Everything is behaving correctly, and it's not too bad either, but we can make it better. Wouldn't it be nice if the scrollbar appeared just a little earlier – when there was still some Memo left? That would make the InfoView usable even when shrunk to a microscopic size. But we don't have any direct control over when the scrollbar appears: it does so when the form reaches some non-moving item in it. And that's precisely the trick.
The above screenshot displays such an item in a position that we consider reasonable. Note that the item is underneath other controls, so all you can see is its selection handles.
We were talking about this "doorstop" item being "non-moving", and by now you probably understand what exactly this means "technically": it's an item with only its default Anchors turned On: Left and Top.
There are some special considerations when deciding on what Container you should place the doorstop item. Generally speaking, it is always true that it is the parent Container of this item that will display its scrollbars when the item no longer fits in it. The rather technical problem (which, incidentally, is not specific to Alventis) is that items anchored right and/or bottom maintain their distance to the visible edge of their Container – irrespective of scrollbars, if any. This may have sounded obscure, and it really is. You don't have to worry about such intricacies though. What's important is the bottom line: always place the doorstop item behind a client-aligned Container. Both the doorstop item and the Container must be siblings, both being parented to their common Container. A simple example would be: the InfoView form (acting here as a parent Container) would have the doorstop item and a Panel. The Panel would be client-aligned thus covering the doorstop item. If that Panel weren't client-aligned but merely anchored on all sides, you'd fall victim to that obscure problem we have mentioned earlier. Try it if you don't believe us.
Creating effective layouts that behave well when you resize the form is half science and half art. It certainly takes a bit of practice and some trial and error. With the unprecedented flexibility of the Layout tools Designer puts at your disposal, you should be soon creating dazzling and fully-resizable InfoViews.