AAC-Pvoice

 view release on metacpan or  search on metacpan

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

package AAC::Pvoice::Input;
use strict;
use warnings;

use Wx qw(:everything);
use Wx::Perl::Carp;
BEGIN
{
    use Device::ParallelPort;
    if ($^O eq 'MSWin32')
    {
        require Device::ParallelPort::drv::win32;
    }
    else
    {
        require Device::ParallelPort::drv::parport;
    }
}
use Wx::Event qw(   EVT_TIMER
                    EVT_CHAR
                    EVT_MOUSE_EVENTS);
our $VERSION     = sprintf("%d.%02d", q$Revision: 1.12 $=~/(\d+)\.(\d+)/);

sub new
{
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self = {};
    bless $self, $class;
    $self->{window} = shift;

    # We get the configuration from the Windows registry
    # If it's not initialized, we provide some defaults
    $self->{window}->{config} = Wx::ConfigBase::Get || croak "Can't get Config";

    # Get the input-device
    # icon   = mouse left/right buttons
    # adremo = electric wheelchair adremo
    # keys   = keystrokes
    $self->{window}->{Device} = $self->{window}->{config}->Read('Device',    'icon');

    $self->{window}->{Interval}          = $self->{window}->{config}->ReadInt('Interval', 10);
    $self->{window}->{Buttons}           = $self->{window}->{config}->ReadInt('Buttons',   2);
    $self->{window}->{OneButtonInterval} = $self->{window}->{config}->ReadInt('OneButtonInterval',    2000);

    $self->_initmonitor if $self->{window}->{Device} eq 'adremo';
    $self->_initautoscan if $self->{window}->{config}->ReadInt('Buttons') == 1;
    $self->_initkeys;
    $self->_initicon;

    $self->StartMonitor if $self->{window}->{Device} eq 'adremo';
    $self->StartAutoscan if $self->{window}->{config}->ReadInt('Buttons') == 1;

    return $self;
}

sub newchild
{
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self = {};
    bless $self, $class;
    $self->{window} = shift;

    # We get the configuration from the Windows registry
    # If it's not initialized, we provide some defaults
    $self->{window}->{config} = Wx::ConfigBase::Get || croak "Can't get Config";

    # Get the input-device
    # icon   = mouse left/right buttons
    # adremo = electric wheelchair adremo
    # keys   = keystrokes
    $self->{window}->{Device} = $self->{window}->{config}->Read('Device',    'icon');

    $self->_initkeys;
    $self->_initicon;

    return $self;
}

sub _initkeys
{
    my $self = shift;
    EVT_CHAR($self->{window}, \&_keycontrol)
        if $self->{window}->{config}->Read('Device') eq 'keys';
}

sub _initicon
{
    my $self = shift;
    EVT_MOUSE_EVENTS($self->{window}, \&_iconcontrol)
        if $self->{window}->{config}->Read('Device') eq 'icon';
}

sub _initmonitor
{
    my $self = shift;
    # The event for the adremo device
    $self->{window}->{adremotimer} = Wx::Timer->new($self->{window},my $tid = Wx::NewId());
    EVT_TIMER($self->{window}, $tid, \&_monitorport);
}

sub _initautoscan
{
    my $self = shift;
    $self->{window}->{onebuttontimer} = Wx::Timer->new($self->{window},my $obtid = Wx::NewId());
    EVT_TIMER($self->{window}, $obtid, sub{my $self = shift; $self->{input}->{next}->() if $self->{input}->{next}});
}

sub StartMonitor
{
    my $self = shift;
    $self->{window}->{adremotimer}->Start($self->{window}->{Interval}, 0) # 0 is continuous
                                                if $self->{window}->{adremotimer};
}

sub QuitMonitor
{
    my $self = shift;
    # stop the timer for the port monitor
    $self->{window}->{adremotimer}->Stop() if  $self->{window}->{adremotimer} && $self->{window}->{adremotimer}->IsRunning;
}

sub StartAutoscan
{
    my $self = shift;
    $self->{window}->{onebuttontimer}->Start($self->{window}->{OneButtonInterval}, 0)  # 0 is continuous
                                                if $self->{window}->{onebuttontimer};
}

sub QuitAutoscan
{
    my $self = shift;
    $self->{window}->{onebuttontimer}->Stop() if  $self->{window}->{onebuttontimer} && $self->{window}->{onebuttontimer}->IsRunning;
}

sub PauseMonitor
{
    my $self = shift;
    my $bool = shift;
    return unless $self->{window}->{config}->Read('Device') eq 'adremo';
    $self->QuitMonitor if $bool;
    $self->StartMonitor unless $bool;
}

sub PauseAutoscan
{
    my $self = shift;
    my $bool = shift;
    return unless $self->{window}->{config}->ReadInt('Buttons') == 1;
    $self->QuitAutoscan if $bool;
    $self->StartAutoscan unless $bool;
}

sub Pause
{
    my $self = shift;
    $self->{pause} = shift;
}

sub GetDevice
{
    my $self = shift;
    return $self->{window}->{config}->Read('Device');
}

sub SetupMouse
{
    my $self = shift;
    my ($window, $subgetfocus, $subup, $sublosefocus) = @_;

    if ($self->{window}->{config}->Read('Device') eq 'mouse')
    {
        EVT_MOUSE_EVENTS($window, sub { my ($self, $event) = @_;
                                        &$subup         if $event->LeftUp;
                                        &$sublosefocus  if $event->Leaving;
                                        &$subgetfocus   if $event->Entering;
                                      });
    }


}

sub Next
{
    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
    }
    $self->{lastvalue} = 0 if not exists $self->{lastvalue};
    # if we detect a change...
    if ($curvalue != $self->{lastvalue})
    {
        unless ($curvalue & 0x40)
        {
            # 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;
}


1;

__END__

=head1 NAME

AAC::Pvoice::Input - A class that handles the input that controls a pVoice-like application

=head1 SYNOPSIS

  # this module will normally not be called directly. It's called from
  # AAC::Pvoice::Panel by default


 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.092 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )