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 )