Gtk2-Ex-DateSpinner

 view release on metacpan or  search on metacpan

lib/Gtk2/Ex/DateSpinner/CellRenderer.pm  view on Meta::CPAN

# with Gtk2-Ex-DateSpinner.  If not, see <http://www.gnu.org/licenses/>.

package Gtk2::Ex::DateSpinner::CellRenderer;
use 5.008;
use strict;
use warnings;
use Gtk2;

our $VERSION = 10;

use Glib::Object::Subclass
  'Gtk2::CellRendererText';

# gtk_cell_renderer_start_editing()
#
# Cannot use parent $self->SUPER::START_EDITING from Gtk2::CellRendererText
# to do the Gtk2::Entry creation because it sets that widget to stop editing
# on losing key focus (handler gtk_cell_renderer_text_focus_out_event()),
# which includes the switch away to the DateSpinner::PopupEntry window, the
# effect being to immediately stop editing when that window pops up.
#
# There doesn't seem to be an easy way to suppress that
# gtk_cell_renderer_text_focus_out_event() editing-done behaviour.  Can't
# catch focus-out and not propagate it, as the GtkEntry code needs it.
#
sub START_EDITING {
  my ($self, $event, $view, $pathstr, $back_rect, $cell_rect, $flags) = @_;
  ### Renderer START_EDITING
  ### $pathstr
  ### back: $back_rect->x.",".$back_rect->y." ".$back_rect->width."x".$back_rect->width
  ### cell: $cell_rect->x.",".$cell_rect->y." ".$cell_rect->width."x".$cell_rect->width

  $self->{'pathstr'} = $pathstr;

  # no frame and copy 'xalign' across, the same as CellRendererText does
  my $entry = Gtk2::Entry->new;
  $entry->set (has_frame => 0,
               xalign    => $self->get('xalign'));
  $entry->signal_connect (key_press_event => \&_do_entry_key_press);
  ### edit with: "$entry"

  {
    # This is a hack for Gtk2-Perl 1.210 and earlier ensuring
    # gtk2perl_cell_renderer_start_editing() doesn't see $entry with a
    # refcount of 1, since it would increment that as a protection against
    # premature destruction -- but then never decrement.  If the refcount is
    # 2 it leaves it alone.
    Glib::Idle->add (sub { 0 }, # Glib::SOURCE_REMOVE
                     $entry);
  }

  require Gtk2::Ex::DateSpinner::PopupForEntry;
  Gtk2::Ex::DateSpinner::PopupForEntry->new (entry => $entry);

  my $value = $self->get('text');
  $entry->set_text (defined $value ? $value : '');
  $entry->select_region (0, -1);

  my $ref_weak_self = \$self;
  require Scalar::Util;
  Scalar::Util::weaken ($ref_weak_self);
  $entry->signal_connect (editing_done => \&_do_entry_editing_done,
                          $ref_weak_self);

  # {
  #   $entry->signal_connect (destroy => sub {
  #                             print "editable: destroy\n";
  #                           });
  #   $entry->signal_connect (focus_out_event => sub {
  #                             print "editable: focus_out_event\n";
  #                             return 0; # Gtk2::EVENT_PROPAGATE
  #                           });
  # }

  $entry->show;
  return $entry;
}

# 'key-press-event' handler for Gtk2::Entry
# An Escape for cancelling the edit is noted in a flag.
# This is like gtk_cell_editable_key_press_event() notes in its (mis-spelt)
# "editing_canceled" field.  Would prefer to look at that field, but it's
# private.
sub _do_entry_key_press {
  my ($entry, $event) = @_;
  if ($event->keyval == Gtk2::Gdk->keyval_from_name('Escape')) {
    $entry->{'editing_cancelled'} = 1;
  }
  return 0; # Gtk2::EVENT_PROPAGATE
}

# 'editing-done' handler on the Gtk2::Entry
#
sub _do_entry_editing_done {
  my ($entry, $ref_weak_self) = @_;
  my $self = $$ref_weak_self || return;
  ### DateSpinner-CellRenderer _do_entry_editing_done() ...
  ### cancelled: $entry->{'editing_cancelled'}

  my $cancelled = $entry->{'editing_cancelled'};
  $self->stop_editing ($cancelled);
  if (! $cancelled) {
    $self->signal_emit ('edited', $self->{'pathstr'}, $entry->get_text);
  }
}

1;
__END__

=for stopwords renderer DateSpinner Gtk2-Ex-DateSpinner YYYY-MM-DD popup decrement Ok Eg Gtk2-Perl Ryde

=head1 NAME

Gtk2::Ex::DateSpinner::CellRenderer -- date cell renderer with DateSpinner for editing

=for test_synopsis my ($treeviewcolumn)

=head1 SYNOPSIS

 use Gtk2::Ex::DateSpinner::CellRenderer;
 my $renderer = Gtk2::Ex::DateSpinner::CellRenderer->new;



( run in 0.566 second using v1.01-cache-2.11-cpan-5a3173703d6 )