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.

 

A Container is simply an item that can contain or hold other items within it. The InfoView form itself is one such Container. The other ones are: a Panel, a Split Panel, and a Page Control. Nothing else "qualifies". An Edit Box can't hold a Checkbox inside it. An Image item may initially seem like a Container, but in reality it's not: you can place items on top of the Image, but not in it. Even a grid is not a Container. While it is true that it can hold columns, these are not items in the general sense, but rather the grid's own sub-elements (even if we occasionally refer to them as "items"). The ultimate test is quite simple: moving a Container moves the items it contains. You can move an Image item all you like, but whatever other items happen to be on top of it won't move with it, so it "fails" the test.

 

 

InfoViewContainers1

 

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

 

A. The first one is rather simple. The Container only reacts to child items within it that do not move when the Container is resized. And the way is reacts is: whenever it is shrunk so much that at least one non-moving child item no longer fits, the Container displays appropriate scrollbars thus extending its "virtual area".

 

It may sound mighty complicated but you have undoubtedly witnessed it a hundred times: make a form too small and suddenly it's got scrollbars, so you can scroll around to still get to all these (child) items.


InfoViewContainerResizing1

 

B. The possible reactions of the Container's child items to their parent's resizing vary between very simple and rather involved:

Do nothing. Nothing gets simpler than that. The Container resizes the child item "stays put" and doesn't budge. Nothing interesting here except that it is precisely such "dumb" items that make the Container react by displaying its scrollbars when necessary.
Move and/or resize itself according to the child's Anchors property. We'll see what this means in a bit.
Resize itself proportionally to the parent Container. This sound like the most natural thing to do, but amazingly, only Panels and Split Panels can do this. We will learn how exactly this works shortly.

 

 

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.

 

Every item has 4 Anchors: Left BarDgnAnchorLeft, Right BarDgnAnchorRight, Top BarDgnAnchorTop, and Bottom BarDgnAnchorBottom one on each side. Each of the Anchors is like an On/Off toggle switch, so an Anchor can be On or Off. They are all pretty much independent from one another, and each of them means the following thing: when On, maintain the distance from the item to its parent on the corresponding side (when Off, don't). Let's see how it works for, say, an Edit Box directly parented to the InfoView (i.e., the Edit Box is child of the InfoView as all our items have been so far). We'll see what will happen to it depending on how we set up its Left and Right Anchors.

By default, the Edit Box (almost all items, in fact) has its Left and Top Anchors On and the Right and Bottom Off.


InfoViewLayoutAnchors1A

 

We promised to only play with the Left and Right ones, so we'll leave the Top/Bottom ones alone. So, initially, the Left Anchor is On, Right one Off. We all know what such Edit Boxes do when their parent resizes: nothing. This makes sense: the Left Anchor tells the Edit Box to maintain its distance on the left from its parent's left edge and that's what it does. It's not its fault that it looks like it's not doing anything.


InfoViewLayoutAnchors1B

 

It's also true that doing what it's doing (staying in place) doesn't take much effort, so let's make its life a little more complicated. Let's turn Left Anchor Off and Right Anchor On. But we haven't told you how to do this, have we? The Anchor - Left and its 3 sibling toggle buttons do this. Now, when we resize the InfoView, our Edit Box moves "with" the right edge of the form. This is exactly what we have told it to do: maintain its distance on the right.


InfoViewLayoutAnchors1C

 

On to the most interesting test now: turn both the Left and Right Anchors On.

 

As is to be expected, the Edit Box now maintains both "margins" constant, and resizes itself as necessary.


InfoViewLayoutAnchors1D

 

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.

 

 

Before we move on, we'd like to point out to you one common source of confusion.

 

Given the item layout depicted in the accompanying screenshot, how do we set the Anchors of the two Edit Boxes so that they maintain the 3 gaps between themselves and the edges of the form?


InfoViewLayoutAnchors1E

 

The frequent initial reaction may be to set both Left and Right Anchors to On, and that for both Edit Boxes. Alas, the results are not what we could hope for. You can try it yourself, but the cause is easy to understand even without experimenting: Edit Box A will maintain its distance to its parent on the left (great!) and... on the right and this is precisely the problem. On the right, it will be maintaining its distance to its parent (the form) and not to Edit Box B. The latter will have the same exact problem on its left side. As a result, both Edit Boxes will be resizing themselves, quite oblivious of one another, overlapping, etc.


InfoViewLayoutAnchors1F

 

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.

 

The Anchor Mode toggle button BarDgnAnchorMode, as the name suggests, is responsible for turning this special mode On or Off. Once in the Anchor Mode, everything behaves a little differently. You can select only one item at a time. You cannot move or resize items. The only thing you can do is what this mode is all about: inspect and adjust Anchors. And this task is remarkably easy. The selected item displays the Anchors in the middle of its edges.

 

The Anchors that are On, are shown as green squares, those that are Off as gray ones. You can toggle an Anchor by clicking it with the mouse.


InfoViewLayoutAnchorMode1A

 

You therefore have a much more direct visual feedback right at the spot where the Anchor is "attached" to the item. The limitation of this mode is of course that you can only adjust Anchors for one item at a time. If you have a whole array of items you want to set Anchors for the same way at the same time, you may be better served by the "regular" Anchor buttons. Make sure Anchor Mode is Off, select all the items you want to affect, and toggle the Anchors using the buttons. You won't have any visual feedback directly on the affected items, but at least you don't have to iterate through them one-by-one to set them up.


InfoViewLayoutAnchorMode1B

 

 

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:

Resize itself proportionally to the parent Container.

 

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 BarDgnProportionalityH and one for the vertical direction BarDgnProportionalityV.

 

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).

 

Let's go back to our last problem with two side-by-side Edit Boxes and see if Panels can help.

 

We will now place two Panels side-by-side, completely "filling" all available space (horizontally).

 

We'll put Edit Box A in the left Panel and Edit Box B in the right one:


InfoViewLayoutProportionality1A

 

With that done, we will make both Panels Proportional in the H direction by selecting both and making sure Proportionality / H button is depressed. Almost there. We now set both Left and Right Anchors to On for both Edit Boxes (yes, just as we have unsuccessfully tried earlier). Done!


InfoViewLayoutProportionality1B

 

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.

 

While it may look for a moment like a very different item, the fact of the matter is: a Split Panel is just a regular Panel (the kind we have examined earlier) that holds two more such Panels inside, with a Splitter in-between. That's all there really is to it, so there's very little new stuff to learn. It mostly works and reacts just the way ordinary Panels would. You can set the Split Panel's Anchors or Proportionality. The Sub-Panels, while true Panels in all respects, offer you fewer layout adjustment possibilities simply because they are already properly laid-out for you within their parent Split Panel. This is why you can't even resize them. You can still set Proportionality for the "top/left" Sub-Panel though. Resizing the entire Split Panel will make that Sub-Panel resize itself proportionally, which will have the effect of the Splitter automatically maintaining the split ratio, e.g., one third on the top, two thirds at the bottom.


 

InfoViewLayoutSplitPanel1A

 

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.

 

You are probably familiar with these ubiquitous and frequently over-used user interface items. A Page Control can have one or more Tab Sheets. The little tabs on the top allow one to select the active Tab Sheet that will then reveal its contents to the world. This can be a neat way of organizing a busy form that has too many items to fit in a single screen. Quite frequently, Panels and/or Split Panels prove sufficient. Even if your monitor's resolution is not very high, and you can only see small Panels with items crammed in them, you may be able to "zoom-in" to a specific Panel using PanelZoom. Somebody else may have a high-resolution monitor though, and he/she will benefit from seeing all form's items at the same time, side-by-side, which is usually preferable. For situations when such a Panel-based solution is not what you're looking for, the Page Control provides an easy alternative.


InfoViewLayoutPageControl1A

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.

 

The Caption column lists the Tab Sheets and allows you to adjust their tab's Captions. The Values column, on the other hand, is not very meaningful. Its only purpose it to make it easier for you to re-order Tab Sheets. You can enter numbers or letters into it and sort the grid by that column. The Tab Sheets will end up in the same order they appear in the list, so whichever way (and by whichever column) you sort, this will determine the Tab Sheets order in the Page Control. The mini-grid is obviously where you can create new Tab Sheets by inserting a record in the list or delete them by deleting the corresponding record.


InfoViewLayoutPageControl1B

 

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" BarDgnAlignment, 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 BarDgnToogleClientAlignment. 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.

 

First, let's place two Panels on an InfoView. For the first panel, let's set its Alignment to Top and ensure the Panel occupies roughly the top third of the form. For the second Panel, we'll set its Alignment to Client. The second Panel now occupies the entire available area, i.e., whatever area was not taken by the first Panel. Resizing the first (Top-aligned) panel automatically adjusts the size of the Client-aligned second Panel. Resizing the entire InfoView form doesn't affect the height of the Top-aligned first panel, but the second one always fills whatever space is left, so it gets automatically resized. This is a great way to very quickly divide a form (any Container really) in portions that will neatly maintain their overall relative layout.


InfoViewLayoutAlignment1A

 

You can put more than two aligned Panels next to each other.

 

Here's an example of just one possible layout.

 

One common thread that is likely to be found in all such layouts is the single Client-aligned Panel that always "completes the picture". You are under no obligation to have one, but you'll discover that your layout will be mighty strange without it.


InfoViewLayoutAlignment1B

 

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.

 

To insert a new item, for example a Label, into the InfoView itself, we'd unselect everything by clicking on the InfoView background, and we'd then invoke the Label command.

To insert it into the Panel A, select Panel A or any non-Container item within it and click Label.

To insert it into the lower Sub-Panel of the Split Panel, select that Sub-Panel.

To insert it into the Tab Sheet select the Tab Sheet.

To insert it into Panel B select that Panel or some non-Container item in it.

Well, hopefully you get the idea.


InfoViewLayoutContainers1A

 

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.

 

All we need to do is put some non-moving item where we want the scrollbar to show up! There are a few items that would suit this purpose: a Label or a Rectangle, for example. Especially since we can easily make both of them effectively invisible. A Label's text can be set to a single (or several) spaces. Or we can set its font color to the color of the background. Similarly, we can persuade the Rectangle to not display a border. We'll see how all this is done in the next chapter, but the point is: we can place a little invisible item where we want, and its only useful function will be to hit the edge of the form (or whatever Container we are working with) thus persuading it to display a scrollbar.


InfoViewLayoutDoorstop1C

 

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.