App-Asciio
view release on metacpan or search on metacpan
lib/App/Asciio/GTK/Asciio.pm view on Meta::CPAN
#-----------------------------------------------------------------------------
=head1 NAME
=cut
sub new
{
my ($class, $width, $height) = @_ ;
my $self = App::Asciio::new($class) ;
bless $self, $class ;
$self->{KEYS}{K} = {%Gtk2::Gdk::Keysyms} ;
$self->{KEYS}{C}= {map{$self ->{KEYS}{K}{$_} => $_} keys %{$self->{KEYS}{K}}} ;
my $drawing_area = Gtk2::DrawingArea->new;
$self->{widget} = $drawing_area ;
$drawing_area->can_focus(TRUE) ;
$drawing_area->signal_connect(configure_event => \&configure_event, $self);
$drawing_area->signal_connect(expose_event => \&expose_event, $self);
$drawing_area->signal_connect(motion_notify_event => \&motion_notify_event, $self);
$drawing_area->signal_connect(button_press_event => \&button_press_event, $self);
$drawing_area->signal_connect(button_release_event => \&button_release_event, $self);
$drawing_area->signal_connect(key_press_event => \&key_press_event, $self);
$drawing_area->set_events
([qw/
exposure-mask
leave-notify-mask
button-press-mask
button-release-mask
pointer-motion-mask
key-press-mask
key-release-mask
/]);
$self->event_options_changed() ;
return($self) ;
}
#-----------------------------------------------------------------------------
sub destroy
{
my ($self) = @_;
$self->{widget}->get_toplevel()->destroy() ;
}
#-----------------------------------------------------------------------------
sub set_title
{
my ($self, $title) = @_;
$self->SUPER::set_title($title) ;
if(defined $title)
{
$self->{widget}->get_toplevel()->set_title($title . ' - asciio') ;
}
}
#-----------------------------------------------------------------------------
sub set_font
{
my ($self, $font_family, $font_size) = @_;
$self->SUPER::set_font($font_family, $font_size) ;
$self->{widget}->modify_font
(
Gtk2::Pango::FontDescription->from_string
(
$self->{FONT_FAMILY} . ' ' . $self->{FONT_SIZE}
)
);
}
#-----------------------------------------------------------------------------
sub update_display
{
my ($self) = @_;
$self->SUPER::update_display() ;
my $widget = $self->{widget} ;
$widget->queue_draw_area(0, 0, $widget->allocation->width,$widget->allocation->height);
}
#-----------------------------------------------------------------------------
sub configure_event
{
my ($widget, $event, $self) = @_;
$self->{PIXMAP} = Gtk2::Gdk::Pixmap->new
(
$widget->window,
$widget->allocation->width, $widget->allocation->height,
-1
);
$self->{WINDOW_SIZE} = [$widget->allocation->width, $widget->allocation->height] ;
$self->{PIXMAP}->draw_rectangle
(
$widget->get_style->base_gc ($widget->state),
TRUE, 0, 0, $widget->allocation->width,
$widget->allocation->height
);
return TRUE;
}
#-----------------------------------------------------------------------------
sub expose_event
{
my ($widget, $event, $self) = @_;
my $gc = Gtk2::Gdk::GC->new($self->{PIXMAP});
# draw background
$gc->set_foreground($self->get_color('background'));
$self->{PIXMAP}->draw_rectangle
(
$gc, TRUE,
0, 0,
$widget->allocation->width, $widget->allocation->height
);
my ($character_width, $character_height) = $self->get_character_size() ;
my ($widget_width, $widget_height) = $self->{PIXMAP}->get_size();
if($self->{DISPLAY_GRID})
{
$gc->set_foreground($self->get_color('grid'));
for my $horizontal (0 .. ($widget_height/$character_height) + 1)
{
$self->{PIXMAP}->draw_line
(
$gc,
lib/App/Asciio/GTK/Asciio.pm view on Meta::CPAN
# draw selection rectangle
if(defined $self->{SELECTION_RECTANGLE}{END_X})
{
my $start_x = $self->{SELECTION_RECTANGLE}{START_X} * $character_width ;
my $start_y = $self->{SELECTION_RECTANGLE}{START_Y} * $character_height ;
my $width = ($self->{SELECTION_RECTANGLE}{END_X} - $self->{SELECTION_RECTANGLE}{START_X}) * $character_width ;
my $height = ($self->{SELECTION_RECTANGLE}{END_Y} - $self->{SELECTION_RECTANGLE}{START_Y}) * $character_height;
if($width < 0)
{
$width *= -1 ;
$start_x -= $width ;
}
if($height < 0)
{
$height *= -1 ;
$start_y -= $height ;
}
$gc->set_foreground($self->get_color('selection_rectangle')) ;
$self->{PIXMAP}->draw_rectangle($gc, FALSE,$start_x, $start_y, $width, $height);
delete $self->{SELECTION_RECTANGLE}{END_X} ;
}
$widget->window->draw_drawable
(
$widget->style->fg_gc($widget->state),
$self->{PIXMAP},
$event->area->x, $event->area->y,
$event->area->x, $event->area->y,
$event->area->width, $event->area->height
);
return TRUE;
}
#-----------------------------------------------------------------------------
sub get_key_modifiers
{
my ($event) = @_ ;
my $key_modifiers = $event->state() ;
my $modifiers = $key_modifiers =~ /control-mask/ ? 'C' :0 ;
$modifiers .= $key_modifiers =~ /mod1-mask/ ? 'A' :0 ;
$modifiers .= $key_modifiers =~ /shift-mask/ ? 'S' :0 ;
return($modifiers) ;
}
#-----------------------------------------------------------------------------
sub button_release_event
{
my ($widget, $event, $self) = @_ ;
$self->SUPER::button_release_event($self->create_asciio_event($event)) ;
}
#-----------------------------------------------------------------------------
sub create_asciio_event
{
my ($self, $event) = @_ ;
my $asciio_event =
{
TYPE => $event->type(),
STATE => $event->state() ,
MODIFIERS => get_key_modifiers($event),
BUTTON => -1,
KEY_VALUE => -1,
COORDINATES => [-1, -1],
} ;
$asciio_event->{BUTTON} = $event->button() if ref $event eq 'Gtk2::Gdk::Event::Button' ;
if
(
ref $event eq "Gtk2::Gdk::Event::Motion"
|| ref $event eq "Gtk2::Gdk::Event::Button"
)
{
$asciio_event->{COORDINATES} = [$self->closest_character($event->coords())] ;
}
$asciio_event->{KEY_VALUE} = $event->keyval() if ref $event eq "Gtk2::Gdk::Event::Key" ;
return $asciio_event ;
}
#-----------------------------------------------------------------------------
sub button_press_event
{
#~ print "button_press_event\n" ;
my ($widget, $event, $self) = @_ ;
my $asciio_event = $self->create_asciio_event($event) ;
$self->SUPER::button_press_event($asciio_event, $event) ;
}
#-----------------------------------------------------------------------------
sub motion_notify_event
{
my ($widget, $event, $self) = @_ ;
my $asciio_event = $self->create_asciio_event($event) ;
$self->SUPER::motion_notify_event($asciio_event) ;
}
#-----------------------------------------------------------------------------
sub key_press_event
{
my ($widget, $event, $self)= @_;
my $asciio_event = $self->create_asciio_event($event) ;
$self->SUPER::key_press_event($asciio_event) ;
}
#-----------------------------------------------------------------------------
sub get_character_size
{
my ($self) = @_ ;
if(exists $self->{USER_CHARACTER_WIDTH})
{
return ($self->{USER_CHARACTER_WIDTH}, $self->{USER_CHARACTER_HEIGHT}) ;
}
else
{
my $layout = $self->{widget}->create_pango_layout('M') ;
return $layout->get_pixel_size() ;
}
}
#-----------------------------------------------------------------------------
sub get_color
{
my ($self, $name) = @_;
unless (exists $self->{ALLOCATED_COLORS}{$name})
{
my $color ;
if('ARRAY' eq ref $name)
{
$color = Gtk2::Gdk::Color->new( map {$_ * 257} @{$name}) ;
}
elsif(exists $self->{COLORS}{$name})
{
if('ARRAY' eq ref $self->{COLORS}{$name})
{
$color = Gtk2::Gdk::Color->new( map {$_ * 257} @{ $self->{COLORS}{$name}}) ;
}
else
{
$color = Gtk2::Gdk::Color->parse($self->{COLORS}{$name});
}
}
else
{
$color = Gtk2::Gdk::Color->parse($name);
}
$color = Gtk2::Gdk::Color->new( map {$_ * 257} (255, 0, 0)) unless defined $color ;
$self->{widget}->get_colormap->alloc_color($color,TRUE,TRUE) ;
$self->{ALLOCATED_COLORS}{$name} = $color ;
}
return($self->{ALLOCATED_COLORS}{$name}) ;
}
#-----------------------------------------------------------------------------
( run in 2.542 seconds using v1.01-cache-2.11-cpan-364913b4093 )