AAC-Pvoice

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

    AAC::Pvoice::EditableRow now has some sensible defaults to prevent
    'Use of uninitialized value' warnings
    AAC::Pvoice::Input can now handle one button input

0.7 AAC::Pvoice::Input
        * now allows keyboard input
        * now allows direct mouseclicks on the buttons
    AAC::Pvoice::Panel
        * now uses a round cornered background and
        * no longer simply sets the background for the normal and
          selected state, but draws a round cornered border around
          the rows and buttons that are selected
        * finally got the screensizing correctly...no more weird
          calculating stuff...
    AAC::Pvoice::Bitmap
        * now produces round cornered bitmaps
    AAC::Pvoice::Row
        * no longer uses too large images (screensizing update)
    AAC::Pvoice::EditableRow
        * no longer uses too large images (screensizing update)

0.8 AAC::Pvoice::Input

lib/AAC/Pvoice.pm  view on Meta::CPAN

    push @$items, $cancel if $style & wxCANCEL;
	$d->Append(AAC::Pvoice::Row->new($d->{panel},          # parent
                                     scalar(@$items),      # max
                                     $items,               # items
                                     wxDefaultPosition,    # pos
                                     wxDefaultSize,
                                     $width,
                                     25,
                                     $d->{ITEMSPACING},
                                     $d->{backgroundcolour}),
                0); #selectable
	return $d->ShowModal();
}

=pod

=head1 NAME

AAC::Pvoice - Create GUI software for disabled people

=head1 SYNOPSIS

lib/AAC/Pvoice/Dialog.pm  view on Meta::CPAN


sub new
{
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    my ($x, $y) = ($self->GetClientSize->GetWidth,
                   $self->GetClientSize->GetHeight);

    $self->{margin}           = 10;
    $self->{ITEMSPACING}      = 4;
    $self->{selectionborder}  = 3;
    $self->{backgroundcolour} = Wx::Colour->new(220,220,220);
    $self->SetBackgroundColour(wxWHITE);

    $self->{panel} = AAC::Pvoice::Panel->new(   $self,                 # parent
                                                -1,                    # id
                                                [$self->{margin},
                                                 $self->{margin}],     # position
                                                [$x-2*$self->{margin},
                                                 $y-2*$self->{margin}],# size
                                                wxNO_3D|wxWANTS_CHARS,               # style
                                                1,                     # disabletextrow 
                                                $self->{ITEMSPACING},  # rowspacing
                                                $self->{selectionborder}, # selectionborderwidth
                                                1);                     # disabletitle
    
    $self->{panel}->BackgroundColour($self->{backgroundcolour});
    $self->WarpPointer($self->{margin}+1,$self->{margin}+1);
    $self->SetFocus();
    EVT_CLOSE($self, \&OnClose);
    return $self;
}

sub Append

lib/AAC/Pvoice/Input.pm  view on Meta::CPAN

{
    my $self = shift;
    my $sub = shift;
    $self->{next} = $sub;
}

sub Select
{
    my $self = shift;
    my $sub = shift;
    $self->{select} = $sub;
}

sub _keycontrol
{
    # BEWARE: $self is the window object this event belongs to
    my ($self, $event) = @_;
    return if $self->{pause};
    $self->{input}->{select}->() if ($event->GetKeyCode == $self->{config}->ReadInt('SelectKey', WXK_RETURN)) || (uc(chr($event->GetKeyCode)) eq uc(chr($self->{config}->ReadInt('SelectKey'))));
    $self->{input}->{next}->()   if (( ($event->GetKeyCode == $self->{config}->ReadInt('NextKey', WXK_SPACE)) ||
                                       (uc(chr($event->GetKeyCode)) eq uc(chr($self->{config}->ReadInt('NextKey'))))) and
                                     (not $self->{config}->ReadInt('Buttons') == 1));
}

sub _iconcontrol
{
    # BEWARE: $self is the window object this event belongs to
    my ($self, $event) = @_;
    return if $self->{pause};
    $self->{input}->{select}->() if $event->LeftUp;
    $self->{input}->{next}->()   if $event->RightUp &&
                                    not $self->{config}->ReadInt('Buttons') == 1;
}

#----------------------------------------------------------------------
# This sub is used to monitor the parallel port for the adremo device
sub _monitorport
{
    # BEWARE: $self is the wxWindow subclass the timer
    # belongs to!
    my ($self, $event) = @_;
    # do nothing if the device is not adremo or
    # if we're already running
    return if ($self->{monitorrun}                           || 
               (not $self->{input}->{next})                  || 
               (not $self->{input}->{select})                ||
               $self->{pause});
    # set the flag that we're checking the port
    $self->{monitorrun} = 1;
    $self->{pp} = Device::ParallelPort->new() if not $self->{pp};
    my $curvalue = $self->{pp}->get_status();
    if (not defined $curvalue)
    {
        # clear the flag that we're checking the port and return
        $self->{monitorrun} = 0;
        return

lib/AAC/Pvoice/Input.pm  view on Meta::CPAN

        {
            # if bit 6 is off it's a headmove to the right
            # which will indicate a Next() event unless we're in
            # one button mode
            $self->{input}->{next}->() unless $self->{config}->ReadInt('Buttons') == 1;
        }
        if ($curvalue & 0x80)
        {
            # if bit 7 is on (this bit is inverted), it's a headmove to the left
            # which will indicate a Select() event.
            $self->{input}->{select}->();
        }
    }
    # the current value becomes the last value
    $self->{lastvalue} = $curvalue if $curvalue;

    # clear the flag that we're checking the port
    $self->{monitorrun} = 0;
}


lib/AAC/Pvoice/Input.pm  view on Meta::CPAN

This constructor takes the window (AAC::Pvoice::Panel typically) on which
the events and timer will be called as a parameter.
If the configuration (read using Wx::ConfigBase::Get) has a key called
'Device' (which can be set to 'icon', 'keys' , 'mouse' or 'adremo') is set to 'adremo', it
will start polling the parallel port every x milliseconds, where x is the
value of the configuration key 'Interval'. This setting is only useful if you connect
an "Adremo" electrical wheelchair to the parallel port of your PC (for more
information see http://www.adremo.nl).
If the key 'Device' is set to 'icon' it will respond to the left and right
mouse button, and if it's set to 'keys' it will respond to the configuration
keys 'SelectKey' and 'NextKey' (which are the keyboard codes for the 'select'
and 'next' events respectively.

AAC::Pvoice::Input has the ability to operate with either one or two buttons.
If you want to use only one button, you need to set the configuration key "Buttons"
to 1, and it will automatically invoke the subroutine you pass to Next() 
at an interval of the value set in the configuration key OneButtonInterval (set in milliseconds).

The default for is to operate in two button mode, and if OneButtonInterval is not 
set, it will use a default of 2000 milliseconds if "Buttons"  is set to 1.

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

    $_[4] ||= wxTAB_TRAVERSAL;
    my $self = $class->SUPER::new(@_[0..4]);

    $self->SetBackgroundColour(wxWHITE);

    $self->{parent}         = $_[0];
    $self->{position}       = $_[2];
    $self->{size}           = $_[3];
    $self->{disabletextrow} = $_[5] || 0;
    $self->{itemspacing}    = $_[6] || 0;
    $self->{selectionborder}= $_[7] || int($self->{itemspacing}/2)||1;
    $self->{disabletitle}   = $_[8] || 0;
    $self->{tls} = Wx::FlexGridSizer->new(0,1);
    $self->{totalrows}   = 0;
    $self->{lastrow}     = 0;
    $self->{currentpage} = 0;
    $self->{unfinished}  = 1;
    
    $self->RoundCornerRadius(10);

    my ($x, $y);

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN


sub SetEditmode
{
    my $self = shift;
    $self->{editmode} = shift;
}

sub OnPaint
{
    my ($self, $event) = @_;
    $self->{setselection} = 1;
    my $dc = Wx::PaintDC->new($self);
    $self->SetBackgroundColour($self->{parent}->GetBackgroundColour);
    $self->DrawBackground($dc);
    if ($self->{rowcolumnscanning} && not $self->{editmode})
    {
	$dc = Wx::WindowDC->new($self->{selectedwindow}->GetParent);
	$self->DrawBorder($dc);
    }
    $event->Skip;
}

sub DrawBorder
{
    my $self = shift;
    my $dc = shift;
    my $window = $self->{selectedwindow};
    my ($x, $y) = $window->GetPositionXY;
    my $size = $window->GetSize;
    my ($xsize, $ysize) = ($size->GetWidth, $size->GetHeight);
    $dc->BeginDrawing;
    $dc->SetBrush(wxTRANSPARENT_BRUSH);
    $dc->SetPen(Wx::Pen->new($self->{setselection} ? $self->SelectColour :
			                         $self->BackgroundColour, $self->{selectionborder}, wxSOLID));
    $dc->DrawRoundedRectangle($x-($self->{itemspacing}/2-1), $y-($self->{itemspacing}/2-1), $xsize+($self->{itemspacing}/2+1), $ysize+($self->{itemspacing}/2+1), $self->RoundCornerRadius);
    $dc->EndDrawing;
}

sub SetSelectionBorder
{
    my $self = shift;
    $self->{selectedwindow} = shift;
    $self->{setselection} = 1;
    my $dc = Wx::WindowDC->new($self->{selectedwindow}->GetParent);
    $self->DrawBorder($dc);
}

sub SetNormalBorder
{
    my $self = shift;
    $self->{selectedwindow} = shift;
    $self->{setselection} = 0;
    my $dc = Wx::WindowDC->new($self->{selectedwindow}->GetParent);
    $self->DrawBorder($dc);
}

sub RoundCornerRadius
{
    my $self = shift;
    $self->{radius} = shift || $self->{radius};
    return $self->{radius};
}

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

sub lastrow
{
    my $self = shift;
    return $self->{lastrow};
}


sub SelectColour
{
    my $self = shift;
    $self->{selectcolour} = shift || $self->{selectcolour};
    return $self->{selectcolour};
}

sub BackgroundColour
{
    my $self = shift;
    $self->{backgroundcolour} = shift || $self->{backgroundcolour};
    return $self->{backgroundcolour};
}

sub DrawBackground

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

    $self->{titlefont} = shift || $self->{titlefont};
    return if not $self->{titlefont};
    $self->{title}->SetFont($self->{titlefont}) if $self->{title};
    return $self->{titlefont};
}

sub Append
{
    my $self = shift;
    my $row = shift;
    my $unselectable = shift;
    $self->{tls}->Add($row,                 # what to add
                      0,                    # unused
                      wxALIGN_CENTRE,       # style
                      0);                   # padding

    # setup the input event handling unless we're in editmode
    unless ($self->{editmode})
    {
	$row->{input} = AAC::Pvoice::Input->newchild($row);
	$row->{input}->Next(  sub{$self->Next});

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

	    $child->{input}->Select(sub{$self->Select});
	    if ((defined $row->{ids}->[$index]) && ($child->GetId == $row->{ids}->[$index]))
	    {
		my $action = $row->{actions}->[$index];
		$self->{input}->SetupMouse($child, sub{$self->SetSelectionBorder($child)}, $action, sub{$self->SetNormalBorder($child)});
		$index++;
	    }
	}
    }

    $self->{totalrows}++ if not $unselectable;
    $self->{lastrow}++;
    push @{$self->{rows}}, $row if not $unselectable;
    push @{$self->{unselectablerows}}, $row if $unselectable;
}

sub PauseInput
{
    my $self = shift;
    my $bool = shift;
    $self->{input}->PauseMonitor($bool);
    $self->{input}->PauseAutoscan($bool);
    $self->{input}->Pause($bool);
}

sub Clear
{
    my $self = shift;
    $self->{tls}->Remove($_) for (0..$self->{lastrow});
    foreach my $row (@{$self->{rows}})
    {
	$_->Destroy for $row->GetChildren();
	$row->Destroy
    }
    $_->Destroy for @{$self->{unselectablerows}};
    $self->{text}->Destroy if exists $self->{text};
    $self->{title}->Destroy if exists $self->{title};
    $self->{rows} = [];
    $self->{unselectablerows} = [];
    $self->SUPER::Clear();
    $self->{totalrows} = 0;
    $self->{lastrow} = 0;
    $self->Refresh;
}

sub Finalize
{
    my $self = shift;
    my $dc = Wx::WindowDC->new($self);

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

	$self->{text}->SetStyle(0, length($self->{text}->GetValue), $self->{ta});
	$self->{text}->Refresh(); # Added to test it on the Mercury...added text
				  # isn't visible there...
    }    
    $self->{title}->SetBackgroundColour($self->BackgroundColour) unless $self->{disabletitle};

    $self->{tls}->AddGrowableCol(0);
    $self->Layout;

    # Select the first row
    $self->{selectedrow} = 0;
    $self->{selecteditem} = 0;
    $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning} && not $self->{editmode};
    $self->{rowselection} = 1;
    $self->Refresh;
    $self->Update();
    $self->{unfinished} = 0;
}

sub Next
{
    my $self = shift;
    return if ($self->{editmode} || $self->{unfinished});
    $self->{input}->QuitAutoscan;
    if ($self->{rowselection})
    {
        $self->SetNormalBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning};
        if ($self->{selectedrow} < ($self->{totalrows}-1))
        {
            $self->{selectedrow}++;
        }
        else
        {
            $self->{selectedrow} = 0;
        }
        $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning};
    }
    else
    {
        $self->SetNormalBorder($self->{rows}->[$self->{selectedrow}]->{items}->[$self->{selecteditem}]) if $self->{rowcolumnscanning};
        if ($self->{selecteditem} < ($self->{rows}->[$self->{selectedrow}]->{totalitems}-1))
        {
            $self->{selecteditem}++;
        }
        else
        {
            $self->{selecteditem} = 0;
        }
        $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]->{items}->[$self->{selecteditem}]) if $self->{rowcolumnscanning};
    }
    $self->{input}->StartAutoscan;
}

sub Select
{
    my $self = shift;
    return if $self->{editmode};
    $self->{input}->QuitAutoscan;
    if (($self->{rowselection}) &&  (@{$self->{rows}->[$self->{selectedrow}]->{items}} == 1))
    {
	$self->{rowselection} = 0;
	$self->{selecteditem} = 0;
    }
    if ($self->{rowselection})
    {
        $self->SetNormalBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning};
        $self->{rowselection} = 0;
        $self->{selecteditem} = 0;
        $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]->{items}->[$self->{selecteditem}]) if $self->{rowcolumnscanning};
    }
    else
    {
        $self->SetNormalBorder($self->{rows}->[$self->{selectedrow}]->{items}->[$self->{selecteditem}]) if $self->{rowcolumnscanning};
        $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning};

        &{$self->{rows}->[$self->{selectedrow}]->{actions}->[$self->{selecteditem}]};
        $self->{rowselection} = 1;
    }
    $self->{input}->StartAutoscan;
}

sub ToRowSelection
{
    my $self = shift;
	return if $self->{editmode};
    $self->SetNormalBorder($self->{rows}->[$self->{selectedrow}]->{items}->[$self->{selecteditem}]) if $self->{rowcolumnscanning};
    $self->SetSelectionBorder($self->{rows}->[$self->{selectedrow}]) if $self->{rowcolumnscanning};
    $self->{rowselection} = 1;
}

sub DisplayAddText
{
    my $self = shift;
    push @{$self->{displaytextsave}}, $_[0];
    $self->{text}->AppendText($_[0]);
    $self->{text}->Refresh(); # Added to test it on the Mercury...added text
                              # isn't visible there...
}

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN

  use AAC::Pvoice::Panel;



=head1 DESCRIPTION



=head1 USAGE

=head2 new(parent, id, size, position, style, disabletextrow, itemspacing, selectionborderwidth, disabletitle)

This is the constructor for a new AAC::Pvoice::Panel. The first 5 parameters are
equal to the parameters for a normal Wx::Panel, see the wxPerl documentation
for those parameters.

=over 4

=item disabletextrow

This is s a boolean (1 or 0), which determines
if the text-input field at the bottom of the screen should be hidden or
not. Normally this inputfield will be shown (for an application like pVoice
this is normal, because that will contain the text the user is writing),
but for an application like pMusic this row is not nessecary, so it can be
disabled.

=item itemspacing

This is the spacing used between the rows that are appended.

=item selectionborderwidth

This is the width of the border around a selected row or a selected item.

=item disabletitle

This is also a boolean (1 or 0), which determines if the panel should
reserve space for a title. If disabletitle is set to 1, AddTitle won't have
any effect at all.

=back

=head2 SetEditmode($onoff)

lib/AAC/Pvoice/Panel.pm  view on Meta::CPAN


This returns the x-size of the panel in pixels.

=head2 ysize

This returns the y-size of the panel in pixels.

=head2 RoundCornerRadius

This sets the radius for the round corners that are used to draw the panel
background and to draw the selectionborder around rows and buttons.

=head2 lastrow

This retrieves the index of the last row that was added to the panel.

=head2 SelectColour(Wx::Colour)

This gets or sets the colour that indicates a selected row or selected item. It
takes a Wx::Colour (or a predefined colour constant) as a parameter.

=head2 BackgroundColour(Wx::Colour)

This gets or sets the normal backgroundcolour. It
takes a Wx::Colour (or a predefined colour constant) as a parameter.

=head2 AddTitle(title)

This method sets the title of the page and draws it on the AAC::Pvoice::Panel.
By default it uses the Comic Sans MS font at a size of 18pt. You can change
this using TitleFont.

=head2 TitleFont(Wx::Font)

This method gets or sets the Wx::Font used to write the Title.

=head2 Append(row, unselectable)

This method adds a row (AAC::Pvoice::Row or any subclass of Wx::Window) to
the panel. If this row shouldn't be selectable by the user, you should set
unselectable to 1. Omitting this parameter, or setting it to 0 makes the
row selectable.

=head2 Clear

This method clears the panel completely and destroys all objects on it.

=head2 Finalize

This method 'finalizes' the panel by creating the textinput row (if appliccable)
and setting up the selection of the first row. You always need to call
this method before being able to let the user interact with the pVoice panel.

=head2 Next

This method normally won't be called directly. It will highlight the 'next'
row (when we're in 'rowselection') or the next item inside a row (when
we're in 'columnselection')

=head2 Select

This method normally won't be called directly either. It will either 'select'
the row that is highlighted and thus go into columnselection, or, when we're
in columnselection, invoke the callback associated with that item and
go into rowselection again.

=head2 ToRowSelection

This method will remove the highlighting of an item (if nessecary) and highlight
the entire current row again and set rowselection back on.

=head2 DisplayAddText(text)

In pVoice-like applications there's a difference between 'displaytext' (which is
the text that the user actually is writing and which should be displayed on the
textrow) and the speech (phonetical) text (which is not displayed, but -if nessecary-
differs from the text as we would write it, so a speechsynthesizer sounds
better.

This method adds text to the displaytext. It is saved internally and displayed

lib/AAC/Pvoice/Row.pm  view on Meta::CPAN

}

1;

__END__

=pod

=head1 NAME

AAC::Pvoice::Row - A row of selectable items

=head1 SYNOPSIS

  use AAC::Pvoice::Row;
  use Wx;
  
  my $panel = Wx::Panel->new($self, -1);
  my $items = [ [Wx::NewId, $SomeWxBitmap,      sub{ print "do something useful here"} ],
                [Wx::NewId, $SomeOtherWxBitmap, sub{ print "do something else here"} ]];
		

lib/AAC/Pvoice/Row.pm  view on Meta::CPAN

                                  wxDefaultPosition,# pos
                                  wxDefaultSize,    # size
                                  50,		    # maxX
                                  75,               # maxY
                                  5,                # spacing
                                  wxWHITE)          # background colour

=head1 DESCRIPTION

AAC::Pvoice::Row is a subclass of Wx::Panel. It will typically be placed
on an AAC::Pvoice::Panel, and contains selectable Wx::Bitmap-s, which,
when selected, will invoke a callback.

=head1 USAGE

=head 2 new(parent, maxitems, items, position, size, maxX, maxY, spacing, backgroundcolour)

This constructor is the only overridden function in AAC::Pvoice::Row. It
takes quite a number of parameters

=over 4

=item parent

The parent on which this row will be placed. Typically you'll be using an
instance of AAC::Pvoice::Panel for this, but it can be any Wx::Window
subclass

=item maxitems

The maximum number of items (images) in this row. If the supplied number
of items (next parameter) is lower than maxitems, the row will be filled up
with (unselectable) WxNullBitmap-s.

=item items

This parameter is a reference to a list of lists. Each item in the listref
contains three items: a unique id, a Wx::Bitmap (or AAC::Pvoice::Bitmap for
that matter), and a callback that will be invoked when the item is selected.

=item position

This parameter is passed on to the SUPER's constructor directly. See the
documentation for Wx::Panel.

=item size

This parameter is passed on to the SUPER's constructor directly. See the
documentation for Wx::Panel.



( run in 0.684 second using v1.01-cache-2.11-cpan-49f99fa48dc )