--- deliantra/Deliantra-Client/DC/UI.pm 2006/04/09 00:43:11 1.31 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/04/09 01:21:11 1.32 @@ -8,13 +8,13 @@ use SDL::OpenGL::Constants; our $FOCUS; # the widget with current focus -our @ACTIVE_WIDGETS; +#our @ACTIVE_WIDGETS; # class methods for events sub feed_sdl_key_down_event { $FOCUS->key_down ($_[0]) if $FOCUS } sub feed_sdl_key_up_event { $FOCUS->key_up ($_[0]) if $FOCUS } -sub feed_sdl_button_down_event { $FOCUS->button_down ($_[0]) if $FOCUS } -sub feed_sdl_button_up_event { $FOCUS->button_up ($_[0]) if $FOCUS } +sub feed_sdl_button_down_event { } +sub feed_sdl_button_up_event { } sub new { my $class = shift; @@ -22,17 +22,17 @@ bless { @_ }, $class } -sub activate { - push @ACTIVE_WIDGETS, $_[0]; - Scalar::Util::weaken $ACTIVE_WIDGETS[-1]; -} - -sub deactivate { - @ACTIVE_WIDGETS = - sort { $a->{z} <=> $b->{z} } - grep { $_ && $_ != $_[0] } - @ACTIVE_WIDGETS; -} +#sub activate { +# push @ACTIVE_WIDGETS, $_[0]; +# Scalar::Util::weaken $ACTIVE_WIDGETS[-1]; +#} + +#sub deactivate { +# @ACTIVE_WIDGETS = +# sort { $a->{z} <=> $b->{z} } +# grep { $_ && $_ != $_[0] } +# @ACTIVE_WIDGETS; +#} sub move { my ($self, $x, $y, $z) = @_; @@ -94,13 +94,40 @@ } sub bbox { - my ($widget) = @_; + my ($self) = @_; + my ($w, $h) = $self->size_request; + ( + $self->{x}, + $self->{y}, + $self->{x} = $w, + $self->{y} = $h + ) +} + +sub del_parent { $_[0]->{parent} = undef } + +sub set_parent { + my ($self, $par) = @_; + + $self->{parent} = $par; + Scalar::Util::weaken $self->{parent}; +} + +sub get_parent { + $_[0]->{parent} +} + +sub update { + my ($self) = @_; + + $self->{parent}->update + if $self->{parent}; } sub DESTROY { my ($self) = @_; - $self->deactivate; + #$self->deactivate; } package Crossfire::Client::Widget::Container; @@ -109,13 +136,54 @@ use SDL::OpenGL; -sub add { $_[0]->{child} = $_[1] } +sub add { $_[0]->{child} = $_[1]; $_[1]->set_parent ($_[0]); $_[1]->update } sub get { $_[0]->{child} } +sub remove { + my ($self, $chld) = @_; + delete $self->{child} + if $self->{child} == $chld; +} sub size_request { $_[0]->{child}->size_request if $_[0]->{child} } sub _draw { die "Containers can't be drawn!" } +package Crossfire::Client::Widget::Toplevel; + +our @ISA = Crossfire::Client::Widget::; + +use SDL::OpenGL; + +sub add { + my ($self, $chld) = @_; + + push @{$self->{childs}}, $chld; + @{$self->{childs}} = + sort { $a->{z} <=> $b->{z} } + @{$self->{childs}}; + + $chld->set_parent ($self); +} + +sub remove { + my ($self, $chld) = @_; + @{$self->{childs}} = + sort { $a->{z} <=> $b->{z} } + grep { $_ && $_ != $_[0] } + @{$self->{childs}} +} + +sub update { + my ($self) = @_; + ::refresh (); +} + +sub _draw { + my ($self) = @_; + + $_->draw for @{$self->{childs}}; +} + package Crossfire::Client::Widget::Window; our @ISA = Crossfire::Client::Widget::Container::; @@ -125,7 +193,19 @@ sub add { my ($self, $chld) = @_; $self->SUPER::add ($chld); - $self->render_chld; #TODO: Move this to the size_request event propably? + $chld->set_parent ($self); + $self->update; #TODO: Move this to the size_request event propably? +} + +sub remove { + my ($self) = @_; + # TODO FIXME: removing a child from a window will crash, see render_chld + $self->update; +} + +sub update { + my ($self) = @_; + $self->render_chld; } sub render_chld { @@ -223,7 +303,11 @@ sub add { my ($self, $x, $y, $chld) = @_; + my $old_chld = $self->{childs}[$y][$x]; + $self->{childs}[$y][$x] = $chld; + $chld->set_parent ($self); + $self->update; } sub max_row_height { @@ -305,6 +389,8 @@ sub add { my ($self, $chld) = @_; push @{$self->{childs}}, $chld; + $chld->set_parent ($self); + $self->update; } sub size_request { @@ -352,8 +438,9 @@ my ($self, $text) = @_; $self->{text} = $text; - $self->{texture} = new_from_text Crossfire::Client::Texture $text, $self->{height}; + + $self->update; } sub get_text {