/usr/local/CPAN/Deliantra-Client/DC/UI/Canvas.pm
package DC::UI::Canvas;
use common::sense;
use List::Util qw(max min);
use DC::OpenGL;
our @ISA = DC::UI::Fixed::;
sub new {
my ($class, %arg) = @_;
my $items = delete $arg{items};
my $self = $class->SUPER::new (
items => [],
@_,
);
$self->add (@$items)
if $items && @$items;
$self
}
sub add_items {
my ($self, @items) = @_;
push @{$self->{items}}, @items;
my @coords =
map @{ $_->{coord} },
grep $_->{coord_mode} ne "rel",
@{ $self->{items} };
$self->{item_max_w} = max map $_->[0], @coords;
$self->{item_max_h} = max map $_->[1], @coords;
$self->realloc;
map $_+0, @items
}
sub size_request {
my ($self) = @_;
my ($w, $h) = $self->SUPER::size_request;
(
(max $w, $self->{item_max_w}),
(max $h, $self->{item_max_h}),
)
}
my %GLTYPE = (
lines => GL_LINES,
line_strip => GL_LINE_STRIP,
line_loop => GL_LINE_LOOP,
quads => GL_QUADS,
quad_strip => GL_QUAD_STRIP,
triangles => GL_TRIANGLES,
triangle_strip => GL_TRIANGLE_STRIP,
triangle_fan => GL_TRIANGLE_FAN,
polygon => GL_POLYGON,
);
sub _draw {
my ($self) = @_;
$self->SUPER::_draw;
for my $item (@{ $self->{items} }) {
glPushMatrix;
glScale $self->{w}, $self->{h} if $item->{coord_mode} eq "rel";
glColor @{ $item->{color} };
glLineWidth $item->{width} || 1.;
glPointSize $item->{size} || 1.;
if (my $gltype = $GLTYPE{$item->{type}}) {
glBegin $gltype;
glVertex @$_ for @{$item->{coord}};
glEnd;
}
glPopMatrix;
}
glLineWidth 1;
glPointSize 1;
}
1