AAC-Pvoice

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Perl module AAC::Pvoice

0.1 First version

0.2 0.1 didn't arrive on PAUSE correctly

0.3 minor documentation update in AAC::Pvoice::Bitmap

0.4 correction in AAC::Pvoice::Input to read individual bits
    instead of the whole statusbyte from the parallel port

0.5 AAC::Pvoice::Input now no longer uses Win32::API. Now it uses
    Device::ParallelPort, so it should be able to run on Linux now too.

0.6 AAC::Pvoice::Bitmap now returns a wxNullBitmap if the resize-factor
    is 0 to prevent 'illegal division by zero'
    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
        * when keystrokes are used, alpha keys are now case-insensitive
    Several bugfixes and therefore needed new methods (for most of you
    probably not that important)

0.9 AAC::Pvoice::Bitmap
        * We now use Image::Magick to create the bitmaps. It's a change to
          the internals, so the methods and their parameters stay the same.
        * Returned images are cached first (using File::Cache). If an image
          has been processed before, it will be retrieved from the cache.
          The cache never expires, but every combination of parameters
          results in a new cached image (and of course the file modificationtime
          of the image is also taken into account.
    AAC::Pvoice::Dialog
        * This is a newly added class. It's a subclass of Wx::Dialog and
          allows you to create dialog boxes, using an AAC::Pvoice::Panel
    AAC::Pvoice
        * This module now provides the AAC::Pvoice::MessageBox function,
          similar to Wx::MessageBox.
0.91 AAC::Pvoice
        * Made a little more space between the text and the buttons in the MessageBox
          function
     AAC::Pvoice::Bitmap
        * Minor changes
     AAC::Pvoice::Panel
        * ability to return the array of added texts from RetrieveText and SpeechRetrieveText
        and made accompanying changes in other methods.

MANIFEST  view on Meta::CPAN

MANIFEST
LICENSE
README
Todo
Changes
lib/AAC/Pvoice.pm
lib/AAC/Pvoice/Bitmap.pm
lib/AAC/Pvoice/Input.pm
lib/AAC/Pvoice/Panel.pm
lib/AAC/Pvoice/Row.pm
lib/AAC/Pvoice/EditableRow.pm
lib/AAC/Pvoice/Dialog.pm
t/001_load.t
Makefile.PL
META.yml

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

package AAC::Pvoice;

use strict;
use warnings;

use Wx qw(:everything);
use Wx::Perl::Carp;
use AAC::Pvoice::Bitmap;
use AAC::Pvoice::Input;
use AAC::Pvoice::Row;
use AAC::Pvoice::EditableRow;
use AAC::Pvoice::Panel;
use AAC::Pvoice::Dialog;
use Text::Wrap qw(wrap);

BEGIN {
	use Exporter ();
	use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

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

	$messagectrl->SetBackgroundColour($d->{backgroundcolour});
	$messagectrl->SetFont(Wx::Font->new(10,                 # font size
                                        wxDECORATIVE,       # font family
                                        wxNORMAL,           # style
                                        wxNORMAL,           # weight
                                        0,                  
                                        'Comic Sans MS',    # face name
                                        wxFONTENCODING_SYSTEM));

	$d->Append($messagectrl,1);
    my $ok     = [Wx::NewId,AAC::Pvoice::Bitmap->new('',50,25,'OK',    Wx::Colour->new(255, 230, 230)),sub{$d->SetReturnCode(wxOK);    $d->Close()}];
    my $yes    = [Wx::NewId,AAC::Pvoice::Bitmap->new('',50,30,'Yes',   Wx::Colour->new(255, 230, 230)),sub{$d->SetReturnCode(wxYES);   $d->Close()}];
    my $no     = [Wx::NewId,AAC::Pvoice::Bitmap->new('',50,25,'No',    Wx::Colour->new(255, 230, 230)),sub{$d->SetReturnCode(wxNO);    $d->Close()}];
    my $cancel = [Wx::NewId,AAC::Pvoice::Bitmap->new('',50,60,'Cancel',Wx::Colour->new(255, 230, 230)),sub{$d->SetReturnCode(wxCANCEL);$d->Close()}];
    my $items = [];
    push @$items, $ok     if $style & wxOK;
    push @$items, $yes    if $style & wxYES_NO;
    push @$items, $no     if $style & wxYES_NO;
    push @$items, $cancel if $style & wxCANCEL;
	$d->Append(AAC::Pvoice::Row->new($d->{panel},          # parent
                                     scalar(@$items),      # max
                                     $items,               # items
                                     wxDefaultPosition,    # pos
                                     wxDefaultSize,

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


This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the
LICENSE file included with this module.


=head1 SEE ALSO

perl(1), Wx, AAC::Pvoice::Panel, AAC::Pvoice::Bitmap, AAC::Pvoice::Row
AAC::Pvoice::EditableRow, AAC::Pvoice::Input

=cut


1; 
__END__

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

package AAC::Pvoice::Bitmap;

use strict;
use warnings;
use Wx qw(:everything);
use Wx::Perl::Carp;
use Image::Magick;
use IO::Scalar;
use File::Cache;
use File::stat;
use File::Temp qw( :POSIX );

our $VERSION     = sprintf("%d.%02d", q$Revision: 1.12 $=~/(\d+)\.(\d+)/);

use base qw(Wx::Bitmap);
our $cache;
BEGIN
{
    Wx::InitAllImageHandlers;
    $cache = File::Cache->new({namespace => 'images'});
}

#----------------------------------------------------------------------
sub new
{

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

                                        0,                  
                                        'Comic Sans MS',    # face name
                                        wxFONTENCODING_SYSTEM);
                ($cw, $ch, undef, undef) = $capdc->GetTextExtent($caption, $cfont);
                $cpt--;
            } until ($cw<$x);
        }
        my $img = Wx::Image->new($x, $y-$ch);
        $img->SetOption('quality', 100);
        my $rc = $img->LoadFile($file, wxBITMAP_TYPE_ANY);
        return wxNullBitmap if not $rc;
        my ($w,$h) = ($img->GetWidth, $img->GetHeight);
        if (($w > $x) || ($h > ($y-$ch)))
        {
            my ($newx, $newy) = ($w, $h);
            if ($w > $x)
            {
                my $factor = $w/$x;
                return wxNullBitmap if not $factor;
                $newy = int($h/$factor);
                ($w,$h) = ($x, $newy);
            }
            if ($h > ($y-$ch))
            {
                my $factor = $h/($y-$ch);
                return wxNullBitmap if not $factor;
                ($w, $h) = (int($w/$factor),$y-$ch);
            }
            $img = $img->Scale($w, $h);
        }
        elsif ($blowup)
        {
            # Do we really want to blow up images that are too small??
            my $factor = $w/$x;
            return wxNullBitmap if not $factor;
            my $newy = int($h/$factor);
            ($w,$h) = ($x, $newy);
            if ($h > ($y-$ch))
            {
                my $factor = $h/($y-$ch);
                return wxNullBitmap if not $factor;
                ($w, $h) = (int($w/$factor),$y-$ch);
            }
            $img = $img->Scale($w, $h);
        }
        my $bmp = Wx::Bitmap->new($img);
        my $newbmp = Wx::Bitmap->new($x, $y);
        my $tmpdc = Wx::MemoryDC->new();
        $tmpdc->SelectObject($newbmp);
    
        my $bgbr = Wx::Brush->new($parent_background, wxSOLID);
        $tmpdc->SetBrush($bgbr); 
        $tmpdc->SetBackground($bgbr);
        $tmpdc->Clear();
    
        my $bg = $parent_background;
        if (defined $background)

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

            }
            my $br = Wx::Brush->new($bg, wxSOLID);
            my $pen = Wx::Pen->new($bg, 1, wxSOLID);
            $tmpdc->SetBrush($br);
            $tmpdc->SetPen($pen);
            $tmpdc->DrawRoundedRectangle(1,1,$x-1,$y-1, 10);
        }
    
        my $msk = Wx::Mask->new($bmp, Wx::Colour->new(255,255,255));
        $bmp->SetMask($msk);
        $tmpdc->DrawBitmap($bmp, int(($x - $bmp->GetWidth())/2), int(($y-$ch-$bmp->GetHeight())/2), 1);
    
        if ($caption)
        {
            $tmpdc->SetTextBackground($bg);
            $tmpdc->SetTextForeground(wxBLACK);
            $tmpdc->SetFont($cfont);
            $tmpdc->DrawText($caption, int(($x-$cw)/2),$y-$ch);
        }
        my $tmpfile = File::Temp::tmpnam();
    	$newbmp->SaveFile($tmpfile, wxBITMAP_TYPE_PNG);

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

        open(my $fh, "<$tmpfile");
        binmode($fh);
        my $image = <$fh>;
        close($fh);
    	$cache->set("$file-$x-$y-$caption-$ibg-$blowup-$pbg-$mtime", $image);	
    }
    
    my $fh = IO::Scalar->new(\$image); 	 

    my $contenttype = 'image/png'; 
    return Wx::Bitmap->new(Wx::Image->newStreamMIME($fh,  $contenttype)) 
}

sub wxColor2hex
{
    my $color = shift;
    my $red   = $color->Red();
    my $green = $color->Green();
    my $blue  = $color->Blue();
    return sprintf("#%0x%0x%0x", $red,$green,$blue);
}

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

    	$img->Transparent(color => 'white') if (!$img->Get('matte') || $file =~ /wmf$/i);
    	my $w = $img->Get('width');
    	my $h = $img->Get('height');
    	my $ch = $textheight;
    	if (($w > $x) || ($h > ($y-$ch)))
    	{
    	    my ($newx, $newy) = ($w, $h);
    	    if ($w > $x)
    	    {
    		my $factor = $w/$x;
    		return wxNullBitmap if not $factor;
    		$newy = int($h/$factor);
    		($w,$h) = ($x, $newy);
    	    }
    	    if ($h > ($y-$ch))
    	    {
    		my $factor = $h/($y-$ch);
    		return wxNullBitmap if not $factor;
    		($w, $h) = (int($w/$factor),$y-$ch);
    	    }
    	    $img->Thumbnail(height => $h, width =>$w );
    	}
    	elsif ($blowup)
    	{
    	    # Do we really want to blow up images that are too small??
    	    my $factor = $w/$x;
    	    return wxNullBitmap if not $factor;
    	    my $newy = int($h/$factor);
    	    ($w,$h) = ($x, $newy);
    	    if ($h > ($y-$ch))
    	    {
    		my $factor = $h/($y-$ch);
    		return wxNullBitmap if not $factor;
    		($w, $h) = (int($w/$factor),$y-$ch);
    	    }
    	    $img->Resize(height => $h, width =>$w );
    	}
        
    	$img->Border(width  => int(($x - $img->Get('width'))/2) - $radius/2,
    		      height => int((($y-$textheight) - $img->Get('height'))/2) - $radius/2,
    		      fill   => $ibg);
    	
    	# Call the Composite method of the background image, with the logo image as an argument.

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

    	$background->Set(magick => 'png');
    	$image = $background->imagetoblob();
    	$cache->set("$file-$x-$y-$caption-$ibg-$blowup-$pbg-$mtime", $image);	
    	undef $background;
    	undef $img;
    }
    
    my $fh = IO::Scalar->new(\$image); 	 

    my $contenttype = 'image/png'; 
    return Wx::Bitmap->new(Wx::Image->newStreamMIME($fh,  $contenttype)) 
}

END
{
    undef $cache;
}

sub DrawCaption
{
    my ($x, $y, $caption, $background, $parent_background) = @_;

    confess "MaxX and MaxY should be positive" if $x < 1 || $y < 1;
    
    my $newbmp = Wx::Bitmap->new($x, $y);
    my $tmpdc = Wx::MemoryDC->new();
    $tmpdc->SelectObject($newbmp);

    my $bgbr = Wx::Brush->new($parent_background, wxSOLID);
    $tmpdc->SetBrush($bgbr); 
    $tmpdc->SetBackground($bgbr);
    $tmpdc->Clear();

    my $bg = $parent_background;
    if (defined $background)

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

}

1;

__END__

=pod

=head1 NAME

AAC::Pvoice::Bitmap - Easily create resized bitmaps with options

=head1 SYNOPSIS

  use AAC::Pvoice::Bitmap;
  my $bitmap = AAC::Pvoice::Bitmap->new('image.jpg',        #image
                                        100,                #maxX
					100,                #maxY
					'This is my image', #caption
					wxWHITE,            #background
					1);                 #blowup?

=head1 DESCRIPTION

This module is a simpler interface to the Wx::Bitmap to do things with
images that I tend to do with almost every image I use in pVoice applications.

It's a subclass of Wx::Bitmap, so you can call any method that a Wx::Bitmap
can handle on the resulting AAC::Pvoice::Bitmap.

=head1 USAGE

=head2 new(image, maxX, maxY, caption, background, blowup, parentbackground)

This constructor returns a bitmap (useable as a normal Wx::Bitmap), that
has a size of maxX x maxY, the image drawn into it as large as possible.
If blowup has a true value, it will enlarge the image to try and match
the maxX and maxY. Any space not filled by the image will be the
specified background colour. A caption can be specified to draw under the
image.

If the image doesn't exist, it will draw a large questionmark and warn
the user.

=over 4

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

(i.e. wxWHITE) or as an arrayref of RGB colours (like [128,150,201] ).

=item blowup

This boolean parameter determines whether or not images that are smaller
than maxX and maxY should be blown up to be as large as possible within
the given maxX and maxY.

=item parentbackground

This is the background of the parent of this bitmap, which is the colour to
be used outside of the round cornered background.

=back

=head1 BUGS

probably a lot, patches welcome!


=head1 AUTHOR

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

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

use Wx qw(:everything);
use Wx::Perl::Carp;
use Wx::Event qw(   EVT_BUTTON );
use AAC::Pvoice::Bitmap;
use base qw(Wx::Panel);

our $VERSION     = sprintf("%d.%02d", q$Revision: 1.4 $=~/(\d+)\.(\d+)/);

#----------------------------------------------------------------------
sub new
{
    my $class = shift;
    my ($parent,$maxitems,$items,$wxPos,$wxSize, $itemmaxX, $itemmaxY, $itemspacing, $background, $style,$name) = @_;
    $wxPos ||= wxDefaultPosition;

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

    my $sizer = Wx::GridSizer->new(1,0);
    $self->{items} = [];
    $self->{actions} = [];

    my ($maxX, $maxY) = ($itemmaxX, $itemmaxY);

    # Add the defined keys for this row
    for (@$items)
    {
        my ($id, $img, $sub) = @$_;
        my $button = Wx::BitmapButton->new
                                    ($self,             # parent
                                     $id,               # id
                                     $img,              # image
                                     wxDefaultPosition, # position
                                     [$maxX+3, $maxY+3],     	# size
                                     wxBU_AUTODRAW);  # style
        $button->SetBackgroundColour($background);
        $sizer->Add($button, 0, wxALIGN_CENTRE|wxALL, $self->{itemspacing});
        push @{$self->{items}}, $button;
	EVT_BUTTON($self, $id, $sub);

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

keycode set in the 'SelectKey', this will generate a 'Select' event too.

=head2 GetDevice

This method will return the value of the configuration key called 'Device'

=head2 SetupMouse($window, $subgetfocus, $subup, $sublosefocus)

This method is used to setup a button for normal mouse input (when
configuration key 'Device' is set to 'mouse'). It takes the wxWindow
(typically a Wx::BitmapButton) that should respond to this way of
input as the first parameter.
$subgetfocus is the coderef that should be invoked when the mousecursor
hovers over this $window (EVT_ENTER).
$subup is the coderef that should be invoked when the left mousebutton
is released (EVT_LEFT_UP).
$sublosefocus is the coderef that should be invoked when the $window
loses focus (EVT_LEAVE).

=head2 StartMonitor

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

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

use Wx qw(:everything);
use Wx::Perl::Carp;
use AAC::Pvoice::Bitmap;
use base qw(Wx::Panel);

our $VERSION     = sprintf("%d.%02d", q$Revision: 1.5 $=~/(\d+)\.(\d+)/);
#----------------------------------------------------------------------
sub new
{
    my $class = shift;
    my ($parent,$maxitems,$items,
		$wxPos,$wxSize, $itemmaxX, $itemmaxY,
		$itemspacing, $background, $style,$name) = @_;

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

    $self->{items}   = [];
    $self->{actions} = [];
    
    my ($maxX, $maxY) = ($itemmaxX, $itemmaxY);

    # Add the defined keys for this row
    for (@$items)
    {
    	if (not defined $_)
    	{
            my $empty = Wx::BitmapButton->new(  $self, 
                                                Wx::NewId, 
                                                wxNullBitmap, 
                                                wxDefaultPosition, 
                                                [$maxX, $maxY],
                                                wxSUNKEN_BORDER);
            $empty->SetBackgroundColour($background);
    	    $sizer->Add($empty,0, wxALIGN_CENTRE|wxALL, $itemspacing);
            next;
    	}
        my ($id, $img, $sub) = @$_;
        my $button = Wx::BitmapButton->new ($self,             # parent
					    $id,               # id
					    $img,              # image
					    wxDefaultPosition, # position
					    [$maxX, $maxY],# size
					    wxSUNKEN_BORDER);  # style
        $button->SetBackgroundColour($background);
        $sizer->Add($button, 0, wxALIGN_CENTRE|wxALL, $itemspacing);
        push @{$self->{items}}, $button;
        push @{$self->{actions}}, $sub;
        push @{$self->{ids}}, $id;
    }
    my $totalitems = scalar(@$items);
    $self->{totalitems} = scalar(@{$self->{items}});
    for (0..($self->{maxitems} - $totalitems -1))
    {
	my $empty = Wx::BitmapButton->new(  $self, 
					    Wx::NewId, 
					    wxNullBitmap, 
					    wxDefaultPosition, 
					    [$maxX, $maxY],
					    wxSUNKEN_BORDER);
	$empty->SetBackgroundColour($background);
	$sizer->Add($empty,0, wxALIGN_CENTRE|wxALL, $itemspacing);
    }
    $self->SetBackgroundColour($background);
    $self->SetSizer($sizer);
    $self->SetAutoLayout(1);
    $sizer->Fit($self);

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

=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"} ]];
		
  my $row = AAC::Pvoice::Row->new($panel,           # parent
                                  scalar(@$items),  # max
                                  $items,           # items
                                  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

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

=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.

=item maxX

This is the maximum X size in pixels for an item (a Bitmap) in this row

=item maxY

This is the maximum Y size in pixels for an item (a Bitmap) in this row

=item spacing

This is the spacing between the items in pixels in this row

=item backgroundcolour

This is the backgroundcolour of the panel, defined as a Wx::Colour, or one
of the constants defined by Wx (like wxWHITE)



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