Gtk2-CV

 view release on metacpan or  search on metacpan

lib/Gtk2/CV/ImageWindow.pm  view on Meta::CPAN

use Gtk2;
use Gtk2::Gdk::Keysyms;

use Gtk2::CV;
use Gtk2::CV::PrintDialog;

use List::Util qw(min max);

use Scalar::Util;
use POSIX ();
use FileHandle ();
use Errno ();
use Fcntl ();
use Socket ();

use JSON::XS ();

my $title_image;

# should go to utility module
sub dir_is_movie($) {
   -f "$_[0]/VIDEO_TS/VIDEO_TS.IFO"		and return "dvd";
   -d "$_[0]/BDMV/STREAM/."			and return "br";

   undef
}

use Glib::Object::Subclass
   Gtk2::Window::,
   properties => [
      Glib::ParamSpec->scalar ("path", "Pathname", "The image pathname", [qw(writable readable)]),
   ],
   signals => {
      image_changed        => { flags => [qw/run-first/], return_type => undef, param_types => [] },
      button3_press_event  => { flags => [qw/run-first/], return_type => undef, param_types => [] },

      button_press_event   => sub { $_[0]->do_button_press (1, $_[1]) },
      button_release_event => sub { $_[0]->do_button_press (0, $_[1]) },
      motion_notify_event  => \&motion_notify_event,
      show                 => sub {
         $_[0]->realize_image;
         $_[0]->signal_chain_from_overridden;
      },
   };

our $SET_ASPECT;

sub INIT_INSTANCE {
   my ($self) = @_;

   $self->push_composite_child;

   $self->double_buffered (0);

   $self->set_role ("image window");

   $self->signal_connect (destroy => sub { $self->kill_player });
   $self->signal_connect (realize => sub { $_[0]->do_realize; 0 });
   $self->signal_connect (map_event => sub { $_[0]->check_screen_size; $_[0]->auto_position (($_[0]->allocation->values)[2,3]) });
   $self->signal_connect (expose_event => sub {
      # in most cases, we get no expose events, except when our _own_ popups
      # obscure some part of the window. se we have to do lots of unneessary refreshes :(
      $self->{window}->clear_area ($_[1]->area->values);
      $self->draw_drag_rect ($_[1]->area);
      1
   });
   $self->signal_connect (configure_event => sub { $_[0]->do_configure ($_[1]); 0 });
   $self->signal_connect (key_press_event => sub { $_[0]->handle_key ($_[1]->keyval, $_[1]->state) });

   $self->{frame_extents_property}         = Gtk2::Gdk::Atom->intern ("_NET_FRAME_EXTENTS", 0);
   $self->{request_frame_extents_property} = Gtk2::Gdk::Atom->intern ("_NET_REQUEST_FRAME_EXTENTS", 0);

   $self->signal_connect (property_notify_event => sub {
      return unless $_[0]{frame_extents_property} == $_[1]->atom;

      $self->update_properties;

      0
   });

   $self->add_events ([qw(key_press_mask focus-change-mask button_press_mask property_change_mask
                          button_release_mask pointer-motion-hint-mask pointer-motion-mask)]);
   $self->can_focus (1);
   $self->set_size_request (0, 0);
   #$self->set_resize_mode ("immediate");

   $self->{interp} = 'bilinear';
   $self->{maxpect} = 1;

   $self->pop_composite_child;

   $self->clear_image;
}

sub SET_PROPERTY {
   my ($self, $pspec, $newval) = @_;

   $pspec = $pspec->get_name;
   
   if ($pspec eq "path") {
      $self->load_image ($newval);
   } else {
      $self->{$pspec} = $newval;
   }
}

sub do_image_changed {
   my ($self) = @_;
}

sub kill_player {
   my ($self) = @_;

   if ($self->{player_pid} > 0) {

      if ($self->{mpv_fh}) {
         local $SIG{PIPE} = 'IGNORE';
         print {$self->{mpv_fh}} "quit\n";
         delete $self->{mpv_fh};
      } else {
         kill INT  => $self->{player_pid};



( run in 1.673 second using v1.01-cache-2.11-cpan-364913b4093 )