… | |
… | |
145 | |
145 | |
146 | $self; |
146 | $self; |
147 | } |
147 | } |
148 | |
148 | |
149 | sub configure { |
149 | sub configure { |
150 | my ($self, $user, $rules) = @_; |
150 | my ($self, $app, $user, $rules) = @_; |
151 | |
151 | |
152 | if ($self->{name}->get_text ne $user->as_string) { |
152 | if ($self->{name}->get_text ne $user->as_string) { |
153 | $self->{name}->set_text ($user->as_string); |
153 | $self->{name}->set_text ($user->as_string); |
154 | |
154 | |
155 | $self->{imagebox}->remove ($_) for $self->{imagebox}->get_children; |
155 | $self->{imagebox}->remove ($_) for $self->{imagebox}->get_children; |
156 | $self->{imagebox}->add (gtk::image_from_data undef); |
156 | $self->{imagebox}->add (gtk::image_from_data undef); |
157 | $self->{imagebox}->show_all; |
157 | $self->{imagebox}->show_all; |
158 | |
158 | |
159 | if ($user->has_pic) { |
159 | if ($user->has_pic) { |
160 | # the big picture... |
160 | # the big picture... |
161 | appwin::userpic ($user->{name}, sub { |
161 | $app->userpic ($user->{name}, sub { |
162 | return unless $self->{imagebox}; |
162 | return unless $self->{imagebox}; |
|
|
163 | |
163 | if ($_[0]) { |
164 | if ($_[0]) { |
164 | $self->{imagebox}->remove ($_) for $self->{imagebox}->get_children; |
165 | $self->{imagebox}->remove ($_) for $self->{imagebox}->get_children; |
165 | $self->{imagebox}->add (gtk::image_from_data $_[0]); |
166 | $self->{imagebox}->add (gtk::image_from_data $_[0]); |
166 | $self->{imagebox}->show_all; |
167 | $self->{imagebox}->show_all; |
167 | } |
168 | } |
… | |
… | |
185 | package game; |
186 | package game; |
186 | |
187 | |
187 | use KGS::Constants; |
188 | use KGS::Constants; |
188 | use KGS::Game::Board; |
189 | use KGS::Game::Board; |
189 | |
190 | |
|
|
191 | use Gtk2::GoBoard; |
|
|
192 | |
190 | use base KGS::Listener::Game; |
193 | use base KGS::Listener::Game; |
191 | use base KGS::Game; |
194 | use base KGS::Game; |
192 | |
195 | |
193 | use base gtk::widget; |
196 | use base gtk::widget; |
194 | |
197 | |
… | |
… | |
227 | # board box (aspect/canvas) |
230 | # board box (aspect/canvas) |
228 | |
231 | |
229 | $self->{boardbox}->pack_start((my $frame = new Gtk2::Frame), 0, 1, 0); |
232 | $self->{boardbox}->pack_start((my $frame = new Gtk2::Frame), 0, 1, 0); |
230 | |
233 | |
231 | { |
234 | { |
232 | $frame->add(my $vbox = new Gtk2::VBox); |
235 | $frame->add (my $vbox = new Gtk2::VBox); |
233 | $vbox->add($self->{title} = new Gtk2::Label $title); |
236 | $vbox->add ($self->{title} = new Gtk2::Label $title); |
|
|
237 | |
|
|
238 | $vbox->add (my $hbox = new Gtk2::HBox); |
|
|
239 | |
|
|
240 | $hbox->pack_start (($self->{board_label} = new Gtk2::Label), 0, 1, 0); |
234 | |
241 | |
235 | $self->{moveadj} = new Gtk2::Adjustment 1, 1, 1, 1, 5, 0; |
242 | $self->{moveadj} = new Gtk2::Adjustment 1, 1, 1, 1, 5, 0; |
236 | |
243 | |
237 | $vbox->add(my $scale = new Gtk2::HScale $self->{moveadj}); |
244 | $hbox->pack_start ((my $scale = new Gtk2::HScale $self->{moveadj}), 1, 1, 0); |
238 | $scale->set_draw_value (0); |
245 | $scale->set_draw_value (0); |
239 | $scale->set_digits (0); |
246 | $scale->set_digits (0); |
240 | |
247 | |
241 | $self->{moveadj}->signal_connect (value_changed => sub { $self->update_board }); |
248 | $self->{moveadj}->signal_connect (value_changed => sub { $self->update_board }); |
242 | } |
249 | } |
243 | |
250 | |
244 | $self->{boardbox}->pack_start((my $aspect_frame = new Gtk2::AspectFrame "", 0.5, 0.5, 1, 0), 1, 1, 0); |
|
|
245 | $aspect_frame->set (border_width => 0, shadow_type => 'none', label_xalign => 0.5); |
|
|
246 | $self->{board_label} = $aspect_frame->get_label_widget; |
|
|
247 | |
|
|
248 | $aspect_frame->add($self->{board} = new board size => $self->{size}); |
251 | $self->{boardbox}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size}); |
249 | |
252 | |
250 | # RIGHT PANE |
253 | # RIGHT PANE |
251 | |
254 | |
252 | $self->{hpane}->pack2(($self->{vpane} = new Gtk2::VPaned), 1, 1); |
255 | $self->{hpane}->pack2(($self->{vpane} = new Gtk2::VPaned), 1, 1); |
253 | $self->{hpane}->set(position_set => 1); |
256 | $self->{hpane}->set(position_set => 1); |
… | |
… | |
262 | |
265 | |
263 | $vbox->pack_start((my $hbox = new Gtk2::HBox 1), 0, 1, 0); |
266 | $vbox->pack_start((my $hbox = new Gtk2::HBox 1), 0, 1, 0); |
264 | $hbox->add (($self->{userpanel}[WHITE] = new game::userpanel colour => WHITE)->widget); |
267 | $hbox->add (($self->{userpanel}[WHITE] = new game::userpanel colour => WHITE)->widget); |
265 | $hbox->add (($self->{userpanel}[BLACK] = new game::userpanel colour => BLACK)->widget); |
268 | $hbox->add (($self->{userpanel}[BLACK] = new game::userpanel colour => BLACK)->widget); |
266 | |
269 | |
267 | $vbox->pack_start(($self->{text} = new gtk::text)->widget, 1, 1, 0); |
270 | $vbox->pack_start(($self->{chat} = new chat), 1, 1, 0); |
268 | |
271 | |
269 | $vbox->pack_start(($self->{entry} = new Gtk2::Entry), 0, 1, 0); |
|
|
270 | $self->{entry}->signal_connect(activate => sub { |
272 | $self->{chat}->signal_connect(command => sub { |
271 | my $text = $self->{entry}->get_text; |
273 | my ($chat, $cmd, $arg) = @_; |
272 | $self->say($text) if $text =~ /\S/; |
274 | if ($cmd eq "rsave") { |
273 | $self->{entry}->set_text(""); |
275 | Storable::nstore { tree => $self->{tree}, curnode => $self->{curnode}, move => $self->{move} }, $arg;#d# |
|
|
276 | } else { |
|
|
277 | $self->{app}->do_command ($chat, $cmd, $arg, userlist => $self->{userlist}, game => $self); |
|
|
278 | } |
274 | }); |
279 | }); |
275 | |
280 | |
276 | $self->event_update_game; |
281 | $self->event_update_game; |
277 | $self; |
282 | $self; |
278 | } |
283 | } |
279 | |
284 | |
280 | sub event_update_users { |
285 | sub event_update_users { |
281 | my ($self, $add, $update, $remove) = @_; |
286 | my ($self, $add, $update, $remove) = @_; |
|
|
287 | |
|
|
288 | return unless $self->{userlist}; |
282 | |
289 | |
283 | $self->{userlist}->update ($add, $update, $remove); |
290 | $self->{userlist}->update ($add, $update, $remove); |
284 | |
291 | |
285 | my %important; |
292 | my %important; |
286 | $important{$self->{user1}{name}}++; |
293 | $important{$self->{user1}{name}}++; |
287 | $important{$self->{user2}{name}}++; |
294 | $important{$self->{user2}{name}}++; |
288 | $important{$self->{user3}{name}}++; |
295 | $important{$self->{user3}{name}}++; |
289 | |
296 | |
290 | if (my @users = grep $important{$_->{name}}, @$add) { |
297 | if (my @users = grep $important{$_->{name}}, @$add) { |
291 | $self->{text}->append_text ("\n<header>Joins:</header>"); |
298 | $self->{chat}->append_text ("\n<header>Joins:</header>"); |
292 | $self->{text}->append_text (" <user>" . $_->as_string . "</user>") for @users; |
299 | $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users; |
293 | } |
300 | } |
294 | if (my @users = grep $important{$_->{name}}, @$remove) { |
301 | if (my @users = grep $important{$_->{name}}, @$remove) { |
295 | $self->{text}->append_text ("\n<header>Parts:</header>"); |
302 | $self->{chat}->append_text ("\n<header>Parts:</header>"); |
296 | $self->{text}->append_text (" <user>" . $_->as_string . "</user>") for @users; |
303 | $self->{chat}->append_text (" <user>" . $_->as_string . "</user>") for @users; |
297 | } |
304 | } |
298 | |
305 | |
299 | } |
306 | } |
300 | |
307 | |
301 | sub join { |
308 | sub join { |
… | |
… | |
391 | }sgexi; |
398 | }sgexi; |
392 | |
399 | |
393 | $text .= $_; |
400 | $text .= $_; |
394 | } |
401 | } |
395 | |
402 | |
396 | $self->{text}->append_text ($text); |
403 | $self->{chat}->append_text ($text); |
397 | } |
404 | } |
398 | |
405 | |
399 | sub event_join { |
406 | sub event_join { |
400 | my ($self) = @_; |
407 | my ($self) = @_; |
401 | $self->SUPER::event_join; |
408 | $self->SUPER::event_join; |
… | |
… | |
414 | |
421 | |
415 | sub event_update_game { |
422 | sub event_update_game { |
416 | my ($self) = @_; |
423 | my ($self) = @_; |
417 | $self->SUPER::event_update_game; |
424 | $self->SUPER::event_update_game; |
418 | |
425 | |
419 | my $title = $self->{channel} ? $self->owner->as_string . " " . $self->opponent_string : "Game Window"; |
426 | return unless $self->{window}; |
|
|
427 | |
|
|
428 | my $title = defined $self->{channel} |
|
|
429 | ? $self->owner->as_string . " " . $self->opponent_string |
|
|
430 | : "Game Window"; |
420 | $self->{window}->set_title("KGS Game $title"); |
431 | $self->{window}->set_title("KGS Game $title"); |
421 | $self->{title}->set_text ($title); |
432 | $self->{title}->set_text ($title); |
422 | |
433 | |
423 | $self->{user}[BLACK] = $self->{user1}; |
434 | $self->{user}[BLACK] = $self->{user1}; |
424 | $self->{user}[WHITE] = $self->{user2}; |
435 | $self->{user}[WHITE] = $self->{user2}; |
… | |
… | |
471 | $text .= "</infoblock>"; |
482 | $text .= "</infoblock>"; |
472 | |
483 | |
473 | $self->{gatext} = \@ga; |
484 | $self->{gatext} = \@ga; |
474 | }; |
485 | }; |
475 | |
486 | |
476 | $self->{text}->append_text ($text); |
487 | $self->{chat}->append_text ($text); |
477 | } |
488 | } |
478 | |
489 | |
479 | sub event_update_rules { |
490 | sub event_update_rules { |
480 | my ($self, $rules) = @_; |
491 | my ($self, $rules) = @_; |
481 | |
492 | |
482 | $self->{userpanel}[$_]->configure ($self->{user}[$_], $rules) |
493 | $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules) |
483 | for BLACK, WHITE; |
494 | for BLACK, WHITE; |
484 | |
495 | |
485 | sound::play 3, "gamestart"; |
496 | sound::play 3, "gamestart"; |
486 | |
497 | |
487 | my $text = "\n<header>Game Rules</header>"; |
498 | my $text = "\n<header>Game Rules</header>"; |
… | |
… | |
501 | } elsif ($rules->{timesys} == TIMESYS_CANADIAN) { |
512 | } elsif ($rules->{timesys} == TIMESYS_CANADIAN) { |
502 | $text .= util::format_time $rules->{time}; |
513 | $text .= util::format_time $rules->{time}; |
503 | $text .= sprintf " + %s/%d CAN", util::format_time $rules->{interval}, $rules->{count}; |
514 | $text .= sprintf " + %s/%d CAN", util::format_time $rules->{interval}, $rules->{count}; |
504 | } |
515 | } |
505 | |
516 | |
506 | $self->{text}->append_text ("<infoblock>$text</infoblock>"); |
517 | $self->{chat}->append_text ("<infoblock>$text</infoblock>"); |
507 | } |
518 | } |
508 | |
519 | |
509 | sub inject_resign_game { |
520 | sub inject_resign_game { |
510 | my ($self, $msg) = @_; |
521 | my ($self, $msg) = @_; |
511 | |
522 | |
512 | sound::play 3, "resign"; |
523 | sound::play 3, "resign"; |
513 | |
524 | |
514 | $self->{text}->append_text ("\n<infoblock><header>Resign</header>" |
525 | $self->{chat}->append_text ("\n<infoblock><header>Resign</header>" |
515 | . "\n<user>" |
526 | . "\n<user>" |
516 | . (util::toxml $self->{user}[$msg->{player}]->as_string) |
527 | . (util::toxml $self->{user}[$msg->{player}]->as_string) |
517 | . "</user> resigned.</infoblock>"); |
528 | . "</user> resigned.</infoblock>"); |
518 | } |
529 | } |
519 | |
530 | |
520 | sub inject_final_result { |
531 | sub inject_final_result { |
521 | my ($self, $msg) = @_; |
532 | my ($self, $msg) = @_; |
522 | |
533 | |
523 | $self->{text}->append_text ("<infoblock>\n<header>Game Over</header>" |
534 | $self->{chat}->append_text ("<infoblock>\n<header>Game Over</header>" |
524 | . "\nWhite Score " . (util::toxml $msg->{whitescore}->as_string) |
535 | . "\nWhite Score " . (util::toxml $msg->{whitescore}->as_string) |
525 | . "\nBlack Score " . (util::toxml $msg->{blackscore}->as_string) |
536 | . "\nBlack Score " . (util::toxml $msg->{blackscore}->as_string) |
526 | . "</infoblock>" |
537 | . "</infoblock>" |
527 | ); |
538 | ); |
528 | } |
539 | } |
529 | |
540 | |
|
|
541 | sub event_challenge { |
|
|
542 | my ($self, $challenge) = @_; |
|
|
543 | |
|
|
544 | use KGS::Listener::Debug; |
|
|
545 | $self->{chat}->append_text ("\n".KGS::Listener::Debug::dumpval($challenge)); |
|
|
546 | } |
|
|
547 | |
530 | sub destroy { |
548 | sub destroy { |
531 | my ($self) = @_; |
549 | my ($self) = @_; |
|
|
550 | |
|
|
551 | delete $self->{app}{gamelist}{game}{$self->{channel}}; |
532 | $self->{userpanel}[$_] && (delete $self->{userpanel}[$_])->destroy |
552 | $self->{userpanel}[$_] && (delete $self->{userpanel}[$_])->destroy |
533 | for BLACK, WHITE; |
553 | for BLACK, WHITE; |
534 | $self->SUPER::destroy; |
554 | $self->SUPER::destroy; |
535 | delete $appwin::gamelist->{game}{$self->{channel}}; |
|
|
536 | } |
555 | } |
537 | |
556 | |
538 | 1; |
557 | 1; |
539 | |
558 | |