Sign In/My Account | View Cart  
advertisement


Listen Print

Accessible Software

by Jouke Visser
July 15, 2004

Last year Perl.com published an article about pVoice. You learned what pVoice is, why it was built, and where it was supposed to go. Maybe you wanted to do something for disabled people yourself, by writing something like a mail client, a simple game like memory, or an instant-messaging client, but you didn't implement it because you felt it was too much work. In that case there's news for you.

Part of pVoice was a set of modules that was actually the engine for the user interface. A few months ago I pulled those modules from the pVoice project and made them into a CPAN distribution. This distribution is called AAC::Pvoice. And no, they have nothing to do with Apple's digital audio format. They're all about Augmentative and Alternative Communication. Although, I like to think that the "C" stands for "Computing," which makes it into a better description of what those modules are for.

You can use the AAC::Pvoice modules to create GUI applications for people who have difficulty using conventional input devices like a mouse or a keyboard. Instead, those people can use your applications using only one or two keystrokes, mouse buttons, or switches on a wheelchair. You can also enhance the use of a conventional mouse or touch screen by highlighting objects on the screen as the mouse cursor hovers over them. AAC::Pvoice does not only handle the input for you, but it also provides an accessible graphical user interface.

Think of the possibilities: there are so many modules on CPAN that in conjunction with AAC::Pvoice can result in simple, accessible applications. For example, a module like Games::Battleship allows you to create a battleship game, AAC::Pvoice allows you to create the GUI and takes care of the input for you, so with very little effort you can create a game accessible for people who can't play regular games that need full control over a mouse and/or keyboard.

This article will explain how to use the AAC::Pvoice modules step by step. It's up to you what kind of functionality will go into the application you build.

The API of the AAC::Pvoice modules is still subject to changes, but you can trust me when I tell you that the behavior of existing methods won't change too much, because I don't like to go over my own code over and over again to adjust it to a new version of an API.

The Concept

The graphical user interface of AAC::Pvoice is based upon wxPerl classes, so it won't hurt if you already know a bit about wxPerl. But since the modules handle most of the GUI for you, as you can see below, it's much simpler to write AAC::Pvoice applications than using plain wxPerl.

Basically an AAC::Pvoice-based application consists of three entities: a Panel, a Row and a Button. A panel is a subclass of a Wx::Panel, on which one or more rows, or in fact any other Wx::Window subclass, can be placed. A row is also a subclass of a Wx::Panel, but a row can contain multiple Wx::BitmapButton objects. Those Wx::BitmapButtons however are created from a data structure you feed to the row's constructor. These buttons don't respond to mouse clicks on them like you're used to, but will be invoked when the user generates a 'Select' event, unless of course you use a normal mouse to control the GUI. The 'Select' event will be discussed later.

Related Reading

Learning Perl Objects, References, and Modules
By Randal L. Schwartz

There is a special class called AAC::Pvoice::Input. You normally won't call any of this class' methods directly. Instead, it's called from the AAC::Pvoice::Panel. The Input class checks for 'normal' mouse, mouse buttons, keyboard or parallel port input (depending on the selected device) and calls whatever the Panel defined it to do when a 'Next' or 'Select' event occurs. If only one switch is used, that switch will only generate a 'Select' event, and a 'Next' event will automatically happen every n milliseconds, depending on your settings. To understand what those events are, you need to understand how the so called 'row/column scanning' mechanism works. Since we've got multiple rows of buttons, and we have only two switches to indicate what we want to do, we can't move the mouse cursor over the screen. Instead, we'll use one switch to indicate 'go to next row' and one to indicate 'select this row'. When we've selected a row, again we need the same two switches to indicate 'go to next button in this row' and 'select this button'.

As you will see in the demo application below, you don't have to worry about row/column scanning when you're creating your application. The AAC::Pvoice::Panel takes care of that. You only have to define what your script will do when a certain button is invoked.

Creating a Demo

To demonstrate how you can use AAC::Pvoice to create your own pVoice-like applications, I'll show you how to build a simple demo application. This application will use the Microsoft Agent (using the Win32::MSAgent module) to move the Merlin character over the screen and let it pronounce a phrase. It's a very simple, silly example, but then again, it's only to demonstrate how the AAC::Pvoice modules work. You'll see how easy it is.

First of all, because an AAC::Pvoice based application is actually a wxPerl-based application, we have to start with a standard wxPerl framework, where we define the application and the frame, and start a main loop. This can be something like this:


use strict;
use warnings;

# Create a wxApp object and start the mainloop
my $obj = pMerlin->new();
$obj->MainLoop;

#----------------------------------------------------------------------
# the pMerlin package implements the Wx::App subclass
package pMerlin;
use Wx;
use base 'Wx::App';

sub OnInit
{
    my $self = shift;
    # Set an AppName and VendorName
    $self->SetAppName('Fun With Merlin');
    $self->SetVendorName("pVoice Applications - Jouke Visser");
    
    # Create a frame and show it
    my $frame = pMerlinFrame->new( undef, -1, 'pMerlin');
    $frame->Show(1);
}

#----------------------------------------------------------------------
# the pMerlinFrame package implements the Wx::Frame subclass
package pMerlinFrame;
use Wx qw(:everything);
use AAC::Pvoice;
use base 'Wx::Frame';

sub new
{
    my $class = shift;
    # Call the superclass' constructor
    my $self = $class->SUPER::new(@_);
    
    # Set the white background colour
    $self->SetBackgroundColour(wxWHITE);
    
    return $self;
}

So far, nothing special. I only used a few calls that aren't really necessary for a default wxPerl script: I'm setting the AppName, VendorName, and I'm telling the frame to have a white background. The reason for setting the AppName and VendorName will be explained later.

Pages: 1, 2

Next Pagearrow