--- deliantra/Deliantra-Client/DC/UI.pm 2010/10/12 05:11:38 1.481 +++ deliantra/Deliantra-Client/DC/UI.pm 2012/11/23 12:14:02 1.487 @@ -4,6 +4,7 @@ use List::Util (); +use AnyEvent (); use Guard (); use DC; @@ -53,7 +54,7 @@ for (grep { $_->{name} } values %WIDGET) { my $win = $layout->{$_->{name}} = { }; - + $win->{x} = ($_->{x} + $_->{w} * 0.5) / $::WIDTH if $_->{x} =~ /^[0-9.]+$/; $win->{y} = ($_->{y} + $_->{h} * 0.5) / $::HEIGHT if $_->{y} =~ /^[0-9.]+$/; $win->{w} = $_->{w} / $::WIDTH if defined $_->{w}; @@ -72,7 +73,7 @@ } # class methods for events -sub feed_sdl_key_down_event { +sub feed_sdl_key_down_event { $FOCUS->emit (key_down => $_[0]) if $FOCUS; } @@ -364,8 +365,8 @@ sub set_size { my ($self, $w, $h) = @_; - $self->{force_w} = $w; - $self->{force_h} = $h; + $self->{force_w} = List::Util::min $w, ($self->{max_w} || $::WIDTH ); + $self->{force_h} = List::Util::min $h, ($self->{max_h} || $::HEIGHT); $self->realloc; } @@ -1157,7 +1158,7 @@ my $ox = $self->{vp}{view_x}; my $oy = $self->{vp}{view_y}; - + $self->{motion} = sub { my ($ev, $x, $y) = @_; @@ -1357,11 +1358,11 @@ use DC::OpenGL; -my $bg = +my $bg = new_from_resource DC::Texture "d1_bg.png", mipmap => 1, wrap => 1; -my @border = +my @border = map { new_from_resource DC::Texture $_, mipmap => 1 } qw(d1_border_top.png d1_border_right.png d1_border_left.png d1_border_bottom.png); @@ -1465,7 +1466,7 @@ my ($self) = @_; $self->hide; - + 1 } @@ -1475,10 +1476,10 @@ my ($w, $h) = @$self{qw(w h)}; my $border = $self->border; - my $lr = ($x >= 0 && $x < $border) || ($x > $w - $border && $x < $w); - my $td = ($y >= 0 && $y < $border) || ($y > $h - $border && $y < $h); + my $lr = ($x >= 0 && $x < $border) || ($x > $w - $border && $x < $w); # left-right + my $td = ($y >= 0 && $y < $border) || ($y > $h - $border && $y < $h); # top-down - if ($lr & $td) { + if ($lr & $td) { # corners my ($wx, $wy) = ($self->{x}, $self->{y}); my ($ox, $oy) = ($ev->{x}, $ev->{y}); my ($bw, $bh) = ($self->{w}, $self->{h}); @@ -1492,14 +1493,16 @@ my $dx = $ev->{x} - $ox; my $dy = $ev->{y} - $oy; - $self->{force_w} = $bw + $dx * ($mx ? -1 : 1); - $self->{force_h} = $bh + $dy * ($my ? -1 : 1); + $self->set_size ( + $bw + $dx * ($mx ? -1 : 1), + $bh + $dy * ($my ? -1 : 1), + ); $self->move_abs ($wx + $dx * $mx, $wy + $dy * $my); $self->realloc; }; - } elsif ($lr ^ $td) { + } elsif ($lr ^ $td) { # edges my ($ox, $oy) = ($ev->{x}, $ev->{y}); my ($bx, $by) = ($self->{x}, $self->{y}); @@ -1839,7 +1842,7 @@ $_ *= $space / $req for @req; } else { my $expand = (List::Util::sum map $_->{expand}, @children) || 1; - + $space = ($space - $req) / $expand; # remaining space to give away $req[$_] += $space * $children[$_]{expand} @@ -2078,7 +2081,7 @@ # $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); # DC::OpenGL::glEndList; # } -# +# # DC::OpenGL::glCallList $self->{list}; $self->{layout}->draw; @@ -2237,7 +2240,7 @@ $self->_set_text ($self->{text}); $self->update; - + 1 } @@ -3138,7 +3141,7 @@ $self->SUPER::invoke_button_down ($ev, $x, $y); $self->{click} = [$self->{range}[0], $self->{vertical} ? $y : $x]; - + $self->invoke_mouse_motion ($ev, $x, $y); 1 @@ -3208,7 +3211,7 @@ if ($self->{vertical}) { # draw a vertical slider like a rotated horizontal slider - + glTranslate 1, 0, 0; glRotate 90, 0, 0, 1; } @@ -3286,9 +3289,8 @@ indent => 0, #font => default_font @_, - + layout => (new DC::Layout), - par => [], max_par => 0, height => 0, children => [ @@ -3299,6 +3301,8 @@ $self->{children}[1]->connect (changed => sub { $self->update }); + $self->add_paragraph (@{ delete $self->{par} }) if @{ $self->{par} }; + $self } @@ -3571,7 +3575,7 @@ $self->{moveto} = [$self->{x}, $self->{y}, $x, $y]; $self->{speed} = 0.001; $self->{time} = 1; - + ::animation_start $self; } @@ -3585,7 +3589,7 @@ } my ($x0, $y0, $x1, $y1) = @{$self->{moveto}}; - + $self->{x} = $x0 * $self->{time} + $x1 * (1 - $self->{time}); $self->{y} = $y0 * $self->{time} + $y1 * (1 - $self->{time}); } @@ -3640,28 +3644,66 @@ ) } -sub set_tooltip_from { - my ($self, $widget) = @_; +# expand, as good as possible +sub _expand_doclets { + my ($tip) = @_; + + $tip =~ s{#\(([^)]+)\)}{ + if ($::CONN) { + exists $::CONN->{doclet}{$1} + ? $::CONN->{doclet}{$1} + : "(waiting for server to show full text)" + } else { + "(unable to show full text without server connection)" + } + }ge; - my $tip = $widget->{tooltip}; - $tip = $tip->($widget) if "CODE" eq ref $tip; - + $tip =~ s/^\n+//; + $tip =~ s/\n+$//; + + $tip +} + +# expands a tooltip, potentially multiple times remotely +# and returns a guard. clals the clalback each time the text changes. +sub expand_tooltip { + my ($tip, $cb) = @_; + + # first expand #name tooltips from local pod $tip = DC::Pod::section_label tooltip => $1 - if $tip =~ /^#(.*)$/; + if $tip =~ /^#([^(].*)$/; + + my $active; # true if any remote requests outstanding - if ($ENV{CFPLUS_DEBUG} & 2) { - $tip .= "\n\n" . (ref $widget) . "\n" - . "$widget->{x} $widget->{y} $widget->{w} $widget->{h}\n" - . "req $widget->{req_w} $widget->{req_h}\n" - . "visible $widget->{visible}"; + if ($::CONN && $::CONN->{addme_success}) { + # now find all doclet references + for my $doclet ($tip =~ /#\(([^)]+)\)/g) { + unless (exists $::CONN->{doclet}{$doclet}) { + # need to ask the server + # we don't try to avoid duplicate requests + + $active = 1; + $::CONN->send_exti_req (doclet => (split /\//, $doclet, 2), sub { + $::CONN->{doclet}{$doclet} = DC::sanitise_cfxml $_[0]; + $cb->(_expand_doclets $tip) if $active; + }); + } + } } - $tip =~ s/^\n+//; - $tip =~ s/\n+$//; + $cb->(_expand_doclets $tip); + + $active and Guard::guard { undef $active } +} + +sub set_tooltip_from { + my ($self, $widget) = @_; + + my $tip = $widget->{tooltip}; + $tip = $tip->($widget) if "CODE" eq ref $tip; $self->add (new DC::UI::Label fg => $DC::THEME{tooltip_fg}, - markup => $tip, max_w => ($widget->{tooltip_width} || 0.25) * $::WIDTH, align => 0, fontsize => 0.8, @@ -3669,6 +3711,19 @@ ellipsise => 0, font => ($widget->{tooltip_font} || $::FONT_PROP), ); + + $self->{tooltip_expand} = expand_tooltip $tip, sub { + my ($tip) = @_; + + if ($ENV{CFPLUS_DEBUG} & 2) { + $tip .= "\n\n" . (ref $widget) . "\n" + . "$widget->{x} $widget->{y} $widget->{w} $widget->{h}\n" + . "req $widget->{req_w} $widget->{req_h}\n" + . "visible $widget->{visible}"; + } + + $self->{children}[0]->set_markup ($tip); + }; } sub size_request { @@ -3714,10 +3769,10 @@ glColor @{ $DC::THEME{tooltip_bg} }; glRect 0, 0, $w, $h; - + glColor @{ $DC::THEME{tooltip_border} }; glRect_lineloop .5, .5, $w + .5, $h + .5; - + glTranslate 2, 2; $self->SUPER::_draw; @@ -3743,7 +3798,7 @@ ); $self->update_anim; - + $self } @@ -4294,7 +4349,7 @@ sub reorder { my ($self) = @_; - my $NOW = EV::time; + my $NOW = AE::time; # freeze display when hovering over any label return if $DC::UI::TOOLTIP->{owner} @@ -4403,6 +4458,16 @@ }); } +sub clr_group { + my ($self, $group) = @_; + + if (delete $self->{item}{$group}) { + $ROOT->on_refresh (reorder => sub { + $self->reorder; + }); + } +} + sub reconfigure { my ($self) = @_; @@ -4566,7 +4631,7 @@ $widget = pop @{ $queue[-1] || [] } and last; - + pop @queue; }