File Coverage

lib/Games/Sudoku/Component/TkPlayer/Selector.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 Games::Sudoku::Component::TkPlayer::Selector;
2             {
3 1     1   1430 use strict;
  1         2  
  1         34  
4 1     1   6 use warnings;
  1         2  
  1         25  
5 1     1   4 use Carp;
  1         2  
  1         77  
6            
7 1     1   550 use Tk::widgets qw/Toplevel/;
  0            
  0            
8             use base qw/Tk::Toplevel/;
9            
10             Construct Tk::Widget 'Selector';
11            
12             sub Populate {
13             my $this = shift;
14            
15             $this->SUPER::Populate(@_);
16             $this->transient($this->Parent->toplevel);
17             $this->withdraw;
18             $this->{result} = undef;
19             $this->protocol(
20             'WM_DELETE_WINDOW' => sub { $this->{result} = 0 }
21             );
22             }
23            
24             sub set_allowed {
25             my ($this, $allowed_only, @allowed) = @_;
26            
27             my $target = 0;
28             foreach my $id (1..$this->{size}) {
29             my $color = 'gray';
30            
31             if ($allowed_only) {
32             $target ||= shift @allowed if @allowed;
33             $color = 'red';
34             if ($id == $target) {
35             $target = 0;
36             $color = 'gray';
37             }
38             }
39             $this->{buttons}[$id]->configure(
40             -background => $color,
41             );
42             }
43             }
44            
45             sub setsize {
46             my ($this, $size) = @_;
47            
48             $this->{size} = $size;
49            
50             foreach my $button (@{ $this->{buttons} }) {
51             $button->destroy;
52             }
53             $this->{frame}->destroy if $this->{frame};
54            
55             my $blocksize = int(sqrt($size - 1)) + 1;
56            
57             my $frame = $this->Frame;
58             foreach my $num (1..$size) {
59             my $row = int(($num - 1) / $blocksize);
60             my $col = ($num - 1) % $blocksize;
61            
62             $this->{buttons}[$num] = $this->Button(
63             -text => $num,
64             -font => [
65             -size => 25,
66             ],
67             -command => sub { $this->{result} = $num }
68             )->grid(
69             -in => $frame,
70             -row => $row,
71             -column => $col,
72             -sticky => 'news',
73             );
74             }
75             $frame->pack(
76             -side => 'left',
77             -padx => 0,
78             -pady => 0,
79             );
80             $this->{frame} = $frame;
81             $this->bind('' => \&keypress);
82             }
83            
84             sub keypress {
85             my $this = shift;
86             my $e = $this->XEvent;
87             if ($e->K eq 'Escape') { $this->{result} = 0 }
88             if (my ($num) = $e->K =~ /^(\d)$/) { $this->{result} = $num; }
89             }
90            
91             sub Show {
92             my $this = shift;
93            
94             $this->{old_focus} = $this->focusSave;
95             $this->{old_grab} = $this->grabSave;
96            
97             $this->Popup(
98             -popover => $this->Parent,
99             -overanchor => 'c',
100             -popanchor => 'c',
101             );
102            
103             $this->grab;
104            
105             if (my $focusw = $this->cget(-focus)) {
106             $focusw->focus;
107             }
108             else {
109             $this->focus;
110             }
111            
112             $this->Wait;
113            
114             $this->{old_focus}->();
115             $this->{old_grab}->();
116            
117             return $this->{result};
118             }
119            
120             sub Wait {
121             my $this = shift;
122            
123             $this->Callback(-showcommand => $this);
124             $this->waitVariable(\$this->{result});
125             $this->grabRelease;
126             $this->withdraw;
127             $this->Callback(-command => $this->{result});
128             }
129             }
130            
131             1;
132            
133             __END__