ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/gtk.pl
Revision: 1.32
Committed: Wed Jun 2 09:32:32 2004 UTC (20 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.31: +90 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 package gtk;
2    
3 pcg 1.3 use Carp;
4 pcg 1.15 use File::Temp;
5     use Gtk2;
6 pcg 1.3
7 pcg 1.26 # I have not yet found a way to simply default style properties
8 pcg 1.24 Gtk2::Rc->parse_string(<<EOF);
9    
10     style "base" {
11     GtkTreeView::vertical_separator = 0
12     }
13     widget_class "*" style "base"
14    
15     EOF
16    
17 root 1.31 sub flush {
18     do {
19     flush Gtk2::Gdk;
20     Glib::MainContext->default->iteration (0);
21     } while Gtk2::Gdk->events_pending;
22     }
23    
24     sub for_all($) {
25     (
26     $_[0],
27     $_[0]->isa (Gtk2::Container)
28     ? map for_all ($_), $_[0]->get_children
29     : ()
30     )
31     }
32    
33     sub double_buffered {
34     return;#d#
35     my ($widget, $state) = @_;
36    
37     for (for_all $widget) {
38     $_->set_double_buffered ($state);
39     print "$_\n";#d#
40     }
41     print "<<<\n";#d#
42     }
43    
44 pcg 1.1 our $text_renderer = new Gtk2::CellRendererText;
45     our $int_renderer = new Gtk2::CellRendererText;
46     $int_renderer->set (xalign => 1);
47    
48 pcg 1.5 our $state = $util::state->{gtk} ||= {};
49 pcg 1.1
50     # shows the properties of a glib object
51 pcg 1.3 sub info {
52 pcg 1.1 my ($idx, $obj) = @_;
53 pcg 1.5 return if $seen{$idx}++;
54 pcg 1.1 print "\n$idx\n";
55     for ($obj->list_properties) {
56     printf "%-16s %-24s %-24s %s\n", $_->{name}, $_->{type}, (join ":", @{$_->{flags}}), $_->{descr};
57     }
58     }
59    
60     my %get = (
61     window_size => sub { [ ($_[0]->allocation->values)[2,3] ] },
62     #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] },
63 pcg 1.5 column_size => sub { $_[0]->get("width") || $_[0]->get("fixed_width") },
64 pcg 1.10 modelsortorder => sub { [ $_[0]->get_sort_column_id ] },
65 pcg 1.1 );
66    
67     my %set = (
68 pcg 1.8 window_size => sub { $_[0]->set_default_size (@{$_[1]}) },
69     #window_pos => sub { $_[0]->set_uposition (@{$_[1]}) if @{$_[1]} },
70     column_size => sub { $_[0]->set (fixed_width => $_[1]) },
71 pcg 1.10 modelsortorder => sub { $_[0]->set_sort_column_id (@{$_[1]}) },
72 pcg 1.1 );
73    
74 pcg 1.5 my %widget;
75    
76 pcg 1.1 sub state {
77     my ($widget, $class, $instance, %attr) = @_;
78    
79     while (my ($k, $v) = each %attr) {
80     my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
81 pcg 1.9
82     $v = $state->{$class}{"*"}{$get}
83     if exists $state->{$class}{"*"} && exists $state->{$class}{"*"}{$get};
84    
85     $v = $state->{$class}{$instance}{$get}
86     if defined $instance
87     && exists $state->{$class}{$instance} && exists $state->{$class}{$instance}{$get};
88    
89 pcg 1.1 $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v);
90 pcg 1.9
91 pcg 1.26 #my $vx = KGS::Listener::Debug::dumpval $v; $vx =~ s/\s+/ /g; warn "set $class ($instance) $set => $vx\n";#d#
92 pcg 1.1 }
93    
94 pcg 1.8 #$widget->signal_connect(destroy => sub { delete $widget{$widget}; 0 });
95 pcg 1.1
96 pcg 1.5 $widget{$widget} = [$widget, $class, $instance, \%attr];
97     Scalar::Util::weaken $widget{$widget}[0];
98 pcg 1.1 }
99    
100     sub save_state {
101 pcg 1.5 for (grep $_, values %widget) {
102     my ($widget, $class, $instance, $attr) = @$_;
103    
104 pcg 1.8 next unless $widget; # no destroy => widget may be undef
105    
106 pcg 1.5 $widget->realize if $widget->can("realize");
107    
108     while (my ($k, $v) = each %$attr) {
109     my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
110     $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get);
111    
112     $state->{$class}{"*"}{$get} = $v;
113     $state->{$class}{$instance}{$get} = $v if defined $instance;
114 pcg 1.9
115 pcg 1.26 #my $vx = KGS::Listener::Debug::dumpval $v; $vx =~ s/\s+/ /g; warn "get $class ($instance) $get => $vx\n";#d#
116 pcg 1.1 }
117     }
118 pcg 1.15 }
119    
120     # string => Gtk2::Image
121     sub image_from_data {
122     my ($data) = @_;
123 pcg 1.18 my $img;
124 pcg 1.15
125 pcg 1.18 if (defined $data) {
126     # need to write to file first :/
127     my ($fh, $filename) = File::Temp::tempfile ();
128     syswrite $fh, $data;
129     close $fh;
130     $img = new_from_file Gtk2::Image $filename;
131     unlink $filename;
132     } else {
133 pcg 1.29 $img = new_from_file Gtk2::Image KGS::Constants::findfile "KGS/kgsueme/images/default_userpic.png";
134 pcg 1.18 }
135 pcg 1.15
136     $img;
137 pcg 1.1 }
138    
139 root 1.32 #############################################################################
140    
141     sub optionmenu {
142     my ($ref, @entry) = @_;
143    
144     my @vals;
145    
146     my $widget = new Gtk2::OptionMenu;
147     $widget->set (menu => my $menu = new Gtk2::Menu);
148    
149     my $idx = 0;
150    
151     while (@entry >= 2) {
152     my $value = shift @entry;
153     my $label = shift @entry;
154    
155     $menu->append (new Gtk2::MenuItem $label);
156     push @vals, $value;
157    
158     if ($value eq $$ref && $idx >= 0) {
159     $widget->set_history ($idx);
160     $idx = -1e6;
161     }
162     $idx++;
163     }
164    
165     my $cb = shift @entry;
166    
167     $widget->signal_connect (changed => sub {
168     my $new = $vals[$_[0]->get_history];
169    
170     if ($new ne $$ref) {
171     $$ref = $new;
172     $cb->($new) if $cb;
173     }
174     });
175    
176     $widget;
177     }
178    
179     sub textentry {
180     my ($ref, $width, $cb) = @_;
181    
182     my $widget = new Gtk2::Entry;
183     $widget->set (text => $$ref, width_chars => $width);
184     $widget->signal_connect (changed => sub {
185     $$ref = $_[0]->get_text;
186     $cb->($$ref) if $cb;
187     });
188    
189     $widget;
190     }
191    
192     sub numentry {
193     my ($ref, $width, $cb) = @_;
194    
195     my $widget = new Gtk2::Entry;
196     $widget->set (text => $$ref, width_chars => $width);
197     eval { $widget->set (xalign => 1) }; # workaround für 2.2
198     $widget->signal_connect (changed => sub {
199     $$ref = $_[0]->get_text;
200     $cb->($$ref) if $cb;
201     });
202    
203     $widget;
204     }
205    
206     sub timeentry {
207     my ($ref, $width, $cb) = @_;
208    
209     my $widget = new Gtk2::Entry;
210     $widget->set (text => util::format_time $$ref, width_chars => $width);
211     eval { $widget->set (xalign => 1) }; # workaround für 2.2
212     $widget->signal_connect (changed => sub {
213     $$ref = util::parse_time $_[0]->get_text;
214     $cb->($$ref) if $cb;
215     });
216    
217     $widget;
218     }
219    
220     sub button {
221     my ($label, $cb) = @_;
222    
223     my $widget = new_with_label Gtk2::Button $label;
224     $widget->signal_connect (clicked => sub { $cb->() if $cb });
225    
226     $widget;
227     }
228    
229 pcg 1.2 package gtk::widget;
230    
231     # hacked gtk pseudo-widget
232    
233 pcg 1.3 sub new {
234     my $class = shift;
235     bless { @_ }, $class;
236     }
237    
238 pcg 1.2 sub widget { $_[0]{widget} }
239    
240     sub AUTOLOAD {
241 pcg 1.3 $AUTOLOAD =~ /::([^:]+)$/ or Carp::confess "$AUTOLOAD: no such method (illegal name)";
242 pcg 1.5 ref $_[0]{widget} or Carp::confess "AUTOLOAD: non-method call $AUTOLOAD(@_)\n";
243 root 1.30 my $method = $_[0]{widget}->can ($1)
244 pcg 1.3 or Carp::confess "$AUTOLOAD: no such method";
245     # do NOT cache.. we are fats enough this way
246     unshift @_, shift->{widget};
247     &$method;
248     }
249    
250 pcg 1.5 sub destroy {
251     my ($self) = @_;
252 pcg 1.14 warn "destroy($self)";#d#
253 pcg 1.12
254 pcg 1.27 delete $self->{app};
255    
256 pcg 1.5 for (keys %$self) {
257 pcg 1.25 warn "$self->{$_} destroy" if UNIVERSAL::can ($self->{$_}, "destroy");
258 pcg 1.5 (delete $self->{$_})->destroy
259 pcg 1.13 if UNIVERSAL::can ($self->{$_}, "destroy");
260     # if (UNIVERSAL::isa ($self->{$_}, Glib::Object)
261     # && UNIVERSAL::isa ($self->{$_}, gtk::widget))
262     # && $self->{$_}->can("destroy");
263 pcg 1.5 }
264     }
265    
266     sub DESTROY {
267     my ($self) = @_;
268 pcg 1.14 warn "DESTROY($self)";#d#
269 pcg 1.5 }
270    
271 pcg 1.1 1;
272