|
A frequently difficult issue is creating forms that adapt to the user's needs
for screen real-estate. It is critical to be able to do this, for several reasons...
-
No screen is large enough for the user with many tasks.
-
A cooperative application may need to be resized so that another application
is available to offer objects for drag and drop, or so its draggables can
be dropped on another application.
-
In multiple window interfaces, the user should be free to resize the user
interface of each window into a convenient configuration.
It is simple enough to create a form that is resizable, but when the form is
shrunken, controls disappear behind the edges, and when the form is made larger,
the controls are surrounded by bare space.
 |
The base form has a set of components in
a particular arrangement.You can see the splitters (in purple) that allow
for a resizing the components manually. |
 |
But when the form is resized, the components
don't follow the form. Here we see the extra margin left when the form is
dragged larger... |
 |
And here, the form grows scrollbars, but
now some of the controls are missing - at least until the user scrolls the
form. |
 |
But when alignment is used, the form components
resize adaptively. When the form shrinks the "client" aligned
components get smaller... |
 |
And when enlarged, they grow. |
The "aligned" form has the following components (you can paste this
onto your own form in the IDE)
object Panel1: TPanel
Left = 186
Top = 0
Width = 185
Height = 300
Align = alRight
Caption = 'Panel1'
TabOrder = 0
object Splitter1: TSplitter
Left = 1
Top = 151
Width = 183
Height = 5
Cursor = crVSplit
Align = alTop
Color = clPurple
ParentColor = False
end
object ListView1: TListView
Left = 1
Top = 1
Width = 183
Height = 150
Align = alTop
Columns = <>
TabOrder = 0
end
object Panel2: TPanel
Left = 1
Top = 156
Width = 183
Height = 143
Align = alClient
Caption = 'Panel2'
TabOrder = 1
object Splitter2: TSplitter
Left = 106
Top = 1
Width = 5
Height = 141
Cursor = crHSplit
Color = clPurple
ParentColor = False
end
object RadioGroup1: TRadioGroup
Left = 1
Top = 1
Width = 105
Height = 141
Align = alLeft
Caption = 'RadioGroup1'
TabOrder = 0
end
object Memo1: TMemo
Left = 111
Top = 1
Width = 71
Height = 141
Align = alClient
Lines.Strings = (
'Memo1')
TabOrder = 1
end
end
end
object TreeView1: TTreeView
Left = 0
Top = 0
Width = 186
Height = 300
Align = alClient
Indent = 19
TabOrder = 1
end
Here you can see the
 |
The form starts completely empty. |
 |
Next, add the panel on the right (Align=alRight) and size appropriately.
Remember, this will not change width to follow the form - only height.
Then add the treeview to the left and align to alClient. The treeview
will now change size as the form is adjusted. This is a common strategy
when a control panel contains buttons or other controls that shouldn't
be or won't take well to resizing.
It is usually a good idea to put a splitter between these two components,
so that the user can override the developer's fixed size for the control
panel as needed.
|
 |
Next on the Panel1, add the ListView as Align=alTop, the splitter as
alTop, and the Panel2 as alClient.
Again, in the change from the prior step to this one, you can see a frequent
pattern in component layout...
-
Break down the layout into major left to right sections, with one
section alClient and the other left or right.
-
Within each of the horizontally arranged components, as appropriate,
break down their layouts into two sections, with one section alClient
and the other top or bottom.
-
Repeat the above process until the layout is complete.
It is possible, though much less common, to also put two horizontal layouts
inside each other or two vertical layouts inside each other. It is slightly
more common than that to have multiple components with the same alignment
(top, left, bottom or right) and one client component. One example of
that is the placement of the splitter on this version of the form; both
the listview and the splitter are alTop.
|
 |
The final version puts a horizontal layout
into the Panel2. |
The extensive use of alignment and splitters provides a highly flexible user
interface. However, there are other important techniques as well.
Anchors offer an alternative to alignment. I only recommend their use, however,
when alignment can't be used or won't work. The following is a classic example
- two buttons which need to stay near the top and bottom of the form as it is
assigned.
 |
Here's the form with the two buttons. The
panel is alRight, and the treeview is alClient. The top button has Anchor->Top
and Anchor->Left = true (the default), and the bottom has Anchor->Left
and Anchor->Bottom = true. |
 |
As the form resizes in height, the bottom
button moves to stay visible. |
 |
But this can be pushed too far. |
For instance, some components don't have an Align property - this included
the TButton. Even if they did have it, there is a certain minimum size below
which a control panel becomes unable to adapt. A TScrollbox can be used to help
with that...
 |
The scrollbox can be used to deal with the
problem of controls overlaying each other. |
 |
But this is no panacea, since the controls
are fixed in position and will vanish when the form is shrunken. |
 |
But they can be scrolled into sight if needed.
Thus, the bottom controls should always be those less necessary for the
operation of the form. |
Cautions
-
These techniques do not deal with issues of font sizing. You can use a
component like GTSizer++ to manage
font sizing, but you will not be able to use alignment in a GTSizer user
interface.
-
Resizable user interfaces have limits. Use all of the techniques at hand
- including TPageControl, TScrollBox, alignment and anchors - to reduce
the complexity and prioritize the elements of the user interface. Trade
off appropriately between stable regions and client regions.
Conclusion
Creating a good user interface is equal parts art and science. You need to
consider the human factors of the interface and the elegance of the presentation.
You need to think about what is critical, what is important and what is optional.
You need to consider what aspects of the user interface need to be visible all
the time and which can be safely allowed to be hidden or obscured. If possible,
work with a trained graphic designer and a usability engineer, or gain that
expertise for yourself.
|
|