NAME

GUI Loft User Manual -- How to use The GUI Loft.


VERSION

Release date: See the Changes file

This is currently beta software, mostly when it comes to some (unimplemented) parts the UI. Code quality and stability should be good though. Please let me know of any bugs or user interface quirks you find. mailto:johanl@bahnhof.se


INTRODUCTION

What is it?

The GUI Loft is a powerful and easy-to-use WYSIWYG editor (written in Perl) for designing Perl Win32::GUI windows. It is also a set of classes used to create the window for you at runtime.

You design your GUI in The GUI Loft and bring it to life with a few lines of code, with the option of taking part in the build process.

There is a User Manual, a Programmer's Reference, Demo code, and a support mailing list.

Getting Started

The Support Mailing List

There is a low volume support mailing list at

http://www.bahnhof.se/~johanl/perl/Loft/

Topics include: announcements, bug reports, usage questions, feature requests, and basically anything else related to using The GUI Loft. Subscribing is recommended. And don't be shy :)

Archives: http://groups.yahoo.com/group/theguiloft


(it's easy to unsubscribe)

General Concepts

This is how The GUI Loft is supposed to work:

You design your window or dialog box in The GUI Loft. You provide external resources--bitmap images for use on Buttons and other controls. You perform a final touch-up of Tab- order and control names to make everything perfect.

Then you have the Win32::GUI::Loft::Design class dynamically create the window for you at runtime. Refer to the Programmer's Reference for details.

(Advanced: If you need to tweak the options of any controls or add currently unsupported controls of your own, you can do that by supplying a subclassed ControlInspector object to the build process.)

Then you add more UI stuff (mostly dynamic behaviour) with regular Win32::GUI code, and then you are done with the UI so you can concentrate on the application logic.

The Birth of The GUI Loft

Visual Basic is cool!

I remember thinking that the first time I saw it. That was when VB was still version 1.0, just a kid. So was I actually :)

At this time VB was in fact really, really pathetic in almost all regards except one--despite it's shortcomings, it was by far the easiest way of creating Windows applications with actual windows, icons and buttons and stuff. So it rocked.

Win32::GUI is cool!

I remember thinking that the first time I saw it. Cool, because now I can use my favourite lingo (yeah, that would be Perl :) and create native Windows applications. Tremendous amounts of cred to Aldo Calpini for creating the module. Loads.

My second thought was, ``Is there a design tool?''. I think most people using Win32::GUI have asked themselves that question, because GUI design is a visual art, a design problem that requires good and mature tools as much as code problems do.

Ok, so I didn't find one, and immediately begun thinking about writing my own. Hey, that's me :) But it seemed really complicated, and I ended up thinking that I should build on other people's work instead. The idea being that the design program is the difficult thing, so let's leave that to someone else. How about just using a third party designer program and convert the saved file to Perl code?

It's a nice idea, but there are drawbacks.

There are a lot of bad editors out there, parts of macro editors and stuff. There must be great editors out there too, but I really didn't find any (to my surprise), especially not any that were shareware or free in a useful way. Maybe I didn't look enough diligently.

Visual Basic would do, but that's a hefty thing to buy (or ``acquire'' :) just to get the designer capability. After all, if I write a program I would like many people to use it.

So I ended up not doing that. And by this time I had found the Win32::GUI mailing list archives, and actually found a design tool: GUI Builder, written by David Hiltz.

With GUI builder you can draw a design and have it come out as Perl code. Tweak it a little (e.g. by declaring the variables created), and you have a working piece of code for creating a window or dialog box.

While GUI Builder gets the job done, it didn't really work as smoothly as I'd like, and the code didn't inspire any adventures of my own. I guess writing a large program without strict or warnings is an impressive feat in itself. But I'm forever grateful to David for proving that it can be done, using low level graphics routines to draw the controls in design mode. And as I understand, Aldo was very responsive when it came to providing the neccessary Win32::GUI support.

So that's the situation where I started writing The Perl GUI Loft.

A lot of time, studying, and adventures in WINUSER.H later, here we are :)


WINDOWS AND PALLETTES

The Main Window

The Main window contains a list of all controls. It's main purpose is to display a complete list of controls (including intangible controls, such as Timers), select controls that are obscured, and let you rearrange the control order.

You can also group controls into Clusters (see below).

The Design Window

The Design window allows you to manipulate the window and it's controls visually.

Select, move and resize controls with the mouse. Or use the keyboard to fine tune size and position.

The Tools Pallette

The Tools pallette contains all the currently available controls. Click to insert a new control in the middle of the Design window.

Currently supported controls are:

The Properties Window

The Properties window contains the properties of the currently selected controls.

Only properties shared by all selected controls are displayed, and only identical property values are displayed with their values (the rest say ``- ? -'' to indicate that they differ).

If you change a property value it will affect all selected controls, a general principle that holds most of the time. If you do something, you do it to what you selected.

When you select a property, you get the opportunity to edit it's value at the top of the screen (I tried to implement edit-in-place but failed due to spotty support in Win32::GUI).

Note: You need to press <Return> to confirm any changes you type.


 


MANIPULATING CONTROLS

Adding Controls

Add controls to the window by clicking the corresponding button in the Tools pallette.

Note: Immediately after the control is added, it is a good idea to give the control a good (as in ``descriptive'') name and to change the Text property. Use the property shortcuts ``n'' and ``t'' to do this.

Read the ``Control Names are Global'' section for a few survival tips regarding names.

Selecting Controls

Combine the following rules and you have a flexible way to select just the contols you want.

Moving and Resizing

Aligning Controls

Align controls with the menu options under Edit | Align, or right-click in the Design window to align the selected controls.

Use liberally :)

Grid & Snap Settings

There is a supporting Grid available in the Design window.

The preselected resolution is 4 by 4 pixels with Snap turned on. Any movements and size changes will snap to the Grid. If you want you can make the Grid visible as well (althoug the current implementation is kind of slow).

The Grid settings are stored along with your window.

Property Shortcuts

You edit the properties of the currently selected controls in the Properties window.

The fastest and easiest way is to click the property and then press Tab to bring the focus to e.g. the textfield where you can change the value.

Actually, for some properties there is an even faster way when you are using the Design window.

Hidden and Disabled Controls

Hidden controls are still visible, but the text is white to indicate ``invisibility''.

Disabled controls look mostly like they actually do on the resulting dialog. Text is gray to indicate that the control is disabled. If the control contains an image, a black cross is displayed on top of the control.

Tab Order

The tab order is the order in which the controls are added to the window. That's also the order in which the controls will gain focus when the user presses the Tab button.

Use the up and down buttons in the main window to change tab order position of the selected controls.

Most controls should have the Tabstop property set. The default setting works fine for most controls, but you may have to change it for certain RadioButton controls or if you have other needs.


CLUSTERS

Controls can be grouped into clusters. There are two major benefits of using clusters.

The first is that you can easily hide some controls temporarily so you can concentrate on other things. This is very handy e.g. in the case of TabStrips, when many controls occupy the same space.

The second (and this is cool) is that you can associate each Tab in the TabStrip with a Cluster and then have The GUI Loft manage the Tabs for you at runtime. Refer to the section about the TabStrip control for information on how to do this.

Working with clusters

Let's say you have a TabStrip with a few controls in the first Tab. To avoid clutter, select the controls and create a new cluster. Then hide it by double clicking on the eye icon. Now is also a good time to rename the cluster to sometning descriptive.


The hidden controls can't be seen or manipulated in the Design window while hidden, so you can concentrate on laying out the controls in the second Tab. Select those controls as well, and create a new cluster. Now you can easily keep track of which controls belong to which Tab in the TabStrip.

Double click on the cluster eye icon to hide/show it. When you show the cluster, all controls in the cluster will become selected.

Memorize

You can redefine which controls belong to a cluster by selecting all appropriate controls and then click on the ``Memorize'' button.

Trick: Start by double clicking the cluster two times to make the controls selected, then add or remove more controls by Ctrl-clicking them. When you're done, click ``Memorize''.

Clusters and the Visible property

Controls of hidden clusters are not visible when windows get built, regardless of the Visible property.


CONTROLS

Most controls are pretty straightforward, but some things you might need to know are non-obvious.

Not all controls are 100% WYSIWYG when you combine weird flags. When that becomes a problem, preview often.

Window

Windows can be a Win32::GUI::Window, Win32::GUI::DialogBox, or Win32::GUI::ToolbarWindow (a Window with style WS_EX_TOOLWINDOW).

Windows of type Window and DialogBox seem to have a minimum size which you can't affect by resizing them. I don't know if that's a Win32 thing or a Win32::GUI thing.

The ToolbarWindow can be any size, but you still can't resize the design window. However, you can change the Width property in the Properties window and get a smaller ToolbarWindow. Preview to see the actual size.

Property: Controlparent -- Allow the user to navigate among the child windows of the window by using the TAB key.

Menu

There is no menu control in The GUI Loft beacuse I really don't see the need; a menu definition is by it's very nature a very text oriented thing and as such is more suited for code.

So there is no menu control. However, there is support for previewing a window with a menu attached using the PreviewMenu property of a Window.

Each comma separated item in PreviewMenu will be displayed as a menu bar item when you preview the window. No drop-down menu, just the actual menu bar.

As an example, the PreviewMenu of The GUI Loft's own main window looks like this:

        &File, &Edit, &Design, &Help

When you eventually create your Window you'll have to provide a complete menu object of course.

ImageList

ImageLists are intangible--they aren't visible in the Design window. You can still select them in the Control list in the Main window.

The Flags property is probably best left untouched, I'm not too sure exactly what it does (I have read the docs, I just don't know what it means in practical terms :) Anyone?)

The Grow property indicates the maximum number of images in the ImageList, in case you would like to add more images to it later.

The Images property is a comma separated string with file names that contains bitmap files (.bmp). If a bitmap fails to load, it will not be inserted into the ImageList (and the index will be screwed up).

Note: It is a good idea to put ImageLists near the top of the Tab order to make them easy to find in the Tab order list; that's the only place where they are visible.

During build, ImageLists are always created before regular controls since they have to exist when other controls reference them.

Button

You can specify bitmaps. If you do that, it is a very good idea to save your window first, so all relative paths get resolved correctly.

Shortcut: Press ``b'' to edit the Bitmap property.

Trick: There is a non-obvious shortcut for selecting a .bmp file. If you enter a single space, the Open dialog will pop up.

Label

Use a label to display static text.

Use a label to display images. The Bitmap shortcut & trick (see Button) work here too.

Use a label to display a horizontal bar. Set the Frame property to ``etched''.

Hyperlink

A Hyperlink is a clickable Label with an Url property.

It uses the Win32::GUI::Hyperlink <http://www.jeb.ca/perl/win32_module.htm> module to do this, so if you use it, that module must be installed on the target system.

Textfield

The GUI Loft supports a few features not available using vanilla Win32::GUI, like Uppercase, Lowercase, OEMConvert, and Number.

Radio button

Set Groupstart: 1 and Tabstop: 1 for the first Radio Button in each group. All other Radio Button controls should have these properties set to 0.

The only available alignment is left/right.

Listbox

Listboxes snap their height to the nearest visible line. I still haven't got that snap algorithm perfect, but it works--kind of. Preview often.

There is preview support using the PreviewList property. Each semicolon separated item in PreviewList will be displayed as a line in the ListBox.

Combobox

If the Combobox has a drop-down style menu, the height of the Combobox decides the height of that menu when dropped down.

AutoHScroll -- Automatically scrolls the text in an edit control to the right when the user types a character at the end of the line. If this style is not set, only text that fits within the rectangular boundary is allowed.

DisableNoScroll -- Shows a disabled vertical scroll bar in the list box when the box does not contain enough items to scroll. Without this style, the scroll bar is hidden when the list box does not contain enough items.

TreeView

You can specify the name of an ImageList control to use. If the ImageList control doesn't exist, it simply won't be used.

There is preview support using the PreviewTree property.

Each semicolon separated item in PreviewList is a branch in the tree.

Each comma separated item in the branch is a node. The first node in the branch is at the top level, the rest are located below.

After the node text, you can (but don't have to) specify which image index in the attached ImageList control to use.

Example:

        Visible:0, Button:1, TreeView:1, Custom:1; Invisible:0, Timer:1, ImageList:1
        + Visible
        |       |- Button
        |       |- TreeView
        |       |- Custom
        |
        + Invisible
                |- Timer
                |- ImageList

ListView

The ListView has a lot of properties to set, so the control is semi-WYSIWYG. Preview often.

Toolbar

StatusBar

You can place the StatusBar control anywhere in a Window, but when displayed it will be placed at the bottom of the window. Just like in Win32::GUI.

ProgressBar

The Pos property isn't WYSIWYG, so you'll always see the control as if Pos == 0. Preview often.

TabStrip

The TabStrip has a lot of properties to set, so the control is semi-WYSIWYG. For example, there is no WYSIWYG support for the Buttons property. Preview often.

Timer

Timers are intangible--they aren't visible in the Design window. You can still select them in the Control list in the Main window.

During build, Timers are always created after regular controls so they don't start firing off events before everything is done (or maybe if they don't start before Dialog() is called, I don't know).


COLOR MANAGEMENT

The color stuff is highly experimental and possibly not forwards compatible (good idea: don't use it).

The following controls have a Foreground and Background property:

        Label 
        Textfield 
        Listbox 
        Treeview (also has Backcolor and Textcolor properties)

Specify RGB colors by setting the property to a color triplet, e.g. ``255 255 0'', ``127 127 127''.

There is no WYSIWYG support for colors, so preview often.

Color Management Done Right

When done right, controls change color in the Design window, it is possible to use colors from the user's color scheme, the Window control has color support, and there is a color selection dialog.

But that's in the future.


RESIZE MANAGEMENT

A Win32::GUI::Resizer object is used to manage the window's Resize event for you. In most cases, this will absolve you from manually coding that boring part of the GUI.

If you have very special needs you may have to do this yourself anyway, either using the Win32::GUI::Resizer class or with straight Win32::GUI code.

Resize properties

Thinking about resizing

The Resize?Mod property

The ResizeHMod and ResizeVMod properties are used to modify how much the control should move/resize when the window changes size. For example:

The value of the Resize?Mod property should a valid Perl expression, returning the new value. $_ is set to the ``original'' value. Examples:

Cut the resize change in half
$_ / 2

Negate the resize change
0 - $_

Invalid Perl code will result in an error when the window is being built, and the buildWindow() method will return undef (so check this return value, ok?). In The GUI Loft, the Test window command will give you an error message.


TIPS & TRICKS

Perl Code From the Design

Use the menu items under Edit | Copy Perl to put useful things in the clipboard.

Control Names are Global

Because Win32::GUI works the way it does, it is somewhat easy to get name clashes. This is important since event handlers (e.g. sub btnOk_Click) are always located in package main unless you fiddle around in impractical ways; controls names are in effect global.

So it is a good idea to give controls names that are likely to be unique. ``btnOk'' isn't really that good, since you are likely to have an Ok button in many windows in your application.

Radio Button Groups

Only one Radio Button in a group can be checked at a time.

You create groups by setting the Groupstart and Tabstop property on the first Radio Button in the group. The other Radio Buttons in the group should not have these properties set.

Name your controls right

Don't leave the default names unless you are making a throwaway prototype. They'll gang up on you and you'll just get confused. Besides, it's lousy craftsmanship to leave junk in your code...

Use the descriptive prefix in the default name, like ``btn'' for Buttons, ``lbl'' for Labels, and ``chb'' for CheckBoxes. It'll help you recognize what kind of type of control it is, and you can use the same name for e.g. both the Label and Textfield that is used for e.g. Age (``lblAge'' and ``tfAge'').

The program will help you do this when you use the ``n'' property shortcut and only highlight the actual name portion of the Name property. Use it, I put it there for a reason :)


ON DESIGN

Not that I'm an expert or anything, but here are a few thoughts on GUI design in general.

Make it Look Nice

It's about design. Visual design. User interface design.

I have a saying:

        The Interface IS the Application

Well, to the user it is. The UI is all there is.

An ugly user interface reflects badly on your application. No matter how elegant, well structured, and easy-to-maintain the code is, an ugly and awkward user interface will make your program a pain to use.

So make it exciting, easy to use, well disposed and nice to look at. Remember, first impressions last.

Be Consistent

Align Things

Think Outside the Box

Or rather, forget the box. Forget what you see. That's the weakness with WYSIWYG--what you see is all you get. But it doesn't have to be like that.

A GUI can be dynamic; you can change the layout in response to some user action, move things around, hide or show controls, change the size of the window.

Don't let the design tool limit your ways. Let it make hard things easy (the visual layout), so you can implement the hard things in code (the dynamic behaviour).

Let Someone Else Do It

What if you're not a great GUI designer? What if, instead, you're a kick ass programmer?

Let someone else design the dialog boxes and do what you do best and have most fun doing.

It's a Win32::GUI Win-win Solution(tm) :)

Further Reading

If you only read one book... and so forth. But this is the book about user interface design. Although it's about GUIs, if you ever, ever, wrote a program with a UI (and I know you did), this book is useful because it forces you out of geek mode long enough to realize why you wrote the program in the first place.

        "About Face: The Essentials of User Interface Design"
        Alan Cooper
        ISBN: 1568843224
        http://www.amazon.com/exec/obidos/ASIN/1568843224

Further Surfing


IMAGES AND ICONS

Icon Editors

MicroAngelo is a good icon editor (but there are loads of them out there). 30-day trial available at:

        http://www.impactsoftware.com/

I also use Photoshop and ImageReady for .bmp files, but only beacause I already know those programs. For icons images, it's pretty much overkill, although the color management is nice.

Finding Icons and Bitmaps

Icons for all occations:

        http://www.eldos.org/icon/icons.html

Take some time to browse the collection to get an idea of what's there when you need it. Their Thumbnailer program is good too (30 day trial).


IF YOU NEED ANYTHING

If you need support for something, please tell me. I need to know what doesn't work and what doesn't work the way you want it.

In particular, I'm interested in the more esotheric controls (like e.g. Rebar), which I haven't toyed with yet. So a working piece of code would be a good help.

Johan Lindström, mailto:johanl@bahnhof.se


KNOWN BUGS

The general paint routine is slow (could probably be optimized). The grid paint routine is even worse (could, no... should be optimized)

The handling of properties updates when moving controls is slow (could be optimized)

The command buttons seem to lose their bitmap sometimes... I don't know if this is my fault or a Win32::GUI thing, but rather suspect the latter... :/

Keyboard handling is home grown (Accelerators doesn't work yet). So if you press two keys rapidly in succession, the second one may be discarded. Might be annyoing if you are fast with the Ctrl-C, Ctrl-V.


COPYRIGHT

The GUI Loft is Copyright (c) Johan Lindström, johanl@bahnhof.se

The Perl Artistic license applies.