… | |
… | |
18 | } |
18 | } |
19 | } |
19 | } |
20 | |
20 | |
21 | # grr... more gtk+ brokenness |
21 | # grr... more gtk+ brokenness |
22 | my %get = ( |
22 | my %get = ( |
|
|
23 | # fix tre_ typoe when gtk2 fixed |
23 | window_size => sub { [ ($_[0]->allocation->values)[2,3] ] }, |
24 | window_size => sub { [ ($_[0]->allocation->values)[2,3] ] }, |
24 | #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] }, |
25 | #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] }, |
25 | column_size => sub { $_[0]->get("width") || $_[0]->get("fixed_width") }, |
26 | column_size => sub { $_[0]->get("width") || $_[0]->get("fixed_width") }, |
26 | clist_column_widths => sub { |
27 | modelsortorder => sub { [ $_[0]->gtk_tree_sortable_get_sort_column_id ] }, |
27 | $_[0]{column_widths}; |
|
|
28 | }, |
|
|
29 | ); |
28 | ); |
30 | |
29 | |
31 | my %set = ( |
30 | my %set = ( |
32 | window_size => sub { $_[0]->set_default_size(@{$_[1]}) }, |
31 | window_size => sub { $_[0]->set_default_size (@{$_[1]}) }, |
33 | #window_pos => sub { $_[0]->set_uposition(@{$_[1]}) if @{$_[1]} }, |
32 | #window_pos => sub { $_[0]->set_uposition (@{$_[1]}) if @{$_[1]} }, |
34 | column_size => sub { $_[0]->set(fixed_width => $_[1]) }, |
33 | column_size => sub { $_[0]->set (fixed_width => $_[1]) }, |
35 | clist_column_widths => sub { |
34 | modelsortorder => sub { $_[0]->gtk_tree_sortable_set_sort_column_id (@{$_[1]}) }, |
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 | ); |
35 | ); |
42 | |
36 | |
43 | my %widget; |
37 | my %widget; |
44 | |
38 | |
45 | sub state { |
39 | sub state { |
… | |
… | |
50 | $v = $state->{$class}{"*"}{$get} if exists $state->{$class}{"*"} && exists $state->{$class}{"*"}{$get}; |
44 | $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}; |
45 | $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); |
46 | $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v); |
53 | } |
47 | } |
54 | |
48 | |
55 | $widget->signal_connect(destroy => sub { delete $widget{$widget}; 0 }); |
49 | #$widget->signal_connect(destroy => sub { delete $widget{$widget}; 0 }); |
56 | |
50 | |
57 | $widget{$widget} = [$widget, $class, $instance, \%attr]; |
51 | $widget{$widget} = [$widget, $class, $instance, \%attr]; |
58 | Scalar::Util::weaken $widget{$widget}[0]; |
52 | Scalar::Util::weaken $widget{$widget}[0]; |
59 | } |
53 | } |
60 | |
54 | |
61 | sub save_state { |
55 | sub save_state { |
62 | for (grep $_, values %widget) { |
56 | for (grep $_, values %widget) { |
63 | my ($widget, $class, $instance, $attr) = @$_; |
57 | my ($widget, $class, $instance, $attr) = @$_; |
64 | |
58 | |
|
|
59 | next unless $widget; # no destroy => widget may be undef |
|
|
60 | |
65 | $widget->realize if $widget->can("realize"); |
61 | $widget->realize if $widget->can("realize"); |
66 | |
62 | |
67 | while (my ($k, $v) = each %$attr) { |
63 | while (my ($k, $v) = each %$attr) { |
68 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
64 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
69 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
65 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
70 | warn "got $widget -> $get => $v\n"; |
|
|
71 | |
66 | |
72 | $state->{$class}{"*"}{$get} = $v; |
67 | $state->{$class}{"*"}{$get} = $v; |
73 | $state->{$class}{$instance}{$get} = $v if defined $instance; |
68 | $state->{$class}{$instance}{$get} = $v if defined $instance; |
74 | } |
69 | } |
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 | } |
70 | } |
95 | } |
71 | } |
96 | |
72 | |
97 | package gtk::widget; |
73 | package gtk::widget; |
98 | |
74 | |
… | |
… | |
155 | |
131 | |
156 | $self->{buffer}->set_text (""); |
132 | $self->{buffer}->set_text (""); |
157 | $self->append_text ($text); |
133 | $self->append_text ($text); |
158 | } |
134 | } |
159 | |
135 | |
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(sizing => 'grow-only'); |
|
|
178 | $self->{widget}->append_column ($column); |
|
|
179 | |
|
|
180 | my $column = $self->{rlcolumns}[1] = |
|
|
181 | Gtk2::TreeViewColumn->new_with_attributes ("Rk", $gtk::text_renderer, text => 2); |
|
|
182 | $column->set_sort_column_id(3); |
|
|
183 | $column->set(sizing => 'grow-only'); |
|
|
184 | $self->{widget}->append_column ($column); |
|
|
185 | |
|
|
186 | my $column = $self->{rlcolumns}[2] = |
|
|
187 | Gtk2::TreeViewColumn->new_with_attributes ("Flags", $gtk::text_renderer, text => 4); |
|
|
188 | $column->set(resizable => 1); |
|
|
189 | $column->set(sizing => 'grow-only'); |
|
|
190 | $self->{widget}->append_column ($column); |
|
|
191 | |
|
|
192 | $self->{widget}->signal_connect(row_activated => sub { |
|
|
193 | my ($widget, $path, $column) = @_; |
|
|
194 | my $user = $self->{model}->get ($self->{model}->get_iter ($path), 0); |
|
|
195 | warn "selected user $user\n"; |
|
|
196 | }); |
|
|
197 | |
|
|
198 | $self; |
|
|
199 | } |
|
|
200 | |
|
|
201 | sub update { |
|
|
202 | my ($self, $users) = @_; |
|
|
203 | |
|
|
204 | remove Glib::Source delete $self->{event_update} if $self->{event_update}; |
|
|
205 | $self->{event_update} ||= add Glib::Timeout 100, sub { |
|
|
206 | my $l = $self->{model}; |
|
|
207 | |
|
|
208 | $l->clear; |
|
|
209 | |
|
|
210 | for (values %$users) { |
|
|
211 | $l->set ($l->append, |
|
|
212 | 0, $_, |
|
|
213 | 1, $_->{name}, |
|
|
214 | 2, $_->rank_string, |
|
|
215 | 3, $_->rank, |
|
|
216 | 4, "?"); |
|
|
217 | } |
|
|
218 | |
|
|
219 | delete $self->{event_update}; |
|
|
220 | 0; |
|
|
221 | }; |
|
|
222 | } |
|
|
223 | |
|
|
224 | 1; |
136 | 1; |
225 | |
137 | |