view release on metacpan or search on metacpan
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
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)