You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki-map/HexGrid/Region.pm

67 lines
2.2 KiB

1 year ago
package HexGrid::Region;
use v5.30;
use Moo;
use MooX::Aliases;
use Hash::Merge qw(merge);
use HexGrid::Tile;
use Data::Dumper;
use feature "signatures";
no warnings "experimental::signatures";
has tiles => (is => 'rw', default => sub { {} });
has subregions => (is => 'rw', default => sub { {} });
has name => (is => 'rw', required => 1);
has defaults => (is => 'rw', default => sub { {} });
has id_suffix => (is => 'rw', default => '_region');
sub add_tile($this, $tile) { $this->{tiles}{$tile->{nw}}{$tile->{sw}} = $tile; }
sub make_tile_at($this, $nw, $sw, %tile_settings)
{
my %settings = %{merge(\%tile_settings, $this->{defaults})};
# say STDERR Dumper(\%settings);
$settings{css_class} = HexGrid::to_id($this->{name});
$this->add_tile(HexGrid::Tile::at($nw, $sw, %settings));
}
sub add_subregion($this, $region) { $this->{subregions}{$region->{name}} = $region; }
sub make_subregion($this, $name, %defaults)
{
my $tile_defaults = merge(\%defaults, $this->{defaults});
$this->add_subregion(HexGrid::Region->new(name => $name, defaults => $tile_defaults));
}
sub render($this, $svg, $laters, $grid)
{
my ($min_x,$min_y,$max_x,$max_y) = qw(Inf Inf -Inf -Inf);
my $g = $svg->g(id => HexGrid::to_id("$this->{name}$this->{id_suffix}"));
foreach my $nw (keys %{$this->{tiles}})
{
foreach my $sw (keys %{$this->{tiles}{$nw}})
{
my ($x_translate, $y_translate) = $grid->translate_coords($nw, $sw);
my $tile_group = $this->{tiles}{$nw}{$sw}->render($g, $grid->tile_width, $grid->tile_height, $laters);
$tile_group->{transform} = "translate($x_translate, $y_translate)";
$min_x = $x_translate if $x_translate < $min_x;
$min_y = $y_translate if $y_translate < $min_y;
$max_x = $x_translate if $x_translate > $max_x;
$max_y = $y_translate if $y_translate > $max_y;
}
}
foreach my $region (keys %{$this->{subregions}})
{
my $m = $this->{subregions}{$region}->render($svg, $laters, $grid);
$min_x = $m->{min_x} if $m->{min_x} < $min_x;
$min_y = $m->{min_y} if $m->{min_y} < $min_y;
$max_x = $m->{max_x} if $m->{max_x} > $max_x;
$max_y = $m->{max_y} if $m->{max_y} > $max_y;
}
return { min_x => $min_x,min_y => $min_y,max_x => $max_x,max_y => $max_y, group => $g };
}
1;