--- deliantra/Deliantra-Client/DC/UI.pm 2006/05/17 14:55:14 1.212 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/05/22 03:28:55 1.220 @@ -138,11 +138,22 @@ } } +sub full_refresh { + # make a copy, otherwise for complains about freed values. + my @widgets = values %WIDGET; + + $_->update + for @widgets; +} + # call when resolution changes etc. sub rescale_widgets { my ($sx, $sy) = @_; - for my $widget (values %WIDGET) { + # make a copy, otherwise for complains about freed values. + my @widgets = values %WIDGET; + + for my $widget (@widgets) { if ($widget->{toplevel}) { $widget->{x} = int 0.5 + $widget->{x} * $sx if exists $widget->{x}; $widget->{w} = int 0.5 + $widget->{w} * $sx if exists $widget->{w}; @@ -690,13 +701,6 @@ glClear GL_COLOR_BUFFER_BIT; $self->_render; -# glColorMask 1, 1, 1, 0; -# glEnable GL_BLEND; -# glBlendFunc GL_SRC_ALPHA, GL_ZERO; -# glRasterPos 0, 0; -# glCopyPixels 0, 0, $self->{w}, $self->{h}; -# glDisable GL_BLEND; -# glColorMask 1, 1, 1, 1; }; } @@ -710,7 +714,7 @@ glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; - glColor 0, 0, 0, 1; + glColor 1, 1, 1, 1; $tex->draw_quad_alpha_premultiplied (0, 0, $w, $h); @@ -803,7 +807,7 @@ ; $self = $class->SUPER::new ( - vp => (new CFClient::UI::ViewPort), + vp => (new CFClient::UI::ViewPort expand => 1), slider => $slider, @_, ); @@ -1299,6 +1303,8 @@ #font => default_font #text => initial text #markup => initial narkup + #max_w => maximum pixel width + ellipsise => 3, # end layout => (new CFClient::Layout), fontsize => 1, align => -1, @@ -1373,6 +1379,8 @@ $self->{layout}->set_font ($self->{font}) if $self->{font}; $self->{layout}->set_width ($self->{max_w} || -1); + $self->{layout}->set_ellipsise ($self->{ellipsise}); + $self->{layout}->set_single_paragraph_mode ($self->{ellipsise}); $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); my ($w, $h) = $self->{layout}->size; @@ -1418,7 +1426,9 @@ $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); + $self->{layout}->set_ellipsise ($self->{ellipsise}); + $self->{layout}->set_single_paragraph_mode ($self->{ellipsise}); + $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); my $tex = new_from_layout CFClient::Texture $self->{layout}; @@ -2050,7 +2060,7 @@ req_h => $::WIDTH / 80, vertical => 0, can_hover => 1, - inner_pad => .05, + inner_pad => 0.02, @_ ); @@ -2150,8 +2160,8 @@ if ($self->{vertical}) { # draw a vertical slider like a rotated horizontal slider + glTranslate 1, 0, 0; glRotate 90, 0, 0, 1; - glTranslate 0, 1, 0; } my $fg = $FOCUS == $self ? $self->{active_fg} : $self->{fg}; @@ -2207,13 +2217,25 @@ $self->reflow; } +sub size_allocate { + my ($self, $w, $h) = @_; + + $self->SUPER::size_allocate ($w, $h); + + $self->{layout}->set_font ($self->{font}) if $self->{font}; + $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); + $self->{layout}->set_width ($self->{children}[0]{w}); + + $self->reflow; +} + sub text_height { - my ($self, $text) = @_; + my ($self, $text, $indent) = @_; my $layout = $self->{layout}; $layout->set_height ($self->{fontsize} * $::FONTSIZE); - $layout->set_width ($self->{children}[0]{w}); + $layout->set_width ($self->{children}[0]{w} - $indent); $layout->set_markup ($text); ($layout->size)[1] @@ -2226,28 +2248,16 @@ $self->update; } -sub size_allocate { - my ($self, $w, $h) = @_; - - $self->SUPER::size_allocate ($w, $h); - - $self->{layout}->set_font ($self->{font}) if $self->{font}; - $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); - $self->{layout}->set_width ($self->{children}[0]{w}); - - $self->reflow; -} - sub add_paragraph { - my ($self, $color, $text) = @_; + my ($self, $color, $text, $indent) = @_; #TODO: intelligently "reformat" paragraph - my $height = $self->text_height ($text); - - $self->{height} += $height; - - push @{$self->{par}}, [$height, $color, $text]; + for my $line (split /\n/, $text) { + my $height = $self->text_height ($line); + $self->{height} += $height; + push @{$self->{par}}, [$height, $color, $indent, $line]; + } $self->{children}[1]{range} = [$self->{height} - $self->{h}, 0, $self->{height}, $self->{h}]; $self->{children}[1]->update; @@ -2266,23 +2276,21 @@ if (delete $self->{need_reflow}) { my $height = 0; - $height += $_->[0] = $self->text_height ($_->[2]) + $height += $_->[0] = $self->text_height ($_->[3], $_->[2]) for @{$self->{par}}; $self->{height} = $height; $self->{children}[1]{range} = [$height - $self->{h}, 0, $height, $self->{h}]; + $self->{children}[1]->update; delete $self->{texture}; } $self->{texture} ||= new_from_opengl CFClient::Texture $self->{children}[0]{w}, $self->{children}[0]{h}, sub { - glClearColor 0, 0, 0, 0; + glClearColor 0.5, 0.5, 0.5, 0; glClear GL_COLOR_BUFFER_BIT; - glEnable GL_TEXTURE_2D; - glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; - my $top = int $self->{children}[1]{range}[0]; my $y0 = $top; @@ -2294,21 +2302,27 @@ $layout->set_font ($self->{font}) if $self->{font}; + glEnable GL_BLEND; + glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; + for my $par (@{$self->{par}}) { my $h = $par->[0]; if ($y0 < $y + $h && $y < $y1) { $layout->set_foreground (@{ $par->[1] }); - $layout->set_markup ($par->[2]); + $layout->set_width ($self->{w} - $par->[2]); + $layout->set_markup ($par->[3]); + + my ($w, $h, $data, $format, $internalformat) = $layout->render; - my ($W, $H) = $layout->size; - CFClient::Texture->new_from_layout ($layout)->draw_quad_alpha_premultiplied (0, $y - $y0); + glRasterPos $par->[2], $y - $y0; + glDrawPixels $w, $h, $format, GL_UNSIGNED_BYTE, $data; } $y += $h; } - glDisable GL_TEXTURE_2D; + glDisable GL_BLEND; }; }); } @@ -2319,7 +2333,7 @@ glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; glColor 1, 1, 1, 1; - $self->{texture}->draw_quad_alpha_premultiplied (0, 0, $self->{children}[0]{w}, $self->{children}[0]{h}); + $self->{texture}->draw_quad_alpha (0, 0, $self->{children}[0]{w}, $self->{children}[0]{h}); glDisable GL_TEXTURE_2D; $self->{children}[1]->draw; @@ -2428,11 +2442,12 @@ my ($self, $widget) = @_; $self->add (new CFClient::UI::Label - markup => $widget->{tooltip}, - max_w => ($widget->{tooltip_width} || 0.25) * $::WIDTH, - fontsize => 0.8, - fg => [0, 0, 0, 1], - font => ($widget->{tooltip_font} || $::FONT_PROP), + markup => $widget->{tooltip}, + max_w => ($widget->{tooltip_width} || 0.25) * $::WIDTH, + fontsize => 0.8, + fg => [0, 0, 0, 1], + ellipsise => 0, + font => ($widget->{tooltip_font} || $::FONT_PROP), ); } @@ -2488,10 +2503,26 @@ sub new { my $class = shift; - $class->SUPER::new ( + my $self = $class->SUPER::new ( aspect => 1, @_, - ) + ); + + if ($self->{anim} && $self->{animspeed}) { + Scalar::Util::weaken (my $widget = $self); + + $self->{timer} = Event->timer ( + at => $self->{animspeed} * int $::NOW / $self->{animspeed}, + hard => 1, + interval => $self->{animspeed}, + cb => sub { + ++$widget->{frame}; + $widget->update; + }, + ); + } + + $self } sub size_request { @@ -2502,9 +2533,18 @@ my ($self) = @_; return unless $::CONN;#d# manage and cache textures differently - my $tex = $::CONN->{texture}[$::CONN->{faceid}[$self->{face}]]; - # TODO animation + my $face; + + if ($self->{frame}) { + my $anim = $::CONN->{anim}[$self->{anim}]; + + $face = $anim->[ $self->{frame} % @$anim ] + if $anim && @$anim; + } + + my $tex = $::CONN->{texture}[$::CONN->{faceid}[$face || $self->{face}]]; + if ($tex) { glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; @@ -2514,6 +2554,15 @@ } } +sub DESTROY { + my ($self) = @_; + + $self->{timer}->cancel + if $self->{timer}; + + $self->SUPER::DESTROY; +} + ############################################################################# package CFClient::UI::InventoryItem; @@ -2526,7 +2575,7 @@ my $desc = $item->{nrof} < 2 ? $item->{name} - : "$item->{nrof} $item->{name_pl}"; + : "$item->{nrof} × $item->{name_pl}"; $item->{flags} & Crossfire::Protocol::F_OPEN and $desc .= " (open)"; @@ -2556,9 +2605,9 @@ my $desc = _item_to_desc ($item); my $self = $class->SUPER::new ( - can_hover => 1, + can_hover => 1, can_events => 1, - tooltip => ((CFClient::UI::Label::escape $desc) + tooltip => ((CFClient::UI::Label::escape $desc) . "\nleftclick - pick up\nmiddle click - apply\nrightclick - menu"), connect_button_down => sub { my ($self, $ev, $x, $y) = @_; @@ -2577,13 +2626,18 @@ } elsif ($ev->{button} == 3) { my @menu_items = ( ["examine", sub { $::CONN->send ("examine $item->{tag}") }], - ["mark", sub { $::CONN->send ("mark $item->{tag}") }], + ["mark", sub { $::CONN->send ("mark ". pack "N", $item->{tag}) }], ["apply", sub { $::CONN->send ("apply $item->{tag}") }], - ["drop", sub { $::CONN->send ("move $main::OPENCONT $item->{tag} 0") }], - [ - $item->{flags} & Crossfire::Protocol::F_LOCKED ? "lock" : "unlock", - sub { $::CONN->send ("lock $item->{tag}") }, - ], + ( + $item->{flags} & Crossfire::Protocol::F_LOCKED + ? ( + ["unlock", sub { $::CONN->send ("lock " . pack "CN", 0, $item->{tag}) }], + ) + : ( + ["lock", sub { $::CONN->send ("lock " . pack "CN", 1, $item->{tag}) }], + ["drop", sub { $::CONN->send ("move $main::OPENCONT $item->{tag} 0") }], + ) + ), ); CFClient::UI::Menu->new (items => \@menu_items)->popup ($ev); @@ -2776,13 +2830,9 @@ ? "$item->{count} × $item->{text}" : $item->{text}; - my $fontsize = $item->{fontsize} || $self->{fontsize}; - for ($short) { s/^\s+//; s/\s+/ /g; - my $len = int 40 / $fontsize; - substr $_, $len, length, "…" if $len < length; } new CFClient::UI::Label @@ -2790,7 +2840,8 @@ tooltip => $item->{tooltip}, tooltip_font => $::FONT_PROP, tooltip_width => 0.67, - fontsize => $fontsize, + fontsize => $item->{fontsize} || $self->{fontsize}, + max_w => $::WIDTH * 0.44, fg => $item->{fg}, can_events => 1, can_hover => 1 @@ -2837,6 +2888,16 @@ $self->reorder; } +sub reconfigure { + my ($self) = @_; + + delete $_->{label} + for values %{ $self->{item} || {} }; + + $self->reorder; + $self->SUPER::reconfigure; +} + ############################################################################# package CFClient::UI::Root; @@ -3007,7 +3068,7 @@ glMatrixMode GL_PROJECTION; glLoadIdentity; - glOrtho 0, $::WIDTH, $::HEIGHT, 0, -10000 , 10000; + glOrtho 0, $::WIDTH, $::HEIGHT, 0, -10000, 10000; glMatrixMode GL_MODELVIEW; glLoadIdentity; @@ -3019,7 +3080,7 @@ package CFClient::UI; $ROOT = new CFClient::UI::Root; -$TOOLTIP = new CFClient::UI::Tooltip; +$TOOLTIP = new CFClient::UI::Tooltip z => 900; 1