… | |
… | |
211 | $self->{idle} ||= add Glib::Idle sub { |
211 | $self->{idle} ||= add Glib::Idle sub { |
212 | $self->{width} = $self->{canvas}->allocation->width; |
212 | $self->{width} = $self->{canvas}->allocation->width; |
213 | $self->{height} = $self->{canvas}->allocation->height; |
213 | $self->{height} = $self->{canvas}->allocation->height; |
214 | $self->draw_background; |
214 | $self->draw_background; |
215 | |
215 | |
216 | $self->draw_board (delete $self->{board}, 0) if $self->{board}; |
216 | $self->draw_board ({ board => delete $self->{board}, label => delete $self->{label} }, 0) if $self->{board}; |
217 | $self->{window}->clear_area (0, 0, $self->{width}, $self->{height}); |
217 | $self->{window}->clear_area (0, 0, $self->{width}, $self->{height}); |
218 | |
218 | |
219 | delete $self->{idle}; |
219 | delete $self->{idle}; |
220 | |
220 | |
221 | 0; |
221 | 0; |
222 | }; |
222 | }; |
223 | |
223 | |
224 | 1; |
224 | 1; |
225 | } |
225 | } |
|
|
226 | |
|
|
227 | =item $board->set_board ($games_go_simpleboard) |
|
|
228 | |
|
|
229 | Sets the new board position to display from the current position stored in |
|
|
230 | the L<Games::Go::SimpleBoard> object. |
|
|
231 | |
|
|
232 | =cut |
226 | |
233 | |
227 | sub set_board { |
234 | sub set_board { |
228 | my ($self, $board) = @_; |
235 | my ($self, $board) = @_; |
229 | |
236 | |
230 | $self->cursor (0); |
237 | $self->cursor (0); |
… | |
… | |
416 | my %stack; |
423 | my %stack; |
417 | |
424 | |
418 | my $put_stack = sub { |
425 | my $put_stack = sub { |
419 | my ($x, $y, $dx, $dy, $ox, $oy) = @_; |
426 | my ($x, $y, $dx, $dy, $ox, $oy) = @_; |
420 | |
427 | |
421 | my $mark = $self->{board}{board}[$x-1][$y-1]; |
428 | my $mark = $self->{board}[$x-1][$y-1]; |
422 | |
429 | |
423 | if ($mark & ~MARK_LABEL) { |
430 | if ($mark & ~MARK_LABEL) { |
424 | my $stack = $stack{$mark} ||= $self->draw_stack ($mark, $edge); |
431 | my $stack = $stack{$mark} ||= $self->draw_stack ($mark, $edge); |
425 | |
432 | |
426 | $stack->[($x ^ $y) % @$stack] |
433 | $stack->[($x ^ $y) % @$stack] |
… | |
… | |
453 | $self->{backgroundpm}->draw_pixbuf ($self->style->black_gc, $pb, |
460 | $self->{backgroundpm}->draw_pixbuf ($self->style->black_gc, $pb, |
454 | 0, 0, @areai, 'max', 0, 0); |
461 | 0, 0, @areai, 'max', 0, 0); |
455 | |
462 | |
456 | # labels are handled here because they are quite rare |
463 | # labels are handled here because they are quite rare |
457 | # (and we can't draw text into pixbufs easily) |
464 | # (and we can't draw text into pixbufs easily) |
458 | my $mark = $self->{board}{board}[$x-1][$y-1]; |
465 | my $mark = $self->{board}[$x-1][$y-1]; |
459 | |
466 | |
460 | if ($mark & MARK_LABEL) { |
467 | if ($mark & MARK_LABEL) { |
461 | my $white = $mark & MARK_W ? 0 : 0xffffff00; |
468 | my $white = $mark & MARK_W ? 0 : 0xffffff00; |
462 | |
469 | |
463 | if ($white) { |
|
|
464 | $self->center_text ($self->{backgroundpm}, 0, |
470 | $self->center_text ($self->{backgroundpm}, 0, |
465 | $areai[0] + $ofs * 1.1, $areai[1] + $ofs * 1.1, |
471 | $areai[0] + $ofs * 1.1, $areai[1] + $ofs * 1.1, |
466 | $ofs * 0.7, $self->{board}{label}[$x-1][$y-1]); |
472 | $ofs * 0.7, $self->{label}[$x-1][$y-1]) |
467 | } |
473 | if $white; |
|
|
474 | |
468 | $self->center_text ($self->{backgroundpm}, $white, |
475 | $self->center_text ($self->{backgroundpm}, $white, |
469 | $areai[0] + $ofs, $areai[1] + $ofs, |
476 | $areai[0] + $ofs, $areai[1] + $ofs, |
470 | $ofs * 0.7, $self->{board}{label}[$x-1][$y-1]); |
477 | $ofs * 0.7, $self->{label}[$x-1][$y-1]); |
471 | } |
478 | } |
472 | |
479 | |
473 | undef $pb; |
480 | undef $pb; |
474 | |
481 | |
475 | [@areai]; |
482 | [@areai]; |
… | |
… | |
540 | } |
547 | } |
541 | |
548 | |
542 | push @stack, $base; |
549 | push @stack, $base; |
543 | } |
550 | } |
544 | |
551 | |
545 | \@stack; |
552 | \@stack |
546 | } |
553 | } |
547 | |
554 | |
548 | sub draw_board { |
555 | sub draw_board { |
549 | my ($self, $new, $dopaint) = @_; |
556 | my ($self, $new, $dopaint) = @_; |
550 | |
557 | |
551 | ($self->{board}, my $old) = ($new, $self->{board}); |
558 | my $newboard = $new->{board}; |
552 | |
559 | my $newlabel = $new->{label}; |
553 | my $draw_stone = $self->{draw_stone}; |
|
|
554 | |
560 | |
555 | if ($self->{backgroundpb}) { |
561 | if ($self->{backgroundpb}) { |
|
|
562 | my $draw_stone = $self->{draw_stone}; |
|
|
563 | |
|
|
564 | my $oldboard = $self->{board} ||= []; |
|
|
565 | my $oldlabel = $self->{label} ||= []; |
|
|
566 | |
556 | my @areas; |
567 | my @areas; |
557 | |
568 | |
558 | my $size1 = $self->{size} - 1; |
569 | my $size1 = $self->{size} - 1; |
559 | |
570 | |
560 | for my $x (0 .. $size1) { |
571 | for my $x (0 .. $size1) { |
561 | my $old = $old->{board}[$x]; |
572 | my $old = $oldboard->[$x] ||= []; |
562 | my $new = $new->{board}[$x]; |
573 | my $new = $newboard->[$x]; |
563 | |
574 | |
564 | for my $y (0 .. $size1) { |
575 | for my $y (0 .. $size1) { |
|
|
576 | next if $old->[$y] == $new->[$y]; |
|
|
577 | |
|
|
578 | $old -> [$y] = $new -> [$y]; |
|
|
579 | $oldlabel->[$x][$y] = $newlabel->[$x][$y]; |
|
|
580 | |
565 | push @areas, $draw_stone->($x+1, $y+1) |
581 | push @areas, $draw_stone->($x+1, $y+1); |
566 | if $old->[$y] != $new->[$y]; |
|
|
567 | } |
582 | } |
568 | } |
583 | } |
569 | |
584 | |
570 | if ($dopaint && @areas) { |
585 | if ($dopaint && @areas) { |
571 | # a single full clear_area is way faster than many single calls here |
586 | # a single full clear_area is way faster than many single calls here |
… | |
… | |
578 | } else { |
593 | } else { |
579 | # update all the affected rectangles |
594 | # update all the affected rectangles |
580 | $self->{window}->clear_area (@$_) for @areas; |
595 | $self->{window}->clear_area (@$_) for @areas; |
581 | } |
596 | } |
582 | } |
597 | } |
|
|
598 | } else { |
|
|
599 | no strict 'refs'; |
|
|
600 | |
|
|
601 | # straight copy |
|
|
602 | $self->{board} = [map [@$_], @$newboard]; |
|
|
603 | $self->{label} = [map [@$_], @$newlabel]; |
583 | } |
604 | } |
584 | } |
605 | } |
585 | |
606 | |
586 | sub cursor { |
607 | sub cursor { |
587 | my ($self, $show) = @_; |
608 | my ($self, $show) = @_; |
… | |
… | |
590 | && $self->{cursor} |
611 | && $self->{cursor} |
591 | && $self->{backgroundpb}; |
612 | && $self->{backgroundpb}; |
592 | |
613 | |
593 | my ($x, $y) = @{$self->{cursorpos}}; |
614 | my ($x, $y) = @{$self->{cursorpos}}; |
594 | |
615 | |
595 | my $mark = $self->{board}{board}[$x][$y]; |
616 | my $mark = $self->{board}[$x][$y]; |
596 | |
617 | |
597 | $mark = $self->{cursor}->($mark, $x, $y) if $show; |
618 | $mark = $self->{cursor}->($mark, $x, $y) if $show; |
598 | |
619 | |
599 | local $self->{board}{board}[$x][$y] = $mark; |
620 | local $self->{board}[$x][$y] = $mark; |
600 | $self->{window}->clear_area (@{ $self->{draw_stone}->($x + 1, $y + 1) }); |
621 | $self->{window}->clear_area (@{ $self->{draw_stone}->($x + 1, $y + 1) }); |
601 | } |
622 | } |
602 | |
623 | |
603 | sub motion { |
624 | sub motion { |
604 | my ($self) = @_; |
625 | my ($self) = @_; |