--- deliantra/Deliantra-Client/DC/UI.pm 2006/04/24 03:19:42 1.159 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/04/25 11:18:49 1.174 @@ -16,7 +16,7 @@ sub check_tooltip { if (!$GRAB) { for (my $widget = $HOVER; $widget; $widget = $widget->{parent}) { - if (exists $widget->{tooltip}) { + if (length $widget->{tooltip}) { if ($TOOLTIP->{owner} != $widget) { $TOOLTIP->{owner} = $widget; @@ -25,9 +25,17 @@ $tip = $tip->($widget) if CODE:: eq ref $tip; - $TOOLTIP->set_text ($widget->{tooltip}); - $TOOLTIP->move ($widget->coord2global ($widget->{w}, 0)); + $TOOLTIP->set_markup ($widget->{tooltip}); + $TOOLTIP->show; + + my ($x, $y) = $widget->coord2global ($widget->{w}, 0); + + if ($x + $TOOLTIP->{w} > $::WIDTH) { + ($x, $y) = $widget->coord2global (-$TOOLTIP->{w}, 0); + } + + $TOOLTIP->move ($x, $y); } return; @@ -41,11 +49,13 @@ # class methods for events sub feed_sdl_key_down_event { - $FOCUS->key_down ($_[0]) if $FOCUS; + $FOCUS->emit (key_down => $_[0]) || $FOCUS->key_down ($_[0]) + if $FOCUS; } sub feed_sdl_key_up_event { - $FOCUS->key_up ($_[0]) if $FOCUS; + $FOCUS->emit (key_up => $_[0]) || $FOCUS->key_up ($_[0]) + if $FOCUS; } sub feed_sdl_button_down_event { @@ -63,7 +73,10 @@ $BUTTON_STATE |= 1 << ($ev->{button} - 1); - $GRAB->button_down ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; + if ($GRAB) { + ($x, $y) = $GRAB->coord2local ($x, $y); + $GRAB->emit (button_down => $ev, $x, $y) || $GRAB->button_down ($ev, $x, $y); + } } sub feed_sdl_button_up_event { @@ -74,7 +87,10 @@ $BUTTON_STATE &= ~(1 << ($ev->{button} - 1)); - $GRAB->button_up ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; + if ($GRAB) { + ($x, $y) = $GRAB->coord2local ($x, $y); + $GRAB->emit (button_up => $ev, $x, $y) || $GRAB->button_up ($ev, $x, $y); + } if (!$BUTTON_STATE) { my $grab = $GRAB; undef $GRAB; @@ -100,7 +116,10 @@ check_tooltip; } - $HOVER->mouse_motion ($ev, $HOVER->coord2local ($x, $y)) if $HOVER; + if ($HOVER) { + ($x, $y) = $HOVER->coord2local ($x, $y); + $HOVER->emit (mouse_motion => $ev, $x, $y) || $HOVER->mouse_motion ($ev, $x, $y); + } } # convert position array to integers @@ -128,9 +147,9 @@ my $class = shift; my $self = bless { - x => 0, - y => 0, - z => 0, + x => 0, + y => 0, + z => 0, can_events => 1, @_ }, $class; @@ -162,9 +181,11 @@ sub hide { my ($self) = @_; - return unless $self->{parent}; + undef $GRAB if $GRAB == $self; + undef $HOVER if $HOVER == $self; - $self->{parent}->remove ($self); + $self->{parent}->remove ($self) + if $self->{parent}; } sub move { @@ -225,6 +246,19 @@ # nothing to be done } +sub children { +} + +# call when resoltuion changes etc. +sub reconfigure { + my ($self) = @_; + + $_->reconfigure + for $self->children; + + $_->check_size; +} + sub set_max_size { my ($self, $w, $h) = @_; @@ -236,6 +270,9 @@ sub _topleft { my ($self, $x, $y) = @_; + $self->{parent} + or Carp::confess "no parent widget in _topleft\n";#d# + $self->{parent}->_topleft ($x + $self->{x}, $y + $self->{y}); } @@ -322,6 +359,20 @@ glEnd; glDisable GL_BLEND; } + + if ($ENV{PCLIENT_DEBUG}) { + glPushMatrix; + glColor 1, 1, 0, 1; + glTranslate $self->{x} + 0.375, $self->{y} + 0.375; + glBegin GL_LINE_LOOP; + glVertex 0 , 0; + glVertex $self->{w}, 0; + glVertex $self->{w}, $self->{h}; + glVertex 0 , $self->{h}; + glEnd; + glPopMatrix; + CFClient::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw; + } } sub _draw { @@ -390,9 +441,7 @@ sub emit { my ($self, $signal, @args) = @_; - for my $cb (@{$self->{signal_cb}{$signal} || []}) { - $cb->($self, @args); - } + List::Util::sum map $_->($self, @args), @{$self->{signal_cb}{$signal} || []} } sub DESTROY { @@ -469,7 +518,11 @@ my $children = delete $arg{children} || []; - my $self = $class->SUPER::new (children => [], can_events => 0, %arg); + my $self = $class->SUPER::new ( + children => [], + can_events => 0, + %arg, + ); $self->add ($_) for @$children; $self @@ -490,10 +543,15 @@ $child->check_size; } +sub children { + @{ $_[0]{children} } +} + sub remove { my ($self, $child) = @_; delete $child->{parent}; + $child->hide; $self->{children} = [ grep $_ != $child, @{ $self->{children} } ]; @@ -501,6 +559,18 @@ $self->update; } +sub clear { + my ($self) = @_; + + my $children = delete $self->{children}; + $self->{children} = []; + + for (@$children) { + delete $_->{parent}; + $_->hide; + } +} + sub find_widget { my ($self, $x, $y) = @_; @@ -583,29 +653,27 @@ sub update { my ($self) = @_; - # we want to do this delayed... - $self->render_chld; + $ROOT->on_refresh ($self => sub { $self->render_child }); $self->SUPER::update; } -sub render_chld { +sub size_allocate { + my ($self, $w, $h) = @_; + + $self->SUPER::size_allocate ($w, $h); + $self->update; +} + +sub render_child { my ($self) = @_; $self->{texture} = new_from_opengl CFClient::Texture $self->{w}, $self->{h}, sub { - glClearColor 0, 0, 0, 1; + glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; $self->child->draw; }; } -sub size_allocate { - my ($self, $w, $h) = @_; - - $self->child->configure (0, 0, $w, $h); - - $self->render_chld; -} - sub _draw { my ($self) = @_; @@ -615,9 +683,10 @@ or return; glEnable GL_BLEND; - glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; + glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + glColor 0, 0, 0, 1; $tex->draw_quad (0, 0, $w, $h); @@ -712,9 +781,9 @@ # TODO: user_x, user_y, overwrite moveto? my $self = $class->SUPER::new ( - bg => [1, 1, 1, 1], - border_bg => [1, 1, 1, 1], - border => 0.8, + bg => [1, 1, 1, 1], + border_bg => [1, 1, 1, 1], + border => 0.8, can_events => 1, @_ ); @@ -872,11 +941,22 @@ $child->check_size; } +sub children { + grep $_, map @$_, grep $_, @{ $_[0]{children} } +} + # TODO: move to container class maybe? send childs a signal on removal? sub clear { my ($self) = @_; + my @children = $self->children; delete $self->{children}; + + for (@children) { + delete $_->{parent}; + $_->hide; + } + $self->update; } @@ -1109,14 +1189,14 @@ my ($class, %arg) = @_; my $self = $class->SUPER::new ( - fg => [1, 1, 1], - #font => default_font - fontsize => 1, - text => "", - align => -1, - valign => -1, - padding => 2, - layout => new CFClient::Layout, + fg => [1, 1, 1], + #font => default_font + fontsize => 1, + text => "", + align => -1, + valign => -1, + padding => 2, + layout => new CFClient::Layout, can_events => 0, %arg ); @@ -1133,7 +1213,7 @@ $self } -sub escape_text { +sub escape { local $_ = $_[1]; s/&/&/g; @@ -1143,24 +1223,43 @@ $_[1] } +sub update { + my ($self) = @_; + + delete $self->{texture}; + $self->SUPER::update; +} + +sub reconfigure { + my ($self) = @_; + + delete $self->{texture}; +} + sub set_text { my ($self, $text) = @_; + return if $self->{text} eq "T$text"; + $self->{text} = "T$text"; + $self->{layout}->set_text ($text); delete $self->{texture}; - $self->check_size; $self->update; + $self->check_size; } sub set_markup { my ($self, $markup) = @_; + return if $self->{text} eq "M$markup"; + $self->{text} = "M$markup"; + $self->{layout}->set_markup ($markup); delete $self->{texture}; - $self->check_size; $self->update; + $self->check_size; } sub size_request { @@ -1250,13 +1349,13 @@ my $class = shift; $class->SUPER::new ( - fg => [1, 1, 1], - bg => [0, 0, 0, 0.2], - active_bg => [1, 1, 1, 0.5], - active_fg => [0, 0, 0], - can_hover => 1, - can_focus => 1, - valign => 0, + fg => [1, 1, 1], + bg => [0, 0, 0, 0.2], + active_bg => [1, 1, 1, 0.5], + active_fg => [0, 0, 0], + can_hover => 1, + can_focus => 1, + valign => 0, can_events => 1, @_ ) @@ -1420,9 +1519,35 @@ my $sym = $ev->{sym}; if ($sym == 13) { - $self->emit (activate => $self->get_text); + unshift @{$self->{history}}, + my $txt = $self->get_text; + $self->{history_pointer} = -1; + $self->{history_saveback} = ''; + $self->emit (activate => $txt); $self->update; + } elsif ($sym == CFClient::SDLK_UP) { + if ($self->{history_pointer} < 0) { + $self->{history_saveback} = $self->get_text; + } + if (@{$self->{history} || []} > 0) { + $self->{history_pointer}++; + if ($self->{history_pointer} >= @{$self->{history} || []}) { + $self->{history_pointer} = @{$self->{history} || []} - 1; + } + $self->set_text ($self->{history}->[$self->{history_pointer}]); + } + + } elsif ($sym == CFClient::SDLK_DOWN) { + $self->{history_pointer}--; + $self->{history_pointer} = -1 if $self->{history_pointer} < 0; + + if ($self->{history_pointer} >= 0) { + $self->set_text ($self->{history}->[$self->{history_pointer}]); + } else { + $self->set_text ($self->{history_saveback}); + } + } else { $self->SUPER::key_down ($ev); } @@ -1445,13 +1570,13 @@ my $class = shift; $class->SUPER::new ( - padding => 4, - fg => [1, 1, 1], - bg => [1, 1, 1, 0.2], - active_fg => [0, 0, 1], - can_hover => 1, - align => 0, - valign => 0, + padding => 4, + fg => [1, 1, 1], + bg => [1, 1, 1, 0.2], + active_fg => [0, 0, 1], + can_hover => 1, + align => 0, + valign => 0, can_events => 1, @_ ) @@ -1668,7 +1793,10 @@ sub set_max { my ($self, $max) = @_; + return if $self->{max_val} == $max; + $self->{max_val} = $max; + $self->update; } sub set_value { @@ -1677,9 +1805,9 @@ $self->set_max ($max) if defined $max; - $max = $self->{max_val}; - $self->{val} = $val; + return if $self->{val} == $val; + $self->{val} = $val; $self->update; } @@ -1752,13 +1880,15 @@ my ($class, %arg) = @_; my $self = $class->SUPER::new ( - tooltip => $arg{type}, + tooltip => $arg{type}, + can_hover => 1, + can_events => 1, %arg, ); - $self->add ($self->{value} = new CFClient::UI::Label valign => +1, align => 0, template => "999", can_events => 1, can_hover => 1); - $self->add ($self->{gauge} = new CFClient::UI::VGauge type => $self->{type}, expand => 1, can_events => 1, can_hover => 1); - $self->add ($self->{max} = new CFClient::UI::Label valign => -1, align => 0, template => "999", can_events => 1, can_hover => 1); + $self->add ($self->{value} = new CFClient::UI::Label valign => +1, align => 0, template => "999"); + $self->add ($self->{gauge} = new CFClient::UI::VGauge type => $self->{type}, expand => 1, can_hover => 1); + $self->add ($self->{max} = new CFClient::UI::Label valign => -1, align => 0, template => "999"); $self } @@ -1770,6 +1900,13 @@ $self->{max} ->set_fontsize ($fsize); } +sub set_max { + my ($self, $max) = @_; + + $self->{gauge}->set_max ($max); + $self->{max}->set_text ($max); +} + sub set_value { my ($self, $val, $max) = @_; @@ -1780,13 +1917,6 @@ $self->{value}->set_text ($val); } -sub set_max { - my ($self, $max) = @_; - - $self->{gauge}->set_max ($max); - $self->{max}->set_text ($max); -} - ############################################################################# package CFClient::UI::Slider; @@ -1934,14 +2064,15 @@ my $class = shift; my $self = $class->SUPER::new ( - fontsize => 1, - #font => default_font + fontsize => 1, + can_events => 0, + #font => default_font @_, - - layout => (new CFClient::Layout), - par => [], - height => 0, - children => [ + + layout => (new CFClient::Layout), + par => [], + height => 0, + children => [ (new CFClient::UI::Empty expand => 1), (new CFClient::UI::Slider vertical => 1), ], @@ -2076,6 +2207,7 @@ if ($self->{texture}) { glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + glColor 1, 1, 1, 1; $self->{texture}->draw_quad (0, 0, $self->{w}, $self->{h}); glDisable GL_TEXTURE_2D; } @@ -2136,9 +2268,8 @@ my $class = shift; my $self = $class->SUPER::new ( - state => 0, + state => 0, connect_activate => \&toggle_flopper, - can_events => 1, @_ ); @@ -2183,24 +2314,30 @@ ) } -sub set_text { +sub set_markup { my ($self, $text) = @_; $self->{label} ||= new CFClient::UI::Label fontsize => 0.8, fg => [0, 0, 0]; - $self->{label}->set_text ($text); + $self->{label}->set_markup ($text); $self->add ($self->{label}); } sub size_request { my ($self) = @_; - $self->child->set_max_size ($::WIDTH * 0.2); + $self->child->set_max_size ($::WIDTH * 0.3); my ($w, $h) = @{$self->child}{qw(req_w req_h)}; ($w + 4, $h + 4) } +sub size_allocate { + my ($self, $w, $h) = @_; + + $self->SUPER::size_allocate ($w - 4, $h - 4); +} + sub _draw { my ($self) = @_; @@ -2232,6 +2369,44 @@ } ############################################################################# + +package CFClient::UI::Face; + +our @ISA = CFClient::UI::Base::; + +use CFClient::OpenGL; + +sub new { + my $class = shift; + + $class->SUPER::new ( + aspect => 1, + @_, + ) +} + +sub size_request { + (32, 8) +} + +sub draw { + my ($self) = @_; + + my $tex = $::CONN->{texture}[$::CONN->{faceid}[$self->{face}]]; + + if ($tex) { + glEnable GL_BLEND; + glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; + glEnable GL_TEXTURE_2D; + glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + glColor 1, 1, 1, 1; + $tex->draw_quad (0, 0, $self->{w}, $self->{h}); + glDisable GL_TEXTURE_2D; + glDisable GL_BLEND; + } +} + +############################################################################# package CFClient::UI::Root;