ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/gtk.pl
Revision: 1.5
Committed: Sat May 31 13:58:32 2003 UTC (21 years ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +112 -27 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;
143 }
144
145 sub append_text {
146 my ($self, $text) = @_;
147
148 $self->{buffer}->insert ($self->{buffer}->get_end_iter, $text);
149 }
150
151 sub set_text {
152 my ($self, $text) = @_;
153
154 $self->{buffer}->set_text ("");
155 $self->append_text ($text);
156 }
157
158 package gtk::userlist;
159
160 use base gtk::widget;
161
162 sub new {
163 my $class = shift;
164 my $self = $class->SUPER::new(@_);
165
166 $self->{model} = new Gtk2::ListStore Glib::Scalar, Glib::String, Glib::String, Glib::Int, Glib::String;
167
168 $self->{widget} = new Gtk2::TreeView $self->{model};
169
170 $self->{widget}->set_search_column(1);
171
172 my $column = $self->{rlcolumns}[0] =
173 Gtk2::TreeViewColumn->new_with_attributes ("Name", $gtk::text_renderer, text => 1);
174 $column->set_sort_column_id(1);
175 $column->set(resizable => 1);
176 $column->set(sizing => 'fixed');
177 gtk::state $column, "userlist::model::Name", undef, column_size => 120;
178 $self->{widget}->append_column ($column);
179
180 my $column = $self->{rlcolumns}[1] =
181 Gtk2::TreeViewColumn->new_with_attributes ("Rank", $gtk::text_renderer, text => 2);
182 $column->set_sort_column_id(3);
183 $column->set(resizable => 1);
184 $column->set(sizing => 'fixed');
185 gtk::state $column, "userlist::model::Rank", undef, column_size => 40;
186 $self->{widget}->append_column ($column);
187
188 my $column = $self->{rlcolumns}[2] =
189 Gtk2::TreeViewColumn->new_with_attributes ("Flags", $gtk::text_renderer, text => 4);
190 $column->set(resizable => 1);
191 $column->set(sizing => 'fixed');
192 gtk::state $column, "userlist::model::Flags", undef, column_size => 80;
193 $self->{widget}->append_column ($column);
194
195 $self->{widget}->signal_connect(row_activated => sub {
196 my ($widget, $path, $column) = @_;
197 my $user = $self->{model}->get ($self->{model}->get_iter ($path), 0);
198 warn "selected user $user\n";
199 });
200
201 $self;
202 }
203
204 sub update {
205 my ($self, $users) = @_;
206
207 remove Glib::Source delete $self->{event_update} if $self->{event_update};
208 $self->{event_update} ||= add Glib::Timeout 100, sub {
209 my $l = $self->{model};
210
211 $l->clear;
212
213 for (values %$users) {
214 $l->set ($l->append,
215 0, $_,
216 1, $_->{name},
217 2, $_->rank_string,
218 3, $_->rank,
219 4, "?");
220 }
221
222 delete $self->{event_update};
223 0;
224 };
225 }
226
227 1;
228