Skip to Main ContentWindow-Eyes  Braille Sense  CCTV  Voice Sense  SyncBraille  Support  Training
GW Micro - Unleashing the power of your mind's eye.
 

User Interface Techniques - GWWiki

Revision as of 20:56, 26 May 2011 by Corange (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Contents

Interface Options

An app developer has several choices of types of interfacing:

  • hot keys as input and spoken text as output
  • the built-in VB script UI commands such as msgBox and inputBox()
  • the built-in WE object model I/O dialogs such as the commonFileDialog method
  • the convenience I/O dialogs such as those available via the GWToolKit, or the Homer shared object library
  • the WE XML dialog feature

Examples Showing Use of Non-XML Options

While the remainder of this article will be used to cover the XML dialog facility, here are some short examples showing the

various other options.

' example showing hot key and speech as the interface technique
Set registeredKey = Keyboard.RegisterHotKey("Control-Shift-Windows-R", "SpeakHelloWorld")
Sub SpeakHelloWorld()
Speak "Hello world!"
End Sub

' example showing use of the WE object model's built-in commonFileDialog method
' get a vbs script file  name
strFileName = commonFileDialog(True, "Select VBS File", , clientInformation.ScriptPath, _

"VBS files,*.vbs", , , cfdfEnableDialogResizing + cfdfHideReadOnlyCheck + cfdfUseLongFileNames)

speak strFileName

' an example showing the use of the built-in VBScript commands

strFileName = inputBox ("enter the vbs script file name")
msgBox "the script name was " & strFileName

' example showing use of the GW toolKit 
' This example creates a simple dialog with a list box of four items, and returns a string of the data associated with the 

selected item.

Set myListBox = SharedObjects("com.GWMicro.GWToolkit.SimpleDialogs").ListBoxDialog
myListBox.AddItem "Red", "Red"
myListBox.AddItem "Green", "Green"
myListBox.AddItem "Blue", "Blue"
Speak myListBox.ChooseItem("Select a color")


the XML Dialog Facility

All of the possible I/O techniques listed above, except for the XML dialog facility, are limited to certain specific I/O

types or situations. They are certainly useful, and often quite convenient to use when they do fit your needs, but what they

lack is flexibility.

When you want dialogs in your app which are standard Windows dialogs, or when you wish to make use of the "apps menu" feature

in the WE control panel, or if you want a custom dialog to appear when the user presses the "help" button for your script in

the script manager (and not just the standard help dialog from the GWToolKit), you will need to use the XML Dialog feature.

Important note: this wiki article was written at a time when each app developer had to hand-code his/her XML, and thus fully understand each element, along with it's syntax and valid options.

Now, a "must have" app has been made available by GW Micro to it's app developers, named "UIDesign". While an app developer still must understand the usage and options of each XML element, UIDesign can now take over the drudgery work of writing all the XML, using correct syntax, having correct options, and with a valid relative placement of one element to another. In addition, it can show you how your dialog or menu will look and function, without your having to write a testing VBS app to do this.

Finally, if this weren't enough, UIDesign also aids enormously in arranging your XML in a way which allows for "internationalization" (or making the contents of your app's messages, dialogs, and menus, available in multiple languages).

Adding XML dialogs/menus to your app has two components:

  • design your XML dialog or menu structure and place it into an XML file
  • use the DIALOG or MENU method (of the application object) in your script to display the dialog or menu. This is documented in the App Developer Reference Manual, in the topic "Designing Custom Interfaces", with a quite detailed entry for this particular topic. the subtopics in this topic of the help file are less detailed, usually focusing only on the syntax of individual elements, and therefore it's helpful to have some additional information here in the wiki.

Creating the XML

XML is nothing mysterious; it's simply ascii text, like your app, and just like your app it has rigid formatting rules which it must follow in order to be valid. The XML statements are usually quite lengthy; while they can actually be passed as a string parameter to the DIALOG or MENU methods, in practice they are usually stored in a file. The choice of file doesn't really matter. Most script authors have one large XML file which contains all the XML needed for their script; however, it's equally as valid to create one XML file for your primary scripting needs, and a second to hold only your dialogs. In fact, this second choice may be useful if you write multiple apps which can share dialogs between them, as you could just copy and rename this file for each app. The reason which file you place your definitions into isn't important is that you must pass the name of this file to the DIALOG or MENU method as it's first parameter.

Designing a Dialog

Designing a dialog involves two areas of consideration, quite different from one another:

  • the functional decisions as to what information, and which controls, are to be included
  • and the need to layout the information and controls on the screen in a visually logical and pleasing way.

It's this latter requirement which can be the most challenging for blind developers, especially so for those who have never

actually seen a Windows dialog. Why do you need to give consideration to the visual appearance of the dialog? Because it's

likely your app will be seen by those with vision at some time; it may be a low-vision user, or it may be a sighted assistant

or coworker. In any case, the visual relationship and appearance of individual elements in a dialog conveys a great deal of

information to the viewer, and if not done properly, will serve only to confuse the person trying to view the dialog.

Functional Design Needs

The functional needs of a dialog are decisions such as: which controls to use, which text to place in the dialog (either as

instructions, as labels for controls or groups of controls, this is done by use of the <static> element because it doesn't

usually change once the dialog is displayed), and what data is to be included in the controls at the design time of the

dialog, and what data must be added and/or updated by the script after the dialog is displayed. When you have controls in

your dialog whose contents are not known at the time you're designing the dialog, but which will be controlled by the script

after the dialog is displayed, you will still need to place these controls in your dialog design when creating the XML,

because it's otherwise a difficult task to create "dynamic XML" in order that you can add or remove controls as the needs of

your app dictate. If you sometimes do not want or need a control at the moment, it's usually a better technique to add it to

the xml dialog, and use the enable and visible properties to make it not usable, and even not visible, at times. You can

also have controls which are "read only", by using a third property named readOnly, so that a blind user can easily tab to

the control and see it's contents, without being able to change it. The enabled property is the equivalent, for sighted

users, of readonly, when it is set to false. all of these properties can be initially set in the xml, and can be changed

later by your app.

Which controls to make use of will probably be guided by your experience gained from use of Windows and other Windows

applications. These obviously include radio buttons, listboxes, comboboxes, editboxes, checkboxes, etc. It's not going to

be possible for any instructional document to tell you the answers to which controls to use, but here are some issues to

consider when making your selection.

Functional Design Tips
  • multiple checkboxes, radio buttons, listboxes, and comboboxes can all be used to present the user with a list of choices,

which they need to pick from.

  • when you know the user may need to select more than one choice from a list of choices, you should probably consider

multiple checkboxes, or a multiselect listbox. another alternative is to use a listbox (or set of radio buttons), in

combination with an "add"and a "delete" button. this allows the user to build up a list of choices by adding one at a time

to a list accumulating on screen in yet another control.

  • both a set of radio buttons, and a listbox, allow the user to choose one alternative from many, and to be able to see all

their choices on the screen at once. there's little functional difference between these two approaches, it's more of a

visual issue. A combo box also allows a user to choose one choice from many, but the user can't see all the possible choices

initially, and they also have the capability if your app allows it, to enter text which is not one of the listed choices.

Visual Design Needs

Some issues of a visual nature have already been mentioned in the functional section. that's because the visual needs often

influence the functional design, even in apps meant to be used by visually impaired users (as has already been discussed).

The issues mentioned so far however are just the tip of the iceburg as far as considerations of a pleasing visual dialog

design. Here are some other guidelines which may help you layout and organize your controls in the dialog, once you've

decided what the controls need to be:

Grouping

It's pleasing to keep objects of a related nature grouped together. For example, this means putting the elements of a name

and address for an order in one group, and the details of the order in a second. It by no means stops here with one level of

grouping however. In your order section for example, you may have quantity, price, description, expected ship date, quantity

in stock, etc. for each item of the order. It could make a pleasing improvement if you put each item, with all it's

associated information, into it's own group; or perhaps, it's own line in a listview control, which would put all these items

into columns, which are a kind of group. The point here is to find ways of defining groups within groups, and even groups

within those. you may for instance divide the orders section into those in the basket, and those set aside for later

consideration, or shipping to a separate address. A technique which should be avoided would be to simply list one field

after the other in the dialog, going from top to bottom of the window, without any organization.

organization usually means use of the <group> XML element, but it also means use of text as titles to label groups, and the

justify, the align, and/or the orientation properties to visually move the controls and groups around in the dialog to aid

the organizational presentation by changing the purely visual presentation.

The primary tool for organizing the controls in a Dialog is the <group> element.  You should become thoroughly familiar with 

how groups function in the XML dialog if you want to create the best possible dialogs.

Every dialog is required to have at least one group (the main group which contains everything in the dialog except for it's

title text). It is usual to subdivide this group with additional groups.

In visualizing a group, and how the controls will be automatically assigned a place in it when you add them in the XML, it

helps to picture the group as an old-fashoned wooden ruler, which is going to be laid on the window. The positioning of this

ruler is going to determine where the controls which it contains are going to be placed in the dialog. How the ruler is laid

on the window, that is from left to right at the top, or top to bottom along the left edge, or left to right along the

bottom, is controlled primarily by the "orientation" property, and the "align" property. Understanding just these two

properties will go a long way in helping you understand how your controls will appear.

A group is either oriented horizontally (left to right), or vertically (top to bottom), and this is controlled by the

"orientation" property. This means when you add controls to the group, they will be added from left to right, or from top to

bottom. When the automatic placement of controls of a horizontal group reaches the right-hand edge, it will go back to the

left margin, make the "ruler" "taller", and begin positioning the next row under the first from left to right. The same idea

is true for a vertical group; the controls are placed one below the next, and then a row to the right is created if the

bottom is reached.

Similar to the way in which "orientation" controls how the "ruler" (or group) "runs", the "align" property controls whether

the "ruler" is pressed against the left or right edge of the dialog (or of the group which contains it) (this is for a

vertically oriented containing group), or the top or bottom edge when the containing group is horizontally oriented. It also

can be "center" for either orientation.

The "orientation" and "align" properties, have been discussed so far, and are probably most important when, used on the

<group> element. they control how the group itself will look, and where the group (and so all the groups and controls it

contains), will be placed in the dialog. There is another group property, "justify", which pertains however to the contents

of the group, and not the group itself. "Justify" (which can be left or right, top or bottom, full or center) controls the

spacing between the controls of a group; it doesn't provide you with any more or less empty space, but it does control how

the empty space in a group is used to position the controls within the group.

While align only pertains to movement of controls in the opposite direction of it's containing group's orientation; Justify

pertains to moving the controls in the direction of the group's orientation.

Finally, there is "childAlign", which is used on the <group> element to provide a default for the "align" value of each

control in the group. For instance, if you wanted all the controls of a group to be aligned along the bottom, it would be

easier to set the "ChildAlign" of the group to "bottom", rather than have to set each individual control's "align" property.

Differences Between Align (ChildAlign), and Justify

(this info is taken from a post by Ron Parker on the scripting list):

"Let's say you have a pile of blocks on a table. Let's pretend the table is the group, and the blocks are the controls.

Line the blocks up in a single row from left to right somewhere on the table. That means that the table is a horizontally-oriented group.

Now, childAlign tells you where the row is vertically on the table. It's either top, bottom, or center. If childAlign is top (the default) then all the blocks are arrayed along the top edge of the table. Moving one of those blocks to the bottom edge of the table, without moving it horizontally, would correspond to changing align to bottom for that control.

Justify tells you how the row is spaced out horizontally across the table. If the blocks are evenly spaced, it's full justification. If they're all bunched up at the left side, it's left, all bunched up at the right side is right, and all bunched up in the center is center."

(end of post); from another post:

"important distinction is this: right/left justification applies to horizontal groups, unlike right/left alignment. Similarly, top/bottom justification applies to vertical groups, and center justification again applies to both. Note that there's a sixth option for justification: "full". That says "if there's extra space in this group, split it up between all of the controls so that the leftmost control is at the left side of the group and the rightmost control is at the right side of the group and everything else is spread out evenly in between. (or the equivalent for vertically-oriented groups.)"

You'd likely use right justification for the OK/Cancel buttons in a standard Windows dialog, which are typically oriented in a horizontal group at the bottom right corner of the dialog."

(end of post)

If I can go back to the ruler analogy to attempt a summary: picture yourself laying a ruler vertically on the dialog; it's

your group. you lay a variety of coins on the ruler, from top to bottom; they're each different sizes. if you push all the

coins to the right, then their right edges are aligned in a straight vertical line; that's "align=right". you could also

align them on the left side, but whichever side you choose, the opposite side of your controls will have a ragged edge. that

is, if you push them to the right, their right edges will align in a straight line, but their left edges will be a ragged

line because they are different widths.

In this same ruler, you can push the coins up or down until you get them spaced the way you want. this is the "justify"

property at work. you can justify to the top, the bottom, in the center, or "full" (which will space them evenly from top to

bottom).


Visual Design Tips

At this point you may have an idea how groups effect the visual layout, but not such a good idea as to how to make use of

groups. What do you group together, and when? Some of the answers are functional: Use a group to surround a set of radio

buttons. If you have several pairs of static labels and editboxes, and they're related such as name, address line 1, address

line 2, city, state, and zip, then usually you will want to surround them with a group just so you can give that group a

title to inform the user, sighted or blind, the context of this group of controls and the information they represent.

Just as often however your group decisions, and especially your decisions for orientation, align, and justify properties will

be visual in nature. Here is where we could use the help of a sighted programmer or two, to provide some examples, rules,

and common conventions used when laying out dialogs. For instance, I believe the "ok" and "cancel" buttons found in most

dialogs, are usually placed in a group, oriented horizontally, justify right, aligned at the bottom, and placed in the bottom

right of the dialog.

there are other conventions; such as a name and address are usually presented in a vertical group, with the static label

placed to the left of each editbox. The static labels often have their right edges aligned, while the editboxes often have

their left edges aligned. The city state and zip edit boxes are usually all placed from left to right in a horizontal group

at the bottom.

Having a long list of such conventions is the only way I can think of to aid a blind programmer, who has never seen dialogs,

to understand what will yield pleasant looking visual displays.

It is reassuring to remember that if you use a good functional design for creating your groups and controls, the WE XML

dialog facility will give you an acceptible dialog, and sometimes a very good dialog, just by allowing it to use all of it's

automatic defaults for the various properties.

Non-Visual Design Tips

Just to be contrary, I will mention I've seen software, written by blind programmers and designed for blind users, which

followed acceptible practices for good visual design, and this yielded a dialog which was rather difficult for a screen

reader user to make use of. The dialog was something like a list of names from a database, in a listbox down the left half

of the dialog, and a series of editboxes in a group down the right half, which contained details about the currently

highlighted listbox choice. As the user went down the list using the arrow keys, he then would have to tab over and through

the listboxes to get the detail information, and then tab back to the listbox. Even the use of shortcut keys didn't make

this process much easier, but for a sighted user, it was a great dialog.

I think some thought needs to go into the needs of a screen reader user when designing a dialog. In this case, perhaps a

checkbox option which would cause the detail info to be spoken as each name was highlighted in the listbox. Or perhaps an

option to allow the user to choose which fields are to be placed in a listView control, along side of the name.

Using an XML Dialog

This is detailed well in the "designing custom user interfaces" topic of the App Developer Reference manual. It explains that you must use the "dialog" or "menu" method to cause the dialog or menu item to be initially displayed, and you must have written a function (known as a "callback"), which will be called each time the user presses a key in the dialog, and many other times simply because Windows has done something to the dialog (such as drawn it, moved it, expanded or shrunk it, etc.). It's your callback function which will do all the work needed for this dialog or menu; in this function you will test on what just happened (what the user did or what Windows just did), and decide if it's time for you to do something as a result.

The callback function will need to initialize the controls (possibly), to test on what control was involved when the user

interacts with one (and what happened to it), and then possibly do something (such as update other controls, or close the

dialog and act on it's info). It's also possible that your callback function (or handler) will be called, but there's

nothing it needs to do (Windows is just informing it that something unimportant to you has just happened).

As a general rule, using a dialog will take place in the following steps:

  • Use the "dialog" command (either as a command or as a function), to launch your dialog into life
  • In the callback function (the handler), create a test for the event type which looks for the event which tells you when the

dialog has been created; this event tells you that it's safe to initialize your controls, and it only occurs once, so it's

also a good marker for when it's the right time to initialize the controls. Your handler can be called by Windows before

this event occurs (for other reasons), but it is not safe to access the dialog or it's controls until this event has

occurred. Initializing the controls usually involves doing things such as loading a listbox with the appropriate values;

setting command buttons to be disabled until it's appropriate for them to be enabled (such as a "save" button, which should

not be enabled until the user has entered some data which can be saved), loading editboxes with strings, etc.

  • In the callback function (the handler), create a test which looks for the event which tells you when the

dialog has been closed; this event tells you that the user has done something such as click the close box

  • And finally, in the handler, test for event types which occur when each of your controls has been accessed (clicked, or

their selected item changed, etc.), for the ones where it's necessary for you to respond. This is likely to be at least your

"ok" and "cancel" buttons, if nothing else.


Launching a Dialog

It's briefly touched on in this help topic, but not explained, that you need to invoke the DIALOG or MENU method by using the

QUEUE method (called a timer in the help topic).

The DIALOG and MENU commands pause your app, at the point where they execute, and it stays paused at this point until the dialog closes. It's often inconvenient to have one of your subroutines or functions paused like this, but use of the "queue" method bypasses this by executing the dialog or menu command later, when your app isn't busy doing something. Even when your app is paused however, this does not prevent your event handlers, and your dialog or menu callback functions, from executing when they are called (or "fired").


Here's some example code from the help file to demonstrate how to use the QUEUE method to open a dialog:

Sub LaunchDialog()
       If isVisible = 0 Then
               Queue "DisplayDialog"
       End If
End Sub
Sub DisplayDialog()
isVisible = 1
Dialog "simon_says.xml", "simon_says", "DialogEventHandler"
' the pause happens here
End Sub

The dialog command above can also be used as a function; that is, it can return a variable of type "dialog object", and if this is stored in a global variable, it allows other parts of your script to interact with the dialog and it's controls; not just your dialog's handler. Such a launching might look like the routine below:

Sub DisplayDialog()
isVisible = 1
 Set myDlg = Dialog ("simon_says.xml", "simon_says", "DialogEventHandler")
End Sub


XML Dialog Tips

  • When using read-only edit boxes, be sure to set returns="no" in the editbox's XML options to allow the dialog's default button to function correctly (assuming a dialog has a default button) if enter is pressed while the read-only edit box has focus. The default for an edit box is returns is true, meaning that pressing enter in an edit box (even a read-only edit box) will pass the keystroke to the control, and therefore it will not trigger the default button.
  • Remember to set focus to an enabled control when disabling controls (i.e. don't leave a disabled control focused).

Examples

For some sample scripts whose purpose is primarily to demonstrate the use of the XML dialog facility, checkout

Fruit Basket by Jamal Mazrui, and

Mission Impossible by Jeff Weiss.



Text Size:
Decrease Text Size Increase Text Size

Personal tools

Powered by MediaWiki
Public Domain
© 2013 GW Micro, Inc. All Rights Reserved.
GW Micro, Inc.    725 Airport North Office Park    Fort Wayne, IN 46825
Ph: 260-489-3671 Fax: 260-489-2608    www.gwmicro.com    sales@gwmicro.com    support@gwmicro.com
Hours: M-F, 8a-5p, EDST