--- Gtk2-GoBoard/GoBoard.pm 2008/06/22 16:31:17 1.3 +++ Gtk2-GoBoard/GoBoard.pm 2008/06/25 07:09:35 1.7 @@ -68,9 +68,10 @@ use Scalar::Util; use POSIX qw(ceil); +use Carp (); use Gtk2; + use Games::Go::SimpleBoard; -use Carp (); use Glib::Object::Subclass Gtk2::AspectFrame::, @@ -139,20 +140,24 @@ or die "$path: $!"; } +our ($board_img, @black_img, @white_img, $shadow_img, + @triangle_img, @square_img, @circle_img, @cross_img); + sub load_images { - @::black_img = load_image "b-01.png"; - @::white_img = map +(load_image "w-0$_.png"), 1,2,3,4,5; - $::shadow_img = load_image "shadow.png"; - @::triangle_img = map +(load_image "triangle-$_.png"), qw(b w); - @::square_img = map +(load_image "square-$_.png"), qw(b w); - @::circle_img = map +(load_image "circle-$_.png"), qw(b w); - $::board_img = load_image "woodgrain-01.jpg"; + $board_img = load_image "woodgrain-01.jpg"; + @black_img = load_image "b-01.png"; + @white_img = map +(load_image "w-0$_.png"), 1,2,3,4,5; + $shadow_img = load_image "shadow.png"; + @triangle_img = map +(load_image "triangle-$_.png"), qw(b w); + @square_img = map +(load_image "square-$_.png" ), qw(b w); + @circle_img = map +(load_image "circle-$_.png" ), qw(b w); + @cross_img = map +(load_image "cross-$_.png" ), qw(b w); } sub INIT_INSTANCE { my $self = shift; - @::black_img + @black_img or load_images; $self->double_buffered (0); @@ -213,7 +218,7 @@ $self->{height} = $self->{canvas}->allocation->height; $self->draw_background; - $self->draw_board (delete $self->{board}, 0) if $self->{board}; + $self->draw_board ({ board => delete $self->{board}, label => delete $self->{label} }, 0) if $self->{board}; $self->{window}->clear_area (0, 0, $self->{width}, $self->{height}); delete $self->{idle}; @@ -224,6 +229,13 @@ 1; } +=item $board->set_board ($games_go_simpleboard) + +Sets the new board position to display from the current position stored in +the L object. + +=cut + sub set_board { my ($self, $board) = @_; @@ -325,13 +337,13 @@ my $pixbuf; - my ($bw, $bh) = ($::board_img->get_width, $::board_img->get_height); + my ($bw, $bh) = ($board_img->get_width, $board_img->get_height); if ($w < $bw && $h < $bh) { $pixbuf = new_pixbuf $w, $h, 0; - $::board_img->copy_area (0, 0, $w, $h, $pixbuf, 0, 0); + $board_img->copy_area (0, 0, $w, $h, $pixbuf, 0, 0); } else { - $pixbuf = scale_pixbuf $::board_img, $w, $h, $::config->{speed} ? 'nearest' : 'bilinear', 0; + $pixbuf = scale_pixbuf $board_img, $w, $h, 'bilinear', 0; # nearest for extra speed } my $linew = int ($w / 40 / $size); @@ -355,9 +367,9 @@ $x = $kx[$x] - $hs / 2; $y = $ky[$y] - $hs / 2; # we use the shadow mask... not perfect, but I want to finish this - $::shadow_img->composite ($pixbuf, + $shadow_img->composite ($pixbuf, $x, $y, ($hs + 1) x2, $x, $y, - $hs / $::shadow_img->get_width, $hs / $::shadow_img->get_height, + $hs / $shadow_img->get_width, $hs / $shadow_img->get_height, 'bilinear', 255); }; @@ -418,7 +430,7 @@ my $put_stack = sub { my ($x, $y, $dx, $dy, $ox, $oy) = @_; - my $mark = $self->{board}{board}[$x-1][$y-1]; + my $mark = $self->{board}[$x-1][$y-1]; if ($mark & ~MARK_LABEL) { my $stack = $stack{$mark} ||= $self->draw_stack ($mark, $edge); @@ -455,19 +467,19 @@ # labels are handled here because they are quite rare # (and we can't draw text into pixbufs easily) - my $mark = $self->{board}{board}[$x-1][$y-1]; + my $mark = $self->{board}[$x-1][$y-1]; if ($mark & MARK_LABEL) { my $white = $mark & MARK_W ? 0 : 0xffffff00; - if ($white) { - $self->center_text ($self->{backgroundpm}, 0, - $areai[0] + $ofs * 1.1, $areai[1] + $ofs * 1.1, - $ofs * 0.7, $self->{board}{label}[$x-1][$y-1]); - } + $self->center_text ($self->{backgroundpm}, 0, + $areai[0] + $ofs * 1.1, $areai[1] + $ofs * 1.1, + $ofs * 0.7, $self->{label}[$x-1][$y-1]) + if $white; + $self->center_text ($self->{backgroundpm}, $white, $areai[0] + $ofs, $areai[1] + $ofs, - $ofs * 0.7, $self->{board}{label}[$x-1][$y-1]); + $ofs * 0.7, $self->{label}[$x-1][$y-1]); } undef $pb; @@ -485,20 +497,20 @@ my $csize = ceil $size; my $shadow = $size * SHADOW; - for my $stone ($mark & MARK_W ? @::white_img : @::black_img) { + for my $stone ($mark & MARK_W ? @white_img : @black_img) { my $base = new_pixbuf +(ceil $size + $shadow) x2, 1, 0x00000000; # zeroeth the shadow if (~$mark & MARK_GRAYED and $mark & (MARK_B | MARK_W)) { - $::shadow_img->composite ( + $shadow_img->composite ( $base, $shadow, $shadow, $csize, $csize, $shadow, $shadow, - $size / $::shadow_img->get_width, $size / $::shadow_img->get_height, + $size / $shadow_img->get_width, $size / $shadow_img->get_height, 'bilinear', 128 ); } - for ([MARK_B, $mark & MARK_GRAYED ? 96 : 255, 1], - [MARK_W, $mark & MARK_GRAYED ? 160 : 255, TRAD_SIZE_W / TRAD_SIZE_B]) { + for ([MARK_B, $mark & MARK_GRAYED ? 106 : 255, 1], + [MARK_W, $mark & MARK_GRAYED ? 190 : 255, TRAD_SIZE_W / TRAD_SIZE_B]) { my ($mask, $alpha, $scale) = @$_; if ($mark & $mask) { $stone->composite ( @@ -510,8 +522,8 @@ } # then the small stones (always using the first image) - for ([MARK_SMALL_B, $::black_img[0]], - [MARK_SMALL_W, $::white_img[0]]) { + for ([MARK_SMALL_B, $black_img[0]], + [MARK_SMALL_W, $white_img[0]]) { my ($mask, $img) = @$_; if ($mark & $mask) { $img->composite ( @@ -525,16 +537,17 @@ # and lastly any markers my $dark_bg = ! ! ($mark & MARK_B); - for ([MARK_CIRCLE, $::circle_img[$dark_bg]], - [MARK_TRIANGLE, $::triangle_img[$dark_bg]], - [MARK_SQUARE, $::square_img[$dark_bg]], - [MARK_KO, $::square_img[$dark_bg]]) { + for ([MARK_CIRCLE, $circle_img[$dark_bg]], + [MARK_TRIANGLE, $triangle_img[$dark_bg]], + [MARK_SQUARE, $square_img[$dark_bg]], + [MARK_CROSS, $cross_img[$dark_bg]], + [MARK_KO, $square_img[$dark_bg]]) { my ($mask, $img) = @$_; if ($mark & $mask) { $img->composite ( $base, 0, 0, $size, $size, 0, 0, $size / $img->get_width, $size / $img->get_height, - 'bilinear', 176 + 'bilinear', $dark_bg ? 176 : 190 ); } } @@ -542,28 +555,36 @@ push @stack, $base; } - \@stack; + \@stack } sub draw_board { my ($self, $new, $dopaint) = @_; - ($self->{board}, my $old) = ($new, $self->{board}); - - my $draw_stone = $self->{draw_stone}; + my $newboard = $new->{board}; + my $newlabel = $new->{label}; if ($self->{backgroundpb}) { + my $draw_stone = $self->{draw_stone}; + + my $oldboard = $self->{board} ||= []; + my $oldlabel = $self->{label} ||= []; + my @areas; my $size1 = $self->{size} - 1; for my $x (0 .. $size1) { - my $old = $old->{board}[$x]; - my $new = $new->{board}[$x]; + my $old = $oldboard->[$x] ||= []; + my $new = $newboard->[$x]; for my $y (0 .. $size1) { - push @areas, $draw_stone->($x+1, $y+1) - if $old->[$y] != $new->[$y]; + next if $old->[$y] == $new->[$y]; + + $old -> [$y] = $new -> [$y]; + $oldlabel->[$x][$y] = $newlabel->[$x][$y]; + + push @areas, $draw_stone->($x+1, $y+1); } } @@ -580,6 +601,12 @@ $self->{window}->clear_area (@$_) for @areas; } } + } else { + no strict 'refs'; + + # straight copy + $self->{board} = [map [@$_], @$newboard]; + $self->{label} = [map [@$_], @$newlabel]; } } @@ -592,11 +619,11 @@ my ($x, $y) = @{$self->{cursorpos}}; - my $mark = $self->{board}{board}[$x][$y]; + my $mark = $self->{board}[$x][$y]; $mark = $self->{cursor}->($mark, $x, $y) if $show; - local $self->{board}{board}[$x][$y] = $mark; + local $self->{board}[$x][$y] = $mark; $self->{window}->clear_area (@{ $self->{draw_stone}->($x + 1, $y + 1) }); }