… | |
… | |
15 | use List::Util; |
15 | use List::Util; |
16 | use Errno; |
16 | use Errno; |
17 | |
17 | |
18 | init Gtk; |
18 | init Gtk; |
19 | |
19 | |
20 | $HACK = 1; # do NEVER enable. ;) |
20 | our $HACK = 1; # do NEVER enable. ;) |
|
|
21 | our $DEBUG_EXPOSE = 1; |
21 | |
22 | |
22 | if ($HACK) { |
23 | if ($HACK) { |
23 | $KGS::debug = 1; |
24 | $KGS::debug = 1; |
24 | } |
25 | } |
|
|
26 | |
|
|
27 | our $VERSION = "0.1"; |
25 | |
28 | |
26 | our $config; |
29 | our $config; |
27 | our $LIBDIR = "."; |
30 | our $LIBDIR = "."; |
28 | our $IMGDIR = "$LIBDIR/images"; |
31 | our $IMGDIR = "$LIBDIR/images"; |
29 | our $SNDDIR = "$LIBDIR/sounds"; |
32 | our $SNDDIR = "$LIBDIR/sounds"; |
… | |
… | |
54 | { |
57 | { |
55 | #my $audioserver = new Audio::Play(0); |
58 | #my $audioserver = new Audio::Play(0); |
56 | my %sound; |
59 | my %sound; |
57 | $SIG{CHLD} = 'IGNORE'; |
60 | $SIG{CHLD} = 'IGNORE'; |
58 | |
61 | |
59 | for (qw(alarm warning move)) { |
62 | for (qw(alarm warning move pass ring connect user_unknown)) { |
60 | local $/; |
63 | local $/; |
61 | open my $snd, "<", "$SNDDIR/$_" |
64 | open my $snd, "<", "$SNDDIR/$_" |
62 | or die "$SNDDIR: $!"; |
65 | or die "$SNDDIR/$_: $!"; |
63 | binmode $snd; |
66 | binmode $snd; |
64 | |
67 | |
65 | $sound{$_} = new Audio::Data; |
68 | $sound{$_} = new Audio::Data; |
66 | $sound{$_}->Load($snd); |
69 | $sound{$_}->Load($snd); |
67 | } |
70 | } |
68 | |
71 | |
69 | sub play_sound { |
72 | sub play_sound { |
|
|
73 | my ($annoyancy, $sound) = @_; |
|
|
74 | # annoyany 1 => important, annoyance 2 => useful, annoyancy 3 => not useful |
70 | if (fork == 0) { |
75 | if (fork == 0) { |
71 | if (my $audioserver = new Audio::Play(1)) { |
76 | if (my $audioserver = new Audio::Play(1)) { |
72 | $audioserver->play ($sound{$_[0]}); |
77 | $audioserver->play ($sound{$sound}); |
73 | } |
78 | } |
74 | Gtk->_exit(0); |
79 | Gtk->_exit(0); |
75 | } |
80 | } |
76 | } |
81 | } |
77 | } |
82 | } |
… | |
… | |
85 | my $state = -r $staterc ? Storable::retrieve($staterc) : {}; |
90 | my $state = -r $staterc ? Storable::retrieve($staterc) : {}; |
86 | my @widgets; |
91 | my @widgets; |
87 | |
92 | |
88 | $config = $state->{config} ||= {}; |
93 | $config = $state->{config} ||= {}; |
89 | |
94 | |
90 | $config{speed} = 1;#d# optimize for speed or memory? |
95 | $config{speed} = 0;#d# optimize for speed or memory? |
91 | $config{conserve_memory} = 0; |
96 | $config{conserve_memory} = 0; |
92 | |
97 | |
93 | # grr... more gtk+ brokenness |
98 | # grr... more gtk+ brokenness |
94 | my %get = ( |
99 | my %get = ( |
95 | hpane_position => sub { ($_[0]->children)[0]->allocation->[2] }, |
100 | hpane_position => sub { ($_[0]->children)[0]->allocation->[2] }, |
… | |
… | |
187 | |
192 | |
188 | if (0) { |
193 | if (0) { |
189 | use KGS::Constants; |
194 | use KGS::Constants; |
190 | |
195 | |
191 | for (19) { |
196 | for (19) { |
192 | my $board = new game size => $_; |
197 | my $board = new game %{Storable::retrieve "testboard.storable"}; |
|
|
198 | |
|
|
199 | if (0) { |
193 | $board->{board} = new KGS::Game::Board; |
200 | $board->{board} = new KGS::Game::Board; |
194 | $board->{board}{board}[0][0] = MARK_B; |
201 | $board->{board}{board}[0][0] = MARK_B; |
195 | $board->{board}{board}[1][1] = MARK_GRAY_B | MARK_SMALL_W; |
202 | $board->{board}{board}[1][1] = MARK_GRAY_B | MARK_SMALL_W; |
196 | $board->{board}{board}[2][2] = MARK_W | MARK_TRIANGLE; |
203 | $board->{board}{board}[2][2] = MARK_W | MARK_TRIANGLE; |
197 | $board->{board}{board}[1][2] = MARK_B | MARK_LABEL; |
204 | $board->{board}{board}[1][2] = MARK_B | MARK_LABEL; |
198 | $board->{board}{label}[1][2] = "198"; |
205 | $board->{board}{label}[1][2] = "198"; |
199 | $board->{board}{board}[0][2] = MARK_W | MARK_LABEL; |
206 | $board->{board}{board}[0][2] = MARK_W | MARK_LABEL; |
200 | $board->{board}{label}[0][2] = "AWA"; |
207 | $board->{board}{label}[0][2] = "AWA"; |
|
|
208 | } |
201 | $board->{window}->show_all; |
209 | $board->{window}->show_all; |
202 | } |
210 | } |
203 | } |
211 | } |
204 | |
212 | |
205 | main Gtk; |
213 | main Gtk; |
… | |
… | |
289 | } |
297 | } |
290 | $self->{conn}->feed_data($buf); |
298 | $self->{conn}->feed_data($buf); |
291 | }; |
299 | }; |
292 | |
300 | |
293 | # now login |
301 | # now login |
294 | $self->{conn}->login($self->{login}->get_text, $self->{password}->get_text); |
302 | $self->{conn}->login("kgsueme $VERSION $^O", $self->{login}->get_text, $self->{password}->get_text); |
295 | } |
303 | } |
296 | |
304 | |
297 | sub inject_login { |
305 | sub inject_login { |
298 | my ($self, $msg) = @_; |
306 | my ($self, $msg) = @_; |
299 | |
307 | |
… | |
… | |
302 | |
310 | |
303 | if ($msg->{success}) { |
311 | if ($msg->{success}) { |
304 | for (keys %{$::config->{rooms}}) { |
312 | for (keys %{$::config->{rooms}}) { |
305 | $self->{roomlist}->join_room($_); |
313 | $self->{roomlist}->join_room($_); |
306 | } |
314 | } |
|
|
315 | ::play_sound 3, "connect"; |
|
|
316 | } elsif ($msg->{result} eq "user unknown") { |
|
|
317 | ::play_sound 2, "user_unknown"; |
|
|
318 | } else { |
|
|
319 | ::play_sound 2, "warning"; |
307 | } |
320 | } |
308 | } |
321 | } |
309 | |
322 | |
310 | sub event_disconnect { } |
323 | sub event_disconnect { } |
311 | |
324 | |
… | |
… | |
417 | ::state $self->{gamelist}, "room::gamelist", $self->{name}, clist_column_widths => [20, 120, 120, 120]; |
430 | ::state $self->{gamelist}, "room::gamelist", $self->{name}, clist_column_widths => [20, 120, 120, 120]; |
418 | |
431 | |
419 | $self->{gamelist}->signal_connect(select_row => sub { |
432 | $self->{gamelist}->signal_connect(select_row => sub { |
420 | my $game = $self->{gamelist}->get_row_data($_[1]) |
433 | my $game = $self->{gamelist}->get_row_data($_[1]) |
421 | or return; |
434 | or return; |
422 | $self->{game}{$game->{channel}} ||= new game %$game, conn => $self->{conn}; |
435 | $self->{game}{$game->{channel}} ||= new game %$game, conn => $self->{conn}, room => $self; |
423 | $self->{game}{$game->{channel}}->join; |
436 | $self->{game}{$game->{channel}}->join; |
424 | $self->{gamelist}->unselect_all; |
437 | $self->{gamelist}->unselect_all; |
425 | }); |
438 | }); |
426 | |
439 | |
427 | $vpane->add(my $vbox = new Gtk::VBox); |
440 | $vpane->add(my $vbox = new Gtk::VBox); |
… | |
… | |
459 | my ($self) = @_; |
472 | my ($self) = @_; |
460 | $self->SUPER::part; |
473 | $self->SUPER::part; |
461 | |
474 | |
462 | delete $::config->{rooms}{$self->{channel}}; |
475 | delete $::config->{rooms}{$self->{channel}}; |
463 | $self->{window}->hide_all; |
476 | $self->{window}->hide_all; |
464 | $self->event_update_users; |
|
|
465 | $self->event_update_games; |
|
|
466 | } |
477 | } |
467 | |
478 | |
468 | sub inject_msg_room { |
479 | sub inject_msg_room { |
469 | my ($self, $msg) = @_; |
480 | my ($self, $msg) = @_; |
470 | |
481 | |
… | |
… | |
574 | |
585 | |
575 | $self->{moveadj}->signal_connect (value_changed => sub { |
586 | $self->{moveadj}->signal_connect (value_changed => sub { |
576 | $self->{board} = new KGS::Game::Board $self->{size}; |
587 | $self->{board} = new KGS::Game::Board $self->{size}; |
577 | $self->{board}->interpret_path ([@{$self->{path}}[0 .. $self->{moveadj}->value - 1]]); |
588 | $self->{board}->interpret_path ([@{$self->{path}}[0 .. $self->{moveadj}->value - 1]]); |
578 | |
589 | |
579 | $self->repaint_board; |
590 | my $area = $self->repaint_board; |
580 | |
591 | |
581 | # force a redraw (not perfect(?)) |
592 | # force a redraw (not perfect(?)) |
582 | expose_event($self->{canvas}, $self, { area => [0, 0, @{$self->{canvas}->allocation}[2,3]] }); |
593 | $self->expose ($area); |
583 | |
594 | |
584 | $self->{text}->backward_delete($self->{text}->get_length); |
595 | $self->{text}->backward_delete($self->{text}->get_length); |
585 | $self->{text}->insert(undef, undef, undef, KGS::Listener::Debug::dumpval([$self->{board}{time},$self->{board}{captures}]). $self->{board}{comment}); |
596 | $self->{text}->insert(undef, undef, undef, KGS::Listener::Debug::dumpval([$self->{board}{time},$self->{board}{captures}]). $self->{board}{comment}); |
586 | }); |
597 | }); |
|
|
598 | |
|
|
599 | $self->{moveadj}->upper (scalar @{$self->{path}}) if $self->{path}; |
587 | } |
600 | } |
588 | |
601 | |
589 | Gtk::Widget->push_visual (Gtk::Gdk::Rgb->get_visual); |
602 | Gtk::Widget->push_visual (Gtk::Gdk::Rgb->get_visual); |
590 | Gtk::Widget->push_colormap (Gtk::Gdk::Rgb->get_cmap); |
603 | Gtk::Widget->push_colormap (Gtk::Gdk::Rgb->get_cmap); |
591 | $vbox->pack_start(($self->{canvas} = new Gtk::DrawingArea), 1, 1, 0); |
604 | $vbox->pack_start(($self->{canvas} = new Gtk::DrawingArea), 1, 1, 0); |
… | |
… | |
643 | } |
656 | } |
644 | |
657 | |
645 | sub configure_event { |
658 | sub configure_event { |
646 | my ($widget, $self, $event) = @_; |
659 | my ($widget, $self, $event) = @_; |
647 | delete $self->{stack}; |
660 | delete $self->{stack}; |
|
|
661 | delete $self->{pixbuf}; |
|
|
662 | delete $self->{board_shown}; |
648 | delete $self->{background}; |
663 | delete $self->{background}; |
649 | $self->repaint_board; |
664 | $self->repaint_board; |
650 | 1; |
665 | 1; |
651 | } |
666 | } |
652 | |
667 | |
… | |
… | |
684 | |
699 | |
685 | # create a stack of stones |
700 | # create a stack of stones |
686 | sub create_stack { |
701 | sub create_stack { |
687 | my ($self, $mark, $size, $rand) = @_; |
702 | my ($self, $mark, $size, $rand) = @_; |
688 | |
703 | |
689 | my $shadow = $size * 0.06; |
704 | my $shadow = $size * 0.05; |
690 | |
705 | |
691 | my $c = \$self->{stack}{$mark}; |
706 | my $c = \$self->{stack}{$mark}; |
692 | unless ($$c) { |
707 | unless ($$c) { |
693 | for my $stone ($mark & (MARK_W | MARK_GRAY_W) ? @::white_img : @::black_img) { |
708 | for my $stone ($mark & (MARK_W | MARK_GRAY_W) ? @::white_img : @::black_img) { |
694 | my $base = new_pixbuf $size + $shadow, $size + $shadow, 1, 1; |
709 | my $base = new_pixbuf $size + $shadow, $size + $shadow, 1, 1; |
… | |
… | |
728 | $::config{speed} ? INTERP_NEAREST : INTERP_HYPER, 192 |
743 | $::config{speed} ? INTERP_NEAREST : INTERP_HYPER, 192 |
729 | ); |
744 | ); |
730 | } |
745 | } |
731 | } |
746 | } |
732 | |
747 | |
733 | # and lastly any markers (labels NYI) |
748 | # and lastly any markers |
734 | my $dark_bg = ! ! ($mark & (MARK_B | MARK_GRAY_B)); |
749 | my $dark_bg = ! ! ($mark & (MARK_B | MARK_GRAY_B)); |
735 | |
750 | |
736 | for ([MARK_CIRCLE, $::circle_img[$dark_bg]], |
751 | for ([MARK_CIRCLE, $::circle_img[$dark_bg]], |
737 | [MARK_TRIANGLE, $::triangle_img[$dark_bg]], |
752 | [MARK_TRIANGLE, $::triangle_img[$dark_bg]], |
738 | [MARK_SQUARE, $::square_img[$dark_bg]]) { |
753 | [MARK_SQUARE, $::square_img[$dark_bg]]) { |
… | |
… | |
793 | } |
808 | } |
794 | |
809 | |
795 | sub repaint_board { |
810 | sub repaint_board { |
796 | my ($self) = @_; |
811 | my ($self) = @_; |
797 | my $canvas = $self->{canvas}; |
812 | my $canvas = $self->{canvas}; |
|
|
813 | my $expose_area = undef; |
798 | |
814 | |
799 | return unless $self->{board}; |
815 | return $expose_area unless $self->{board}; |
800 | |
816 | |
801 | my ($w, $h) = @{$canvas->allocation}[2,3]; |
817 | my ($w, $h) = @{$canvas->allocation}[2,3]; |
802 | |
818 | |
803 | my $s = $w > $h ? $h : $w; |
819 | my $s = $w > $h ? $h : $w; |
804 | |
820 | |
… | |
… | |
806 | |
822 | |
807 | my $size = $self->{size}; |
823 | my $size = $self->{size}; |
808 | |
824 | |
809 | my $border = int ($s / ($size + 3) * 0.5); |
825 | my $border = int ($s / ($size + 3) * 0.5); |
810 | my $s2 = $s - $border * 2; |
826 | my $s2 = $s - $border * 2; |
811 | my $edge = int ($s2 / ($size + 1) * 0.97); |
827 | my $edge = int ($s2 / ($size + 1) * 0.95); |
812 | my $ofs = int ($edge / 2); |
828 | my $ofs = int ($edge / 2); |
813 | |
829 | |
814 | my @k = map int ($s2 * $_ / ($size+1) + $border + 0.5), 0 .. $size; |
830 | my @k = map int ($s2 * $_ / ($size+1) + $border + 0.5), 0 .. $size; |
815 | |
831 | |
816 | my $pixbuf; |
832 | my $pixbuf; |
817 | |
833 | |
|
|
834 | my $oldboard; |
|
|
835 | |
818 | if ($self->{background}) { |
836 | if ($self->{background}) { |
|
|
837 | if ($oldboard = $self->{board_shown}) { |
|
|
838 | $pixbuf = $self->{pixbuf}; |
|
|
839 | } else { |
819 | $pixbuf = $self->{background}->copy; |
840 | $pixbuf = $self->{background}->copy; |
|
|
841 | $expose_area = [0, 0, $s, $s]; |
|
|
842 | } |
820 | } else { |
843 | } else { |
|
|
844 | $expose_area = [0, 0, $s, $s]; |
|
|
845 | |
821 | my ($bw, $bh) = ($::board_img->get_width, $::board_img->get_height); |
846 | my ($bw, $bh) = ($::board_img->get_width, $::board_img->get_height); |
822 | |
847 | |
823 | if ($s < $bw && $s < $bh) { |
848 | if ($s < $bw && $s < $bh) { |
824 | $pixbuf = new_pixbuf $s, $s, $::config{conserve_memory} ? 0 : 1, 0; |
849 | $pixbuf = new_pixbuf $s, $s, $::config{conserve_memory} ? 0 : 1, 0; |
825 | $::board_img->copy_area (0, 0, $s, $s, $pixbuf, 0, 0); |
850 | $::board_img->copy_area (0, 0, $s, $s, $pixbuf, 0, 0); |
… | |
… | |
857 | # hoshi-points(!)#d# |
882 | # hoshi-points(!)#d# |
858 | # caching of empty board gfx(!)#d# |
883 | # caching of empty board gfx(!)#d# |
859 | |
884 | |
860 | for my $x (1 .. $size) { |
885 | for my $x (1 .. $size) { |
861 | for my $y (1 .. $size) { |
886 | for my $y (1 .. $size) { |
|
|
887 | my ($dx, $dy) = ($k[$x] - $ofs, $k[$y] - $ofs); |
862 | my $mark = $self->{board}{board}[$x-1][$y-1]; |
888 | my $mark = $self->{board}{board}[$x-1][$y-1]; |
|
|
889 | my $old = $oldboard ? $oldboard->{board}[$x-1][$y-1] : 0; |
|
|
890 | |
|
|
891 | if ($oldboard && $old != $mark) { |
|
|
892 | my $shadow = $edge * 0.05; |
|
|
893 | my $new_expose = [$dx, $dy, $edge + $shadow, $edge + $shadow]; |
|
|
894 | $self->{background}->copy_area (@$new_expose, $pixbuf, $dx, $dy); |
|
|
895 | $expose_area = $expose_area |
|
|
896 | ? Gtk::Gdk::Rectangle->union ($expose_area, $new_expose) |
|
|
897 | : $new_expose; |
|
|
898 | } |
863 | |
899 | |
864 | if ($mark) { |
900 | if ($mark) { |
865 | my ($dx, $dy) = ($k[$x] - $ofs, $k[$y] - $ofs); |
|
|
866 | my $pb = $self->create_stack($mark, $edge, $x * 17 + $y * 11 ); |
901 | my $pb = $self->create_stack($mark, $edge, $x * 17 + $y * 11 ); |
867 | |
902 | |
868 | $pb->composite ($pixbuf, $dx, $dy, $pb->get_width, $pb->get_height, |
903 | $pb->composite ($pixbuf, $dx, $dy, $pb->get_width, $pb->get_height, |
869 | $dx, $dy, 1, 1, $::config{speed} ? INTERP_NEAREST : INTERP_NEAREST, 255); |
904 | $dx, $dy, 1, 1, $::config{speed} ? INTERP_NEAREST : INTERP_NEAREST, 255); |
870 | |
905 | |
871 | # labels are handled here because they are quite rare |
906 | # labels are handled here because they are quite rare |
872 | if ($mark & MARK_LABEL) { |
907 | if ($mark & MARK_LABEL) { |
873 | pixbuf_text $pixbuf, $mark & (MARK_W | MARK_GRAY_W) ? 0 : 1, |
908 | my $white = $mark & (MARK_W | MARK_GRAY_W) ? 0 : 1; |
|
|
909 | |
|
|
910 | if ($white) { |
|
|
911 | pixbuf_text $pixbuf, 0, |
|
|
912 | $k[$x] + $ofs * 0.1, $k[$y] + $ofs * 0.1, $ofs * 0.7, |
|
|
913 | $self->{board}{label}[$x-1][$y-1]; |
|
|
914 | } |
|
|
915 | pixbuf_text $pixbuf, $white, |
874 | $k[$x], $k[$y], $ofs * 0.7, |
916 | $k[$x], $k[$y], $ofs * 0.7, |
875 | $self->{board}{label}[$x-1][$y-1]; |
917 | $self->{board}{label}[$x-1][$y-1]; |
876 | } |
918 | } |
877 | |
919 | |
|
|
920 | # old pixmap&mask-way. that was fast ;( |
878 | #my ($pm, $bm) = $self->create_stack($gc, $mark, $edge, $x * 17 + $y * 11 ); |
921 | #my ($pm, $bm) = $self->create_stack($gc, $mark, $edge, $x * 17 + $y * 11 ); |
879 | |
922 | |
880 | #$gc->set_clip_mask ($bm); |
923 | #$gc->set_clip_mask ($bm); |
881 | #$gc->set_clip_origin ($dx, $dy); |
924 | #$gc->set_clip_origin ($dx, $dy); |
882 | #$pixmap->draw_pixmap ($gc, $pm, 0, 0, $dx, $dy, $edge, $edge); |
925 | #$pixmap->draw_pixmap ($gc, $pm, 0, 0, $dx, $dy, $edge, $edge); |
883 | } |
926 | } |
884 | } |
927 | } |
885 | } |
928 | } |
886 | } |
|
|
887 | |
929 | |
|
|
930 | $self->{board_shown} = Storable::dclone $self->{board}; |
|
|
931 | #d# save |
|
|
932 | #Storable::nstore { board => $self->{board}, size => $self->{size}, path => $self->{path}}, "testboard.storable"; |
|
|
933 | |
|
|
934 | $expose_area; |
|
|
935 | } |
|
|
936 | |
888 | sub expose_event { |
937 | sub expose { |
889 | my ($widget, $self, $event) = @_; |
938 | my ($self, $area) = @_; |
890 | |
939 | |
891 | $self->{pixbuf} or return; |
940 | if ($area && $self->{pixbuf}) { |
892 | |
941 | my ($x, $y, $w, $h) = @$area; |
893 | my ($ox, $oy, $s) = @{$self->{offsets}}; |
942 | my ($ox, $oy, $s) = @{$self->{offsets}}; |
894 | |
943 | |
895 | my ($x, $y, $w, $h) = |
|
|
896 | @{Gtk::Gdk::Rectangle->intersect( |
|
|
897 | $event->{area}, |
|
|
898 | [$ox, $oy, $s, $s] |
|
|
899 | )}; |
|
|
900 | |
|
|
901 | if (defined $x) { |
|
|
902 | $self->{pixbuf}->render_to_drawable ($self->{canvas}->window, $self->{canvas}->style->white_gc, |
944 | $self->{pixbuf}->render_to_drawable ($self->{canvas}->window, $self->{canvas}->style->white_gc, |
903 | $x - $ox, $y - $oy, $x, $y, $w, $h); |
945 | $x, $y, $x + $ox, $y + $oy, $w, $h); |
|
|
946 | $self->{canvas}->window->draw_rectangle ($self->{canvas}->style->black_gc, 0, |
|
|
947 | $x + $ox - 1, $y + $oy - 1, $w + 2, $h + 2) if $::DEBUG_EXPOSE; |
|
|
948 | |
904 | #$self->{canvas}->window->draw_pixmap ( |
949 | #$self->{canvas}->window->draw_pixmap ( |
905 | # $self->{canvas}->style->white_gc, |
950 | # $self->{canvas}->style->white_gc, |
906 | # $self->{pixmap}, |
951 | # $self->{pixmap}, |
907 | # $x - $ox, $y - $oy, $x, $y, $w, $h, |
952 | # $x - $ox, $y - $oy, $x, $y, $w, $h, |
908 | #); |
953 | #); |
909 | } |
954 | } |
|
|
955 | } |
|
|
956 | |
|
|
957 | sub expose_event { |
|
|
958 | my ($widget, $self, $event) = @_; |
|
|
959 | |
|
|
960 | $self->{pixbuf} or return; |
|
|
961 | |
|
|
962 | my $area = $event->{area}; |
|
|
963 | my ($ox, $oy, $s) = @{$self->{offsets}}; |
|
|
964 | |
|
|
965 | $self->expose (Gtk::Gdk::Rectangle->intersect ( |
|
|
966 | [$area->[0] - $ox, $area->[1] - $oy, $area->[2], $area->[3]], |
|
|
967 | [0, 0, $s, $s], |
|
|
968 | )); |
|
|
969 | |
910 | 1; |
970 | 1; |
911 | } |
971 | } |
912 | |
972 | |
913 | sub event_update_tree { |
973 | sub event_update_tree { |
914 | my ($self) = @_; |
974 | my ($self) = @_; |
… | |
… | |
922 | if ($self->{moveadj}->value >= $move - 1 || !$self->{moveadj}->value) { |
982 | if ($self->{moveadj}->value >= $move - 1 || !$self->{moveadj}->value) { |
923 | $self->{moveadj}->set_value ($move); |
983 | $self->{moveadj}->set_value ($move); |
924 | } |
984 | } |
925 | } |
985 | } |
926 | |
986 | |
|
|
987 | sub event_part { |
|
|
988 | my ($self) = @_; |
|
|
989 | $self->SUPER::event_part; |
|
|
990 | (delete $self->{window})->destroy; # hmm.. why does this keep the object alive? puzzling.. ahh.. the callbacks ;) |
|
|
991 | delete $self->{room}{game}{$self->{channel}}; |
|
|
992 | } |
|
|
993 | |
927 | sub event_move { |
994 | sub event_move { |
928 | ::play_sound "move"; |
995 | my ($self, $pass) = @_; |
|
|
996 | ::play_sound 1, $pass ? "pass" : "move"; |
|
|
997 | } |
|
|
998 | |
|
|
999 | sub DESTROY {#d# |
|
|
1000 | warn "DESTROY(@_)\n";#d# |
929 | } |
1001 | } |
930 | |
1002 | |
931 | 1; |
1003 | 1; |
932 | |
1004 | |
933 | |
1005 | |