File Coverage

blib/lib/Gtk2/Ex/Spinner/CellRenderer.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Gtk2::Ex::Spinner::CellRenderer;
2 1     1   846 use 5.008;
  1         3  
  1         38  
3 1     1   5 use strict;
  1         1  
  1         34  
4 1     1   4 use warnings;
  1         2  
  1         21  
5 1     1   1610 use Gtk2;
  0            
  0            
6              
7             our $VERSION = 5.1;
8              
9             use constant DEBUG => 0;
10              
11             use Glib::Object::Subclass
12             'Gtk2::CellRendererText';
13              
14             # gtk_cell_renderer_start_editing()
15             #
16             # SUPER::START_EDITING of Gtk2::CellRendererText is no good for the
17             # Gtk2::Entry creation because it sets that widget to stop editing on losing
18             # keyboard focus, which includes the switch away to the
19             # Spinner::PopupEntry window, the effect being to immediately stop
20             # editing when that window pops up.
21             #
22             sub START_EDITING {
23             my ($self, $event, $view, $pathstr, $back_rect, $cell_rect, $flags) = @_;
24             if (DEBUG) { print "Renderer START_EDITING '$pathstr'\n";
25             print " back ",$back_rect->x,",",$back_rect->y,
26             " ",$back_rect->width,"x",$back_rect->width,
27             " cell ",$cell_rect->x,",",$cell_rect->y,
28             " ",$cell_rect->width,"x",$cell_rect->width,"\n";
29             }
30             $self->{'pathstr'} = $pathstr;
31              
32             # no frame and copy 'xalign' across, the same as CellRendererText does
33             require Gtk2::Ex::Spinner::EntryWithCancel;
34             my $entry = Gtk2::Ex::Spinner::EntryWithCancel->new
35             (has_frame => 0,
36             xalign => $self->get('xalign'));
37             if (DEBUG) { print " edit with $entry\n"; }
38              
39             {
40             # This is a hack for Gtk2-Perl 1.210 and earlier ensuring
41             # gtk2perl_cell_renderer_start_editing() doesn't see $entry with a
42             # refcount of 1, since it would increment that as a protection against
43             # premature destruction -- but then never decrement. If the refcount is
44             # 2 it leaves it alone.
45             Glib::Idle->add (sub { 0 }, # Glib::SOURCE_REMOVE
46             $entry);
47             }
48              
49             require Gtk2::Ex::Spinner::PopupForEntry;
50             Gtk2::Ex::Spinner::PopupForEntry->new (entry => $entry);
51              
52             my $value = $self->get('text');
53             $entry->set_text (defined $value ? $value : '');
54             $entry->select_region (0, -1);
55              
56             my $ref_weak_self = \$self;
57             require Scalar::Util;
58             Scalar::Util::weaken ($ref_weak_self);
59             $entry->signal_connect (editing_done => \&_do_entry_editing_done,
60             $ref_weak_self);
61              
62             if (DEBUG) {
63             $entry->signal_connect (destroy => sub {
64             print "editable: destroy\n";
65             });
66             $entry->signal_connect (focus_out_event => sub {
67             print "editable: focus_out_event\n";
68             return 0; # Gtk2::EVENT_PROPAGATE
69             });
70             }
71             $entry->show;
72             return $entry;
73             }
74              
75             # 'editing-done' handler on the Gtk2::Ex::Spinner::EntryWithCancel
76             #
77             sub _do_entry_editing_done {
78             my ($entry, $ref_weak_self) = @_;
79             my $self = $$ref_weak_self || return;
80             if (DEBUG) { print "Spinner::CellRenderer _do_entry_editing_done,",
81             " cancelled ",($entry->get('editing_cancelled')?"yes":"no"),
82             "\n"; }
83              
84             my $cancelled = $entry->get('editing_cancelled');
85             $self->stop_editing ($cancelled);
86             if (! $cancelled) {
87             $self->signal_emit ('edited', $self->{'pathstr'}, $entry->get_text);
88             }
89             }
90              
91             1;
92             __END__