File Coverage

blib/lib/Tk/ColourChooser.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Tk::ColourChooser ; # Documented at the __END__.
2             #use Data::Dumper;
3              
4             # $Id: ColourChooser.pm,v 1.32 2000/05/05 16:40:27 root Exp $
5              
6             require 5.004 ;
7              
8 2     2   40223 use strict ;
  2         5  
  2         98  
9 2     2   11 use warnings;
  2         4  
  2         126  
10              
11 2     2   12 use Carp ;
  2         9  
  2         229  
12 2     2   4336 use Symbol ;
  2         3019  
  2         293  
13 2     2   1215 use Tk ;
  0            
  0            
14              
15             require Tk::Toplevel ;
16              
17             use vars qw( $VERSION @ISA %Translate ) ;
18              
19             $VERSION = '1.52';
20              
21             @ISA = qw( Tk::Toplevel ) ;
22              
23             Construct Tk::Widget 'ColourChooser' ;
24              
25             # Global hashes available to all instances
26             my( %Name2hex, %Hex2name ) ;
27             my $Loaded ; # Flag indicating whether we're read the colour data or not.
28              
29              
30             #############################
31             sub Populate {
32             my( $win, $args ) = @_ ;
33              
34             $win->{-language} = delete $args->{-language} || 'en' ;
35             $win->{-showhex} = delete $args->{-showhex} || 0 ;
36             $win->{-language} = 'en' if $win->{-language} eq 'english' ; # Backward compatibility.
37             $args->{-title} = $Translate{$win->{-language}}{-title}
38             unless defined $args->{-title} ;
39             my $hexonly = delete $args->{-hexonly} ;
40             $win->{HEX_ONLY} = defined $hexonly and $hexonly ? 1 : 0 ;
41             my $transparent = delete $args->{-transparent} ;
42             my $colour = delete $args->{-colour} ;
43              
44             $win->SUPER::Populate( $args ) ;
45              
46             $win->withdraw ;
47             $win->iconname( $args->{-title} ) ;
48             $win->protocol( 'WM_DELETE_WINDOW' => sub { } ) ;
49             $win->transient( $win->parent ) ;
50            
51             &_read_rgb( $win ) ;
52            
53             # Create listbox.
54             my $Frame = $win->Frame()->pack( -fill => 'x' ) ;
55             $win->{COLOUR_FRAME} = $Frame ;
56             my $scrollbar = $Frame->Scrollbar->pack( -side => 'right', -fill => 'y' ) ;
57             my $list = $Frame->Listbox(
58             -height => 1,
59             -selectmode => 'single',
60             -background => 'white',
61             -exportselection => 0,
62             )->pack( -expand => 'ns', -fill => 'x', -pady => 20, -padx => 10 ) ;
63             $list->configure(
64             -yscrollcommand => [ \&_listbox_scroll, $scrollbar, $list, $win ] ) ;
65             $scrollbar->configure( -command => [ $list => 'yview' ] ) ;
66              
67             $list->insert( 'end', sort { lc $a cmp lc $b } keys %Name2hex ) ;
68              
69             $list->bind( '', [ \&_set_colour_from_list, $win ] ) ;
70             $list->bind( '', [ \&_set_colour_from_list, $win ] ) ;
71             $list->bind( '<1>', [ \&_set_colour_from_list, $win ] ) ;
72              
73             $win->{COLOUR_LIST} = $list ;
74              
75             &_set_list( $win, 0 ) ;
76              
77             # Colour sliders.
78             foreach my $colour ( qw( red green blue ) ) {
79             my $scale = $win->Scale(
80             -orient => 'horizontal',
81             -from => 0,
82             -to => 255,
83             -tickinterval => 25,
84             -label => $Translate{$win->{-language}}{'-' . $colour},
85             -fg => "dark$colour",
86             '-length' => 300,
87             )->pack( -fill => 'x' ) ;
88             $win->{'-' . $colour} = 0 ;
89             $scale->configure(
90             -variable => \$win->{'-' . $colour},
91             -command => [ \&_set_colour, $win ],
92             ) ;
93             }
94            
95             # Create buttons.
96             $Frame = $win->Frame()->pack() ;
97             my $column = 0 ;
98             foreach my $button ( $Translate{$win->{-language}}{-ok},
99             $Translate{$win->{-language}}{-transparent},
100             $Translate{$win->{-language}}{-cancel} ) {
101             next if $button eq $Translate{$win->{-language}}{-transparent} and
102             defined $transparent and
103             $transparent == 0 ;
104              
105             my $Button = $Frame->Button(
106             -text => $button,
107             -underline => 0,
108             -width => 10,
109             -command => [ \&_close, $win, $button ],
110             )->grid( -row => 0, -column => $column++, -pady => 5 ) ;
111            
112             my $char = lc substr( $button, 0, 1 ) ;
113              
114             $win->bind( "", [ \&_close, $win, $button ] ) ;
115             $win->bind( "", [ \&_close, $win, $button ] ) ;
116             $win->bind( "<${char}>", [ \&_close, $win, $button ] ) ;
117             }
118              
119             $win->bind( "",
120             [ \&_close, $win, $Translate{$win->{-language}}{-ok} ] ) ;
121             $win->bind( "",
122             [ \&_close, $win, $Translate{$win->{-language}}{-cancel} ] ) ;
123              
124             # Set initial colour if given.
125             if( defined $colour ) {
126             if( lc $colour eq 'none' ) {
127             $win->{-red} = $win->{-green} = $win->{-blue} = 0 ;
128             }
129             elsif( $colour =~
130             /^#?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/o ) {
131             $win->{-red} = hex $1 ;
132             $win->{-green} = hex $2 ;
133             $win->{-blue} = hex $3 ;
134             }
135             else {
136             my $hex = $Name2hex{$colour} ;
137             if (defined $hex) {
138             $win->{-red} = hex substr( $hex, 0, 2 ) ;
139             $win->{-green} = hex substr( $hex, 2, 2 ) ;
140             $win->{-blue} = hex substr( $hex, 4, 2 ) ;
141             }
142             }
143             &_set_colour( $win ) ;
144             }
145            
146             $win->{-colour} = undef ;
147             }
148              
149             #############################
150             sub _find_rgb {
151              
152             if ($ENV{RGB_TEXT}) {
153             return $ENV{RGB_TEXT} if -r $ENV{RGB_TEXT};
154             }
155             else {
156             foreach my $file (
157             '/usr/local/lib/X11/rgb.txt', '/usr/lib/X11/rgb.txt',
158             '/usr/local/X11R5/lib/X11/rgb.txt', '/X11/R5/lib/X11/rgb.txt',
159             '/X11/R4/lib/rgb/rgb.txt', '/usr/openwin/lib/X11/rgb.txt',
160             '/usr/X11R6/lib/X11/rgb.txt',
161             ) {
162             return $file if -e $file ;
163             }
164             }
165             carp "Failed to find `rgb.txt', set \$ENV{RGB_TEXT} to the filename" ;
166              
167             return;
168             }
169              
170             #############################
171             sub _read_rgb {
172             my $win = shift ;
173              
174             return if $Loaded ;
175             $Loaded = 1 ;
176              
177             my $file = &_find_rgb ;
178              
179             if( defined $file ) {
180             $Name2hex{'_Unnamed'} = '000000' ;
181             $Hex2name{'000000'} = '_Unnamed' ;
182             my $fh = gensym ;
183             open $fh, $file or croak "Failed to open `$file': $!" ;
184             local $_ ;
185             while( <$fh> ) {
186             chomp ;
187             my @array = split ;
188             if( scalar @array == 4 ) {
189             my $hex = sprintf "%02X%02X%02X", @array[0..2] ;
190             # We only use the first name for a given colour.
191             if( not exists $Name2hex{$array[3]} ) {
192             $Name2hex{$array[3]} = $hex ;
193             $Hex2name{$hex} = $array[3] ;
194             }
195             }
196             }
197             close $fh or carp "Failed to close `$file': $!" ;
198             }
199             }
200              
201             #############################
202             sub _listbox_scroll {
203             my( $scrollbar, $list, $win, @args ) = @_ ;
204              
205             $scrollbar->set( @args ) ;
206             my $index = int( $list->size * $args[0] ) ;
207             $list->activate( $index ) ;
208             $list->selectionSet( $index ) ;
209             }
210              
211             #############################
212             sub _set_colour {
213             my $win = shift ;
214              
215             my $hex = sprintf "%02X%02X%02X",
216             $win->{-red}, $win->{-green}, $win->{-blue} ;
217              
218             my $index = 0 ;
219             if( exists $Hex2name{$hex} ) {
220             my $list = $win->{COLOUR_LIST} ;
221             for( $index = 0 ; $index < $list->size ; $index++ ) {
222             last if $list->get( $index ) eq $Hex2name{$hex} ;
223             }
224             }
225             &_set_list( $win, $index ) ;
226              
227             &_update_colour( $win, $hex ) ;
228             }
229              
230             #############################
231             sub _set_colour_from_list {
232             my( $list, $win ) = @_ ;
233              
234             $list->selectionSet( 'active' ) ;
235             my $colour = $list->get( 'active' ) ;
236             my $hex = $Name2hex{$colour} ;
237             $win->{-red} = hex substr( $hex, 0, 2 ) ;
238             $win->{-green} = hex substr( $hex, 2, 2 ) ;
239             $win->{-blue} = hex substr( $hex, 4, 2 ) ;
240              
241             &_update_colour( $win, $hex ) ;
242             }
243              
244              
245             #############################
246             sub _update_colour {
247             my( $win, $hex ) = @_ ;
248              
249             if( $win->{-showhex} ) {
250             my $title = $win->cget( -title ) ;
251             $title = substr( $title, 0, index( $title, ' -' ) ) ;
252             $win->configure( -title, "$title - #$hex" ) ;
253             }
254             $win->{COLOUR_FRAME}->configure( -bg => "#$hex" ) ;
255             }
256              
257              
258             #############################
259             sub _set_list {
260             my( $win, $index ) = @_ ;
261              
262             my $list = $win->{COLOUR_LIST} ;
263             $list->activate( $index ) ;
264             $list->see( $index ) ;
265             $list->selectionSet( $index ) ;
266             }
267              
268             #############################
269             sub Show {
270             my $win = shift ;
271              
272             $win->Popup() ;
273              
274             my $list = $win->{COLOUR_LIST} ;
275             $list->focus ;
276              
277             $win->waitVariable( \$win->{-colour} ) ;
278             $win->withdraw ;
279              
280             $win->{-colour} ;
281             }
282              
283             #############################
284             sub _close {
285              
286             my $win ;
287             while( ref $_[0] ) {
288             $win = shift ;
289             last if ref $win =~ /ColourChooser/o ;
290             }
291             my $button = shift ;
292              
293             if( $button eq $Translate{$win->{-language}}{-transparent} ) {
294             $win->{-colour} = 'None' ;
295             }
296             elsif( $button eq $Translate{$win->{-language}}{-cancel} ) {
297             $win->{-colour} = '' ;
298             }
299             else {
300             my $hex = sprintf "%02X%02X%02X",
301             $win->{-red}, $win->{-green}, $win->{-blue} ;
302             if( exists $Hex2name{$hex} and not $win->{HEX_ONLY} ) {
303             $win->{-colour} = $Hex2name{$hex} ;
304             }
305             else {
306             $win->{-colour} = "#$hex" ;
307             }
308             }
309              
310             $win->{-colour} ;
311             }
312              
313             #############################
314             BEGIN {
315             %Translate = (
316             'de' => {
317             -title => 'Farbe Chooser',
318             -red => 'Rot',
319             -blue => 'Blau',
320             -green => 'Grün',
321             -ok => 'OK',
322             -transparent => 'Transparent',
323             -cancel => 'Löschen',
324             },
325             'en' => {
326             -title => 'Colour Chooser',
327             -red => 'Red',
328             -blue => 'Blue',
329             -green => 'Green',
330             -ok => 'OK',
331             -transparent => 'Transparent',
332             -cancel => 'Cancel',
333             },
334             'fr' => {
335             -title => 'Couleur Chooser',
336             -red => 'Rouge',
337             -blue => 'Bleu',
338             -green => 'Vert',
339             -ok => 'OK',
340             -transparent => 'Transparent',
341             -cancel => 'Annulent',
342             },
343             ) ;
344             }
345              
346             1 ;
347              
348             __END__