--- deliantra/Deliantra-Client/DC/UI.pm 2006/05/10 21:12:26 1.193 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/05/11 23:41:47 1.194 @@ -1,5 +1,6 @@ package CFClient::UI; +use utf8; use strict; use Scalar::Util (); @@ -668,15 +669,12 @@ my $tex = $self->{texture} or return; - glEnable GL_BLEND; - 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); + $tex->draw_quad_alpha_premultiplied (0, 0, $w, $h); - glDisable GL_BLEND; glDisable GL_TEXTURE_2D; } @@ -1265,12 +1263,13 @@ my $self = $class->SUPER::new ( fg => [1, 1, 1], #font => default_font + #text => initial text + #markup => initial narkup + layout => (new CFClient::Layout), fontsize => 1, - text => "", align => -1, valign => -1, padding => 2, - layout => new CFClient::Layout, can_events => 0, %arg ); @@ -1281,8 +1280,11 @@ $self->{template} = $layout; } - $self->set_text (delete $self->{text}) if exists $self->{text}; - $self->set_markup (delete $self->{markup}) if exists $self->{markup}; + if (exists $self->{markup}) { + $self->set_markup (delete $self->{markup}); + } else { + $self->set_text (delete $self->{text}); + } $self } @@ -1310,6 +1312,7 @@ return if $self->{text} eq "T$text"; $self->{text} = "T$text"; + $self->{layout} = new CFClient::Layout if $self->{layout}->is_rgba; $self->{layout}->set_text ($text); $self->update; @@ -1322,6 +1325,9 @@ return if $self->{text} eq "M$markup"; $self->{text} = "M$markup"; + my $rgba = $markup =~ /span.*(?:foreground|background)/; + + $self->{layout} = new CFClient::Layout $rgba if $self->{layout}->is_rgba != $rgba; $self->{layout}->set_markup ($markup); $self->update; @@ -1373,35 +1379,35 @@ my ($self) = @_; my $tex = $self->{texture} ||= do { + $self->{layout}->set_foreground (@{$self->{fg}}); $self->{layout}->set_font ($self->{font}) if $self->{font}; $self->{layout}->set_width ($self->{w}); $self->{layout}->set_height (List::Util::min $self->{h}, $self->{fontsize} * $::FONTSIZE); - new_from_layout CFClient::Texture $self->{layout} - }; - 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; + my $tex = new_from_layout CFClient::Texture $self->{layout}; - glColor @{$self->{fg}}; + $self->{ox} = int $self->{align} < 0 ? $self->{padding} + : $self->{align} > 0 ? $self->{w} - $tex->{w} - $self->{padding} + : ($self->{w} - $tex->{w}) * 0.5; - $self->{ox} = int ( - $self->{align} < 0 ? $self->{padding} - : $self->{align} > 0 ? $self->{w} - $tex->{w} - $self->{padding} - : ($self->{w} - $tex->{w}) * 0.5 - ); + $self->{oy} = int $self->{valign} < 0 ? $self->{padding} + : $self->{valign} > 0 ? $self->{h} - $tex->{h} - $self->{padding} + : ($self->{h} - $tex->{h}) * 0.5; - $self->{oy} = int ( - $self->{valign} < 0 ? $self->{padding} - : $self->{valign} > 0 ? $self->{h} - $tex->{h} - $self->{padding} - : ($self->{h} - $tex->{h}) * 0.5 - ); + $tex + }; - $tex->draw_quad ($self->{ox}, $self->{oy}); + glEnable GL_TEXTURE_2D; + glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + + if ($tex->{format} == GL_ALPHA) { + glColor @{$self->{fg}}; + $tex->draw_quad_alpha ($self->{ox}, $self->{oy}); + } else { + $tex->draw_quad_alpha_premultiplied ($self->{ox}, $self->{oy}); + } glDisable GL_TEXTURE_2D; - glDisable GL_BLEND; } ############################################################################# @@ -1446,6 +1452,15 @@ $self->emit (changed => $self->{text}); } +sub set_text { + my ($self, $text) = @_; + + $self->{cursor} = length $text; + $self->_set_text ($text); + $self->check_size; + $self->update; +} + sub get_text { $_[0]{text} } @@ -1464,14 +1479,6 @@ $self->_set_text (delete $self->{text});#d# don't check for == inside _set_text } -sub set_text { - my ($self, $text) = @_; - - $self->{cursor} = length $text; - $self->_set_text ($text); - $self->update; -} - sub key_down { my ($self, $ev) = @_; @@ -2656,6 +2663,71 @@ } ############################################################################# + +package CFClient::UI::Statusbox; + +our @ISA = CFClient::UI::VBox::; + +sub reorder { + my ($self) = @_; + my $NOW = time; + + while (my ($k, $v) = each %{ $self->{item} }) { + delete $self->{item}{$k} if $v->{timeout} < $NOW; + } + + my @widgets; + my @items = sort { $a->{time} <=> $b->{time} } values %{ $self->{item} }; + my $count = 10 + 1; + for my $item (@items) { + last unless --$count; + + push @widgets, $item->{label} ||= do { + # TODO: doesn't handle markup well (read as: at all) + my $short = delete $item->{text}; + for ($short) { + s/^\s+//; + s/\012.*//s; + my $len = int 30 / $item->{fontsize}; + substr $_, $len, length, "…" if $len < length; + } + + new CFClient::UI::Label + markup => $short, + tooltip => delete $item->{tooltip}, + fontsize => delete $item->{fontsize}, + color => delete $item->{color}, + can_events => 1, + can_hover => 1, + }; + } + + $self->clear; + $self->SUPER::add (@widgets); +} + +sub add { + my ($self, $text, %arg) = @_; + + my $item = { + time => time, + text => $text, + timeout => 60, + tooltip => $text, + fontsize => 0.8, + color => [0.8, 0.8, 0.8, 0.8], + %arg, + }; + + $item->{timeout} += time; + $item->{group} ||= $item+0; + + $item = $self->{item}{$item->{group}} ||= $item; + + $self->reorder; +} + +############################################################################# package CFClient::UI::Root;