… | |
… | |
4 | |
4 | |
5 | our $text_renderer = new Gtk2::CellRendererText; |
5 | our $text_renderer = new Gtk2::CellRendererText; |
6 | our $int_renderer = new Gtk2::CellRendererText; |
6 | our $int_renderer = new Gtk2::CellRendererText; |
7 | $int_renderer->set (xalign => 1); |
7 | $int_renderer->set (xalign => 1); |
8 | |
8 | |
9 | our $state = $util::state->{gtk} || {}; |
9 | our $state = $util::state->{gtk} ||= {}; |
10 | |
10 | |
11 | # shows the properties of a glib object |
11 | # shows the properties of a glib object |
12 | sub info { |
12 | sub info { |
13 | my ($idx, $obj) = @_; |
13 | my ($idx, $obj) = @_; |
14 | last if $seen{$idx}++; |
14 | return if $seen{$idx}++; |
15 | print "\n$idx\n"; |
15 | print "\n$idx\n"; |
16 | for ($obj->list_properties) { |
16 | for ($obj->list_properties) { |
17 | printf "%-16s %-24s %-24s %s\n", $_->{name}, $_->{type}, (join ":", @{$_->{flags}}), $_->{descr}; |
17 | printf "%-16s %-24s %-24s %s\n", $_->{name}, $_->{type}, (join ":", @{$_->{flags}}), $_->{descr}; |
18 | } |
18 | } |
19 | } |
19 | } |
20 | |
20 | |
21 | # grr... more gtk+ brokenness |
21 | # grr... more gtk+ brokenness |
22 | my %get = ( |
22 | my %get = ( |
23 | window_size => sub { [ ($_[0]->allocation->values)[2,3] ] }, |
23 | window_size => sub { [ ($_[0]->allocation->values)[2,3] ] }, |
24 | #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] }, |
24 | #window_pos => sub { die KGS::Listener::Debug::dumpval [ $_[0]->get_root_origin ] }, |
|
|
25 | column_size => sub { $_[0]->get("width") || $_[0]->get("fixed_width") }, |
25 | clist_column_widths => sub { |
26 | clist_column_widths => sub { |
26 | $_[0]{column_widths}; |
27 | $_[0]{column_widths}; |
27 | }, |
28 | }, |
28 | ); |
29 | ); |
29 | |
30 | |
30 | my %set = ( |
31 | my %set = ( |
31 | window_size => sub { $_[0]->set_default_size(@{$_[1]}) }, |
32 | window_size => sub { $_[0]->set_default_size(@{$_[1]}) }, |
32 | #window_pos => sub { $_[0]->set_uposition(@{$_[1]}) if @{$_[1]} }, |
33 | #window_pos => sub { $_[0]->set_uposition(@{$_[1]}) if @{$_[1]} }, |
|
|
34 | column_size => sub { $_[0]->set(fixed_width => $_[1]) }, |
33 | clist_column_widths => sub { |
35 | clist_column_widths => sub { |
34 | my ($w, $v) = @_; |
36 | my ($w, $v) = @_; |
35 | $v->[$_] && $w->set_column_width($_, $v->[$_]) for 0..$#$v; |
37 | $v->[$_] && $w->set_column_width($_, $v->[$_]) for 0..$#$v; |
36 | $w->{column_widths} = $v; |
38 | $w->{column_widths} = $v; |
37 | $w->signal_connect(resize_column => sub { $v->[$_[1]] = $_[2]; }); |
39 | $w->signal_connect(resize_column => sub { $v->[$_[1]] = $_[2]; }); |
38 | }, |
40 | }, |
39 | ); |
41 | ); |
40 | |
42 | |
|
|
43 | my %widget; |
|
|
44 | |
41 | sub state { |
45 | sub state { |
42 | my ($widget, $class, $instance, %attr) = @_; |
46 | my ($widget, $class, $instance, %attr) = @_; |
43 | |
47 | |
44 | while (my ($k, $v) = each %attr) { |
48 | while (my ($k, $v) = each %attr) { |
45 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
49 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
46 | $v = $state->{$class}{"*"}{$get} if exists $state->{$class}{"*"}{$get}; |
50 | $v = $state->{$class}{"*"}{$get} if exists $state->{$class}{"*"} && exists $state->{$class}{"*"}{$get}; |
47 | $v = $state->{$class}{$instance}{$get} if exists $state->{$class}{$instance}{$get}; |
51 | $v = $state->{$class}{$instance}{$get} if defined $instance && exists $state->{$class}{$instance} && exists $state->{$class}{$instance}{$get}; |
48 | $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v); |
52 | $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v); |
49 | } |
53 | } |
50 | |
54 | |
|
|
55 | $widget->signal_connect(destroy => sub { delete $widget{$widget}; 0 }); |
|
|
56 | |
51 | $widget = [$widget, $class, $instance, \%attr]; |
57 | $widget{$widget} = [$widget, $class, $instance, \%attr]; |
52 | Scalar::Util::weaken $widget->[0]; |
58 | Scalar::Util::weaken $widget{$widget}[0]; |
53 | |
|
|
54 | @widgets = (grep $_->[0], @widgets, $widget); |
|
|
55 | } |
59 | } |
56 | |
60 | |
57 | sub save_state { |
61 | sub save_state { |
58 | for (@widgets) { |
62 | for (grep $_, values %widget) { |
59 | if ($_->[0]) { |
|
|
60 | my ($widget, $class, $instance, $attr) = @$_; |
63 | my ($widget, $class, $instance, $attr) = @$_; |
61 | |
64 | |
62 | $widget->realize if $widget->isa(Gtk2::Widget::); |
65 | $widget->realize if $widget->can("realize"); |
63 | |
66 | |
64 | while (my ($k, $v) = each %$attr) { |
67 | while (my ($k, $v) = each %$attr) { |
65 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
68 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
66 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
69 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
|
|
70 | warn "got $widget -> $get => $v\n"; |
67 | |
71 | |
68 | warn "$class : $get = $v\n";#d# |
|
|
69 | $state->{$class}{"*"}{$get} = $v; |
72 | $state->{$class}{"*"}{$get} = $v; |
70 | $state->{$class}{$instance}{$get} = $v; |
73 | $state->{$class}{$instance}{$get} = $v if defined $instance; |
71 | } |
|
|
72 | } |
74 | } |
73 | ::status("save_state", "layout saved"); |
|
|
74 | } |
75 | } |
75 | } |
76 | } |
76 | |
77 | |
77 | # make a clist unselectable |
78 | # make a clist unselectable |
78 | sub clist_autosort { |
79 | sub clist_autosort { |
… | |
… | |
104 | |
105 | |
105 | sub widget { $_[0]{widget} } |
106 | sub widget { $_[0]{widget} } |
106 | |
107 | |
107 | sub AUTOLOAD { |
108 | sub AUTOLOAD { |
108 | $AUTOLOAD =~ /::([^:]+)$/ or Carp::confess "$AUTOLOAD: no such method (illegal name)"; |
109 | $AUTOLOAD =~ /::([^:]+)$/ or Carp::confess "$AUTOLOAD: no such method (illegal name)"; |
|
|
110 | ref $_[0]{widget} or Carp::confess "AUTOLOAD: non-method call $AUTOLOAD(@_)\n"; |
109 | my $method = $_[0]{widget}->can($1) |
111 | my $method = $_[0]{widget}->can($1) |
110 | or Carp::confess "$AUTOLOAD: no such method"; |
112 | or Carp::confess "$AUTOLOAD: no such method"; |
111 | # do NOT cache.. we are fats enough this way |
113 | # do NOT cache.. we are fats enough this way |
112 | unshift @_, shift->{widget}; |
114 | unshift @_, shift->{widget}; |
113 | &$method; |
115 | &$method; |
114 | } |
116 | } |
115 | |
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 | |
116 | package gtk::text; |
130 | package gtk::text; |
117 | |
131 | |
118 | use base gtk::widget; |
132 | use base gtk::widget; |
119 | |
133 | |
120 | sub new { |
134 | sub new { |
121 | my $class = shift; |
135 | my $class = shift; |
122 | my $self = $class->SUPER::new(@_); |
136 | my $self = $class->SUPER::new(@_); |
123 | |
137 | |
124 | $self->{buffer} = new Gtk2::TextBuffer undef; |
138 | $self->{buffer} = new Gtk2::TextBuffer undef; |
125 | |
139 | |
126 | $self->{widget} = new Gtk2::TextView; |
140 | $self->{widget} = new_with_buffer Gtk2::TextView $self->{buffer}; |
127 | |
141 | |
128 | $self; |
142 | $self; |
129 | } |
143 | } |
130 | |
144 | |
131 | sub append_text { |
145 | sub append_text { |
132 | my ($self, $text); |
146 | my ($self, $text) = @_; |
|
|
147 | |
|
|
148 | $self->{buffer}->insert ($self->{buffer}->get_end_iter, $text); |
133 | } |
149 | } |
134 | |
150 | |
135 | sub set_text { |
151 | sub set_text { |
136 | my ($self, $text) = @_; |
152 | my ($self, $text) = @_; |
137 | |
153 | |
138 | #clear |
154 | $self->{buffer}->set_text (""); |
139 | #$self->add_text ($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 | }; |
140 | } |
225 | } |
141 | |
226 | |
142 | 1; |
227 | 1; |
143 | |
228 | |