ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/gtk.pl
Revision: 1.6
Committed: Sat May 31 15:08:32 2003 UTC (21 years ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +2 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 package gtk;
2
3 use Carp;
4
5 our $text_renderer = new Gtk2::CellRendererText;
6 our $int_renderer = new Gtk2::CellRendererText;
7 $int_renderer->set (xalign => 1);
8
9 our $state = $util::state->{gtk} ||= {};
10
11 # shows the properties of a glib object
12 sub info {
13 my ($idx, $obj) = @_;
14 return if $seen{$idx}++;
15 print "\n$idx\n";
16 for ($obj->list_properties) {
17 printf "%-16s %-24s %-24s %s\n", $_->{name}, $_->{type}, (join ":", @{$_->{flags}}), $_->{descr};
18 }
19 }
20
21 # grr... more gtk+ brokenness
22 my %get = (
23 window_size => sub { [ ($_[0]->allocation->values)[2,3] ] },
24 #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] },
25 column_size => sub { $_[0]->get("width") || $_[0]->get("fixed_width") },
26 clist_column_widths => sub {
27 $_[0]{column_widths};
28 },
29 );
30
31 my %set = (
32 window_size => sub { $_[0]->set_default_size(@{$_[1]}) },
33 #window_pos => sub { $_[0]->set_uposition(@{$_[1]}) if @{$_[1]} },
34 column_size => sub { $_[0]->set(fixed_width => $_[1]) },
35 clist_column_widths => sub {
36 my ($w, $v) = @_;
37 $v->[$_] && $w->set_column_width($_, $v->[$_]) for 0..$#$v;
38 $w->{column_widths} = $v;
39 $w->signal_connect(resize_column => sub { $v->[$_[1]] = $_[2]; });
40 },
41 );
42
43 my %widget;
44
45 sub state {
46 my ($widget, $class, $instance, %attr) = @_;
47
48 while (my ($k, $v) = each %attr) {
49 my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
50 $v = $state->{$class}{"*"}{$get} if exists $state->{$class}{"*"} && exists $state->{$class}{"*"}{$get};
51 $v = $state->{$class}{$instance}{$get} if defined $instance && exists $state->{$class}{$instance} && exists $state->{$class}{$instance}{$get};
52 $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v);
53 }
54
55 $widget->signal_connect(destroy => sub { delete $widget{$widget}; 0 });
56
57 $widget{$widget} = [$widget, $class, $instance, \%attr];
58 Scalar::Util::weaken $widget{$widget}[0];
59 }
60
61 sub save_state {
62 for (grep $_, values %widget) {
63 my ($widget, $class, $instance, $attr) = @$_;
64
65 $widget->realize if $widget->can("realize");
66
67 while (my ($k, $v) = each %$attr) {
68 my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
69 $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get);
70 warn "got $widget -> $get => $v\n";
71
72 $state->{$class}{"*"}{$get} = $v;
73 $state->{$class}{$instance}{$get} = $v if defined $instance;
74 }
75 }
76 }
77
78 # make a clist unselectable
79 sub clist_autosort {
80 my $w = shift;
81 my ($c, $o) = (-1);
82 for (0..$w->columns-1) {
83 $w->signal_connect(click_column => sub {
84 if ($_[1] != $c) {
85 $c = $_[1];
86 $o = 0;
87 } else {
88 $o = !$o;
89 }
90 $w->set_sort_column($c);
91 $w->set_sort_type($o ? "descending" : "ascending");
92 $w->sort;
93 });
94 }
95 }
96
97 package gtk::widget;
98
99 # hacked gtk pseudo-widget
100
101 sub new {
102 my $class = shift;
103 bless { @_ }, $class;
104 }
105
106 sub widget { $_[0]{widget} }
107
108 sub AUTOLOAD {
109 $AUTOLOAD =~ /::([^:]+)$/ or Carp::confess "$AUTOLOAD: no such method (illegal name)";
110 ref $_[0]{widget} or Carp::confess "AUTOLOAD: non-method call $AUTOLOAD(@_)\n";
111 my $method = $_[0]{widget}->can($1)
112 or Carp::confess "$AUTOLOAD: no such method";
113 # do NOT cache.. we are fats enough this way
114 unshift @_, shift->{widget};
115 &$method;
116 }
117
118 sub destroy {
119 my ($self) = @_;
120 for (keys %$self) {
121 (delete $self->{$_})->destroy
122 if UNIVERSAL::isa ($self->{$_}, Glib::Object) && $self->{$_}->can("destroy");
123 }
124 }
125
126 sub DESTROY {
127 my ($self) = @_;
128 }
129
130 package gtk::text;
131
132 use base gtk::widget;
133
134 sub new {
135 my $class = shift;
136 my $self = $class->SUPER::new(@_);
137
138 $self->{buffer} = new Gtk2::TextBuffer undef;
139
140 $self->{widget} = new_with_buffer Gtk2::TextView $self->{buffer};
141
142 $self->{widget}->set_wrap_mode ("word");
143
144 $self;
145 }
146
147 sub append_text {
148 my ($self, $text) = @_;
149
150 $self->{buffer}->insert ($self->{buffer}->get_end_iter, $text);
151 }
152
153 sub set_text {
154 my ($self, $text) = @_;
155
156 $self->{buffer}->set_text ("");
157 $self->append_text ($text);
158 }
159
160 package gtk::userlist;
161
162 use base gtk::widget;
163
164 sub new {
165 my $class = shift;
166 my $self = $class->SUPER::new(@_);
167
168 $self->{model} = new Gtk2::ListStore Glib::Scalar, Glib::String, Glib::String, Glib::Int, Glib::String;
169
170 $self->{widget} = new Gtk2::TreeView $self->{model};
171
172 $self->{widget}->set_search_column(1);
173
174 my $column = $self->{rlcolumns}[0] =
175 Gtk2::TreeViewColumn->new_with_attributes ("Name", $gtk::text_renderer, text => 1);
176 $column->set_sort_column_id(1);
177 $column->set(resizable => 1);
178 $column->set(sizing => 'fixed');
179 gtk::state $column, "userlist::model::Name", undef, column_size => 120;
180 $self->{widget}->append_column ($column);
181
182 my $column = $self->{rlcolumns}[1] =
183 Gtk2::TreeViewColumn->new_with_attributes ("Rank", $gtk::text_renderer, text => 2);
184 $column->set_sort_column_id(3);
185 $column->set(resizable => 1);
186 $column->set(sizing => 'fixed');
187 gtk::state $column, "userlist::model::Rank", undef, column_size => 40;
188 $self->{widget}->append_column ($column);
189
190 my $column = $self->{rlcolumns}[2] =
191 Gtk2::TreeViewColumn->new_with_attributes ("Flags", $gtk::text_renderer, text => 4);
192 $column->set(resizable => 1);
193 $column->set(sizing => 'fixed');
194 gtk::state $column, "userlist::model::Flags", undef, column_size => 80;
195 $self->{widget}->append_column ($column);
196
197 $self->{widget}->signal_connect(row_activated => sub {
198 my ($widget, $path, $column) = @_;
199 my $user = $self->{model}->get ($self->{model}->get_iter ($path), 0);
200 warn "selected user $user\n";
201 });
202
203 $self;
204 }
205
206 sub update {
207 my ($self, $users) = @_;
208
209 remove Glib::Source delete $self->{event_update} if $self->{event_update};
210 $self->{event_update} ||= add Glib::Timeout 100, sub {
211 my $l = $self->{model};
212
213 $l->clear;
214
215 for (values %$users) {
216 $l->set ($l->append,
217 0, $_,
218 1, $_->{name},
219 2, $_->rank_string,
220 3, $_->rank,
221 4, "?");
222 }
223
224 delete $self->{event_update};
225 0;
226 };
227 }
228
229 1;
230