--- deliantra/Deliantra-Client/DC/UI.pm 2006/12/09 02:21:25 1.361 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/07/21 14:01:35 1.397 @@ -3,7 +3,6 @@ use utf8; use strict; -use Scalar::Util (); use List::Util (); use Event; @@ -25,9 +24,11 @@ for (my $widget = $HOVER; $widget; $widget = $widget->{parent}) { if (length $widget->{tooltip}) { if ($TOOLTIP->{owner} != $widget) { + $TOOLTIP->{owner}->emit ("tooltip_hide") if $TOOLTIP->{owner}; $TOOLTIP->hide; $TOOLTIP->{owner} = $widget; + $TOOLTIP->{owner}->emit ("tooltip_show") if $TOOLTIP->{owner}; return if $ENV{CFPLUS_DEBUG} & 8; @@ -45,6 +46,7 @@ } $TOOLTIP->hide; + $TOOLTIP->{owner}->emit ("tooltip_hide") if $TOOLTIP->{owner}; delete $TOOLTIP->{owner}; }); @@ -113,8 +115,12 @@ if ($GRAB) { if ($ev->{button} == 4 || $ev->{button} == 5) { # mousewheel - $ev->{dx} = 0; - $ev->{dy} = $ev->{button} * 2 - 9; + my $delta = $ev->{button} * 2 - 9; + my $shift = $ev->{mod} & CFPlus::KMOD_SHIFT; + + $ev->{dx} = $shift ? $delta : 0; + $ev->{dy} = $shift ? 0 : $delta; + $GRAB->emit (mouse_wheel => $ev); } else { $GRAB->emit (button_down => $ev) @@ -237,7 +243,7 @@ @_ }, $class; - Scalar::Util::weaken ($CFPlus::UI::WIDGET{$self+0} = $self); + CFPlus::weaken ($CFPlus::UI::WIDGET{$self+0} = $self); for (keys %$self) { if (/^on_(.*)$/) { @@ -268,6 +274,10 @@ %$self = (); } +sub TO_JSON { + { __widget_ref__ => $_[0]{s_id} } +} + sub show { my ($self) = @_; @@ -316,8 +326,8 @@ return if $self->{visible} == $visible; - $visible ? $self->hide - : $self->show; + $visible ? $self->show + : $self->hide; } sub toggle_visibility { @@ -532,28 +542,24 @@ #warn +(caller(1))[3] . "emit $signal on $self (parent $self->{parent})\n";#d# - #d##TODO# stop propagating at first true, do not use sum - (List::Util::sum map $_->($self, @args, @append), @{$self->{signal_cb}{$signal} || []}) # before - || ($self->can ("invoke_$signal") || sub { 1 })->($self, @args, @append) # closure - || ($self->{parent} && $self->{parent}->emit ($signal, @args)) # parent -} - -sub find_widget { - my ($self, $x, $y) = @_; - - return () unless $self->{can_events}; - - return $self - if $x >= $self->{x} && $x < $self->{x} + $self->{w} - && $y >= $self->{y} && $y < $self->{y} + $self->{h}; + for my $cb ( + @{$self->{signal_cb}{$signal} || []}, # before + ($self->can ("invoke_$signal") || sub { 1 }), # closure + ) { + return $cb->($self, @args, @append) || next; + } - () + # parent + $self->{parent} && $self->{parent}->emit ($signal, @args) } +#sub find_widget { +# in .xs + sub set_parent { my ($self, $parent) = @_; - Scalar::Util::weaken ($self->{parent} = $parent); + CFPlus::weaken ($self->{parent} = $parent); $self->set_visible if $parent->{visible}; } @@ -642,6 +648,7 @@ warn "no draw defined for $self\n"; } +my $cntx;#d# sub DESTROY { my ($self) = @_; @@ -736,7 +743,7 @@ ); $self->add (@$children) - if $children; + if $children && @$children; $self } @@ -755,6 +762,7 @@ $_->set_parent ($self) for @widgets; + # TODO: only do this in widgets that need it, e.g. root, fixed use sort 'stable'; $self->{children} = [ @@ -783,7 +791,7 @@ sub clear { my ($self) = @_; - my $children = delete $self->{children}; + my $children = $self->{children}; $self->{children} = []; for (@$children) { @@ -934,6 +942,8 @@ package CFPlus::UI::ViewPort; +use List::Util qw(min max); + our @ISA = CFPlus::UI::Window::; sub new { @@ -951,8 +961,8 @@ my ($w, $h) = @{$self->child}{qw(req_w req_h)}; - $w = 10 if $self->{scroll_x}; - $h = 10 if $self->{scroll_y}; + $w = 1 if $self->{scroll_x}; + $h = 1 if $self->{scroll_y}; ($w, $h) } @@ -974,10 +984,16 @@ sub set_offset { my ($self, $x, $y) = @_; - $self->{view_x} = int $x; - $self->{view_y} = int $y; + my $x = max 0, min $self->child->{w} - $self->{w}, int $x; + my $y = max 0, min $self->child->{h} - $self->{h}, int $y; - $self->update; + if ($x != $self->{view_x} or $y != $self->{view_y}) { + $self->{view_x} = $x; + $self->{view_y} = $y; + + $self->emit (changed => $x, $y); + $self->update; + } } # hmm, this does not work for topleft of $self... but we should not ask for that @@ -1002,7 +1018,7 @@ if ( $x >= $self->{x} && $x < $self->{x} + $self->{w} && $y >= $self->{y} && $y < $self->{y} + $self->{h} ) { - $self->child->find_widget ($x + $self->{view_x}, $y + $self->{view_y}) + $self->child->find_widget ($x + $self->{view_x}, $y + $self->{view_y}) } else { $self->CFPlus::UI::Base::find_widget ($x, $y) } @@ -1023,7 +1039,7 @@ package CFPlus::UI::ScrolledWindow; -our @ISA = CFPlus::UI::HBox::; +our @ISA = CFPlus::UI::Table::; sub new { my ($class, %arg) = @_; @@ -1032,64 +1048,155 @@ my $self; - my $slider = new CFPlus::UI::Slider + my $hslider = new CFPlus::UI::Slider + col => 0, + row => 1, + vertical => 0, + range => [0, 0, 1, 0.01], # HACK fix + on_changed => sub { + $self->{hpos} = $_[1]; + $self->{vp}->set_offset ($self->{hpos}, $self->{vpos}); + }, + ; + + my $vslider = new CFPlus::UI::Slider + col => 1, + row => 0, vertical => 1, range => [0, 0, 1, 0.01], # HACK fix on_changed => sub { - $self->{vp}->set_offset (0, $_[1]); + $self->{vpos} = $_[1]; + $self->{vp}->set_offset ($self->{hpos}, $self->{vpos}); }, ; $self = $class->SUPER::new ( - vp => (new CFPlus::UI::ViewPort expand => 1), + scroll_x => 0, + scroll_y => 1, can_events => 1, - slider => $slider, + hslider => $hslider, + vslider => $vslider, + col_expand => [1, 0], + row_expand => [1, 0], %arg, ); - $self->SUPER::add ($self->{vp}, $self->{slider}); + $self->{vp} = new CFPlus::UI::ViewPort + col => 0, + row => 0, + expand => 1, + scroll_x => $self->{scroll_x}, + scroll_y => $self->{scroll_y}, + on_changed => sub { + my ($vp, $x, $y) = @_; + + $vp->{parent}{hslider}->set_value ($x); + $vp->{parent}{vslider}->set_value ($y); + + 0 + }, + ; + + $self->SUPER::add ($self->{vp}); + $self->add ($child) if $child; $self } -#TODO# update range on size_allocate depending on child - sub add { my ($self, $widget) = @_; $self->{vp}->add ($self->{child} = $widget); } +sub update_slider { + my ($self) = @_; + + my $child = ($self->{vp} or return)->child; + + my ($w1, $w2) = ($child->{w}, $self->{vp}{w}); + $self->{hslider}->set_range ([$self->{hslider}{range}[0], 0, $w1, $w2, 1]); + + my $visible = $w1 > $w2; + if ($visible != $self->{hslider_visible}) { + $self->{hslider_visible} = $visible; + $visible ? $self->SUPER::add ($self->{hslider}) + : $self->SUPER::remove ($self->{hslider}); + } + + my ($h1, $h2) = ($child->{h}, $self->{vp}{h}); + $self->{vslider}->set_range ([$self->{vslider}{range}[0], 0, $h1, $h2, 1]); + + my $visible = $h1 > $h2; + if ($visible != $self->{vslider_visible}) { + $self->{vslider_visible} = $visible; + $visible ? $self->SUPER::add ($self->{vslider}) + : $self->SUPER::remove ($self->{vslider}); + } +} + + +sub start_dragging { + my ($self, $ev) = @_; + + $self->grab_focus; + + my $ox = $self->{vp}{view_x}; + my $oy = $self->{vp}{view_y}; + + $self->{motion} = sub { + my ($ev, $x, $y) = @_; + + $ox -= $ev->{xrel}; + $oy -= $ev->{yrel}; + + $self->{vp}->set_offset ($ox, $oy); + }; +} + sub invoke_mouse_wheel { my ($self, $ev) = @_; - return 0 unless $ev->{dy}; # only vertical movements + $self->{vslider}->emit (mouse_wheel => $ev); + $self->{hslider}->emit (mouse_wheel => $ev); - $self->{slider}->emit (mouse_wheel => $ev); + 1 +} + +sub invoke_button_down { + my ($self, $ev, $x, $y) = @_; + + $self->start_dragging ($ev); 1 } -sub update_slider { - my ($self) = @_; +sub invoke_button_up { + my ($self, $ev, $x, $y) = @_; + + if (delete $self->{motion}) { + return 1; + } - $self->{slider}->set_range ([$self->{slider}{range}[0], 0, $self->{vp}->child->{h}, $self->{vp}{h}, 1]); + 0 } -sub update { - my ($self) = @_; +sub invoke_mouse_motion { + my ($self, $ev, $x, $y) = @_; - $self->SUPER::update; + if ($self->{motion}) { + $self->{motion}->($ev, $x, $y); + return 1; + } - $self->update_slider; + 0 } sub invoke_size_allocate { my ($self, $w, $h) = @_; $self->update_slider; - $self->SUPER::invoke_size_allocate ($w, $h) } @@ -1249,6 +1356,10 @@ map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } qw(d1_border_top.png d1_border_right.png d1_border_left.png d1_border_bottom.png); +my @icon = + map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } + qw(x1_move.png x1_resize.png); + sub new { my ($class, %arg) = @_; @@ -1426,10 +1537,24 @@ my $border = $self->border; glColor @{ $self->{border_bg} }; - $border[0]->draw_quad_alpha (0, 0, $w, $border); - $border[1]->draw_quad_alpha (0, $border, $border, $ch); - $border[2]->draw_quad_alpha ($w - $border, $border, $border, $ch); - $border[3]->draw_quad_alpha (0, $h - $border, $w, $border); + $border[0]->draw_quad_alpha ( 0, 0, $w, $border); + $border[1]->draw_quad_alpha ( 0, $border, $border, $ch); + $border[2]->draw_quad_alpha ($w - $border, $border, $border, $ch); + $border[3]->draw_quad_alpha ( 0, $h - $border, $w, $border); + + # move + my $w2 = ($w - $border) * .5; + my $h2 = ($h - $border) * .5; + $icon[0]->draw_quad_alpha ( 0, $h2, $border, $border); + $icon[0]->draw_quad_alpha ($w - $border, $h2, $border, $border); + $icon[0]->draw_quad_alpha ($w2 , $h - $border, $border, $border); + + # resize + $icon[1]->draw_quad_alpha ( 0, 0, $border, $border); + $icon[1]->draw_quad_alpha ($w - $border, 0, $border, $border) + unless $self->{has_close_button}; + $icon[1]->draw_quad_alpha ( 0, $h - $border, $border, $border); + $icon[1]->draw_quad_alpha ($w - $border, $h - $border, $border, $border); if (@{$self->{bg}} < 4 || $self->{bg}[3]) { glColor @{ $self->{bg} }; @@ -1460,7 +1585,7 @@ package CFPlus::UI::Table; -our @ISA = CFPlus::UI::Base::; +our @ISA = CFPlus::UI::Container::; use List::Util qw(max sum); @@ -1471,47 +1596,37 @@ $class->SUPER::new ( col_expand => [], + row_expand => [], @_, ) } -sub children { - grep $_, map @$_, grep $_, @{ $_[0]{children} } -} - sub add { - my ($self) = shift; + my ($self, @widgets) = @_; - while (@_) { - my ($x, $y, $child) = splice @_, 0, 3, (); - $child->set_parent ($self); - $self->{children}[$y][$x] = $child; + for my $child (@widgets) { + $child->{rowspan} ||= 1; + $child->{colspan} ||= 1; } - $self->{force_realloc} = 1; - $self->{force_size_alloc} = 1; - $self->realloc; + $self->SUPER::add (@widgets); } -sub remove { - my ($self, $child) = @_; +sub add_at { + my $self = shift; - # TODO: not yet implemented -} + my @widgets; -# TODO: move to container class maybe? send children a signal on removal? -sub clear { - my ($self) = @_; + while (@_) { + my ($col, $row, $child) = splice @_, 0, 3, (); - my @children = $self->children; - delete $self->{children}; - - for (@children) { - delete $_->{parent}; - $_->hide; + $child->{row} = $row; + $child->{col} = $col; + + push @widgets, $child; } - $self->realloc; + $self->add (@widgets); } sub get_wh { @@ -1519,17 +1634,27 @@ my (@w, @h); - for my $y (0 .. $#{$self->{children}}) { - my $row = $self->{children}[$y] - or next; - - for my $x (0 .. $#$row) { - my $widget = $row->[$x] - or next; - my ($w, $h) = @$widget{qw(req_w req_h)}; + my @children = $self->children; - $w[$x] = max $w[$x], $w; - $h[$y] = max $h[$y], $h; + # first pass, columns + for my $widget (sort { $a->{colspan} <=> $b->{colspan} } @children) { + my ($c, $w, $cs) = @$widget{qw(col req_w colspan)}; + + my $sw = sum @w[$c .. $c + $cs - 1]; + + if ($w > $sw) { + $_ += ($w - $sw) / ($sw ? $sw / $_ : $cs) for @w[$c .. $c + $cs - 1]; + } + } + + # second pass, rows + for my $widget (sort { $a->{rowspan} <=> $b->{rowspan} } @children) { + my ($r, $h, $rs) = @$widget{qw(row req_h rowspan)}; + + my $sh = sum @h[$r .. $r + $rs - 1]; + + if ($h > $sh) { + $_ += ($h - $sh) / ($sh ? $sh / $_ : $rs) for @h[$r .. $r + $rs - 1]; } } @@ -1555,65 +1680,118 @@ my $req_w = (sum @$ws) || 1; my $req_h = (sum @$hs) || 1; - # TODO: nicer code && do row_expand + # now linearly scale the rows/columns to the allocated size my @col_expand = @{$self->{col_expand}}; @col_expand = (1) x @$ws unless @col_expand; my $col_expand = (sum @col_expand) || 1; - # linearly scale sizes $ws->[$_] += $col_expand[$_] / $col_expand * ($w - $req_w) for 0 .. $#$ws; - $hs->[$_] *= 1 * $h / $req_h for 0 .. $#$hs; CFPlus::UI::harmonize $ws; - CFPlus::UI::harmonize $hs; - my $y; + my @row_expand = @{$self->{row_expand}}; + @row_expand = (1) x @$ws unless @row_expand; + my $row_expand = (sum @row_expand) || 1; - for my $r (0 .. $#{$self->{children}}) { - my $row = $self->{children}[$r] - or next; + $hs->[$_] += $row_expand[$_] / $row_expand * ($h - $req_h) for 0 .. $#$hs; - my $x = 0; - my $row_h = $hs->[$r]; - - for my $c (0 .. $#$row) { - my $col_w = $ws->[$c]; + CFPlus::UI::harmonize $hs; - if (my $widget = $row->[$c]) { - $widget->configure ($x, $y, $col_w, $row_h); - } + my @x; for (0 .. $#$ws) { $x[$_ + 1] = $x[$_] + $ws->[$_] } + my @y; for (0 .. $#$hs) { $y[$_ + 1] = $y[$_] + $hs->[$_] } - $x += $col_w; - } + for my $widget ($self->children) { + my ($r, $c, $w, $h, $rs, $cs) = @$widget{qw(row col req_w req_h rowspan colspan)}; - $y += $row_h; + $widget->configure ( + $x[$c], $y[$r], + $x[$c + $cs] - $x[$c], $y[$r + $rs] - $y[$r], + ); } 1 } -sub find_widget { - my ($self, $x, $y) = @_; +############################################################################# - $x -= $self->{x}; - $y -= $self->{y}; +package CFPlus::UI::Fixed; - my $res; +use List::Util qw(min max); - for (grep $_, map @$_, grep $_, @{ $self->{children} }) { - $res = $_->find_widget ($x, $y) - and return $res; - } +our @ISA = CFPlus::UI::Container::; - $self->SUPER::find_widget ($x + $self->{x}, $y + $self->{y}) +sub add { + my ($self, $child, $posmode, $x, $y, $sizemode, $w, $h) = @_; + + $child->{_fixed} = [$posmode, $x, $y, $sizemode, $w, $h]; + $self->SUPER::add ($child); } -sub _draw { +sub _scale($$$) { + my ($mode, $val, $max) = @_; + + $mode eq "abs" ? $val + : $mode eq "rel" ? $val * $max + : 0 +} + +sub size_request { my ($self) = @_; - for (grep $_, @{$self->{children}}) { - $_->draw for grep $_, @$_; + my ($x1, $y1, $x2, $y2) = (0, 0, 0, 0); + + # determine overall size by querying abs widgets + for my $child ($self->visible_children) { + my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + + if ($pos eq "abs") { + $w = _scale $size, $w, $child->{req_w}; + $h = _scale $size, $h, $child->{req_h}; + + $x1 = min $x1, $x; $x2 = max $x2, $x + $w; + $y1 = min $y1, $y; $y2 = max $y2, $y + $h; + } + } + + my $W = $x2 - $x1; + my $H = $y2 - $y1; + + # now layout remaining widgets + for my $child ($self->visible_children) { + my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + + if ($pos ne "abs") { + $x = _scale $pos, $x, $W; + $y = _scale $pos, $x, $H; + $w = _scale $size, $w, $child->{req_w}; + $h = _scale $size, $h, $child->{req_h}; + + $x1 = min $x1, $x; $x2 = max $x2, $x + $w; + $y1 = min $y1, $y; $y2 = max $y2, $y + $h; + } + } + + my $W = $x2 - $x1; + my $H = $y2 - $y1; + + ($W, $H) +} + +sub invoke_size_allocate { + my ($self, $W, $H) = @_; + + for my $child ($self->visible_children) { + my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + + $x = _scale $pos, $x, $W; + $y = _scale $pos, $x, $H; + $w = _scale $size, $w, $child->{req_w}; + $h = _scale $size, $h, $child->{req_h}; + + $child->configure ($x, $y, $w, $h); } + + 1 } ############################################################################# @@ -1964,6 +2142,8 @@ my $text = $self->get_text; + $self->{cursor} = List::Util::max 0, List::Util::min $self->{cursor}, length $text; + if ($uni == 8) { substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; } elsif ($uni == 127) { @@ -1973,15 +2153,25 @@ } elsif ($sym == CFPlus::SDLK_RIGHT) { ++$self->{cursor} if $self->{cursor} < length $self->{text}; } elsif ($sym == CFPlus::SDLK_HOME) { - $self->{cursor} = 0; + # what a hack + $self->{cursor} = + (substr $self->{text}, 0, $self->{cursor}) =~ /^(.*\012)/ + ? length $1 + : 0; } elsif ($sym == CFPlus::SDLK_END) { - $self->{cursor} = length $text; + # uh, again + $self->{cursor} = + (substr $self->{text}, $self->{cursor}) =~ /^([^\012]*)\012/ + ? $self->{cursor} + length $1 + : length $self->{text}; } elsif ($uni == 21) { # ctrl-u $text = ""; $self->{cursor} = 0; } elsif ($uni == 27) { $self->emit ('escape'); - } elsif ($uni >= 0x20 || $uni == 0x0d) { + } elsif ($uni == 0x0d) { + substr $text, $self->{cursor}++, 0, "\012"; + } elsif ($uni >= 0x20) { substr $text, $self->{cursor}++, 0, chr $uni; } else { return 0; @@ -2169,7 +2359,7 @@ my @tex = map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } - qw(b1_button_active.png); + qw(b1_button_inactive.png b1_button_active.png); sub new { my $class = shift; @@ -2177,8 +2367,8 @@ $class->SUPER::new ( padding_x => 4, padding_y => 4, - fg => [1, 1, 1], - active_fg => [0, 0, 1], + fg => [1.0, 1.0, 1.0], + active_fg => [0.8, 0.8, 0.8], can_hover => 1, align => 0, valign => 0, @@ -2206,7 +2396,8 @@ glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; glColor 0, 0, 0, 1; - $tex[0]->draw_quad_alpha (0, 0, $self->{w}, $self->{h}); + my $tex = $tex[$GRAB == $self]; + $tex->draw_quad_alpha (0, 0, $self->{w}, $self->{h}); glDisable GL_TEXTURE_2D; @@ -2312,7 +2503,7 @@ $self->{tex} ||= $texture_cache{$self->{path}} ||= new_from_file CFPlus::Texture CFPlus::find_rcfile $self->{path}, mipmap => 1; - Scalar::Util::weaken $texture_cache{$self->{path}}; + CFPlus::weaken $texture_cache{$self->{path}}; $self->{aspect} ||= $self->{tex}{w} / $self->{tex}{h}; @@ -2695,7 +2886,9 @@ my $delta = $self->{vertical} ? $ev->{dy} : $ev->{dx}; - $self->set_value ($self->{range}[0] + $delta * $self->{range}[3] * 0.2); + my $pagepart = $ev->{mod} & CFPlus::KMOD_SHIFT ? 1 : 0.2; + + $self->set_value ($self->{range}[0] + $delta * $self->{range}[3] * $pagepart); ! ! $delta } @@ -2815,6 +3008,7 @@ layout => (new CFPlus::Layout), par => [], + max_par => 0, height => 0, children => [ (new CFPlus::UI::Empty expand => 1), @@ -2949,6 +3143,10 @@ push @{$self->{par}}, $para; } + if (my $max = $self->{max_par}) { + shift @{$self->{par}} while @{$self->{par}} > $max; + } + $self->{need_reflow}++; $self->update; } @@ -3264,30 +3462,84 @@ my $class = shift; my $self = $class->SUPER::new ( + size_w => 32, + size_h => 8, aspect => 1, can_events => 0, @_, ); if ($self->{anim} && $self->{animspeed}) { - Scalar::Util::weaken (my $widget = $self); + CFPlus::weaken (my $widget = $self); + $widget->{animspeed} = List::Util::max 0.05, $widget->{animspeed}; + $widget->{anim_start} = $self->{animspeed} * Event::time / $self->{animspeed}; $self->{timer} = Event->timer ( - at => $self->{animspeed} * int $::NOW / $self->{animspeed}, - hard => 1, - interval => $self->{animspeed}, + parked => 1, cb => sub { + return unless $::CONN && $widget; + ++$widget->{frame}; + $widget->update_face; $widget->update; + + $widget->update_timer; }, ); + + $self->update_face; + $self->update_timer; } $self } +sub update_timer { + my ($self) = @_; + + return unless $self->{timer}; + + if ($self->{visible}) { + $self->{timer}->at ( + $self->{anim_start} + + $self->{animspeed} + * int 1.5 + (Event::time - $self->{anim_start}) / $self->{animspeed} + ); + $self->{timer}->start; + } else { + $self->{timer}->stop; + } +} + +sub update_face { + my ($self) = @_; + + return unless $::CONN; + + if (my $anim = $::CONN->{anim}[$self->{anim}]) { + if ($anim && @$anim) { + delete $self->{wait_face}; + $self->{face} = $anim->[ $self->{frame} % @$anim ]; + } + } +} + sub size_request { - (32, 8) + my ($self) = @_; + + if ($::CONN) { + if (my $faceid = $::CONN->{faceid}[$self->{face}]) { + if (my $tex = $::CONN->{texture}[$faceid]) { + return ($self->{size_w} || $tex->{w}, $self->{size_h} || $tex->{h}); + } else { + $self->{wait_face} ||= $::CONN->connect_face_update ($faceid, sub { + $self->realloc; + }); + } + } + } + + ($self->{size_w} || 8, $self->{size_h} || 8) } sub update { @@ -3298,6 +3550,14 @@ $self->SUPER::update; } +sub invoke_visibility_change { + my ($self) = @_; + + $self->update_timer; + + 0 +} + sub _draw { my ($self) = @_; @@ -3305,16 +3565,10 @@ $self->SUPER::_draw; - my $face; - - if ($self->{frame}) { - my $anim = $::CONN->{anim}[$self->{anim}]; - - $face = $anim->[ $self->{frame} % @$anim ] - if $anim && @$anim; - } + my $faceid = $::CONN->{faceid}[$self->{face}] + or return; - my $tex = $::CONN->{texture}[$::CONN->{faceid}[$face || $self->{face}]]; + my $tex = $::CONN->{texture}[$faceid]; if ($tex) { glEnable GL_TEXTURE_2D; @@ -3328,7 +3582,7 @@ sub destroy { my ($self) = @_; - $self->{timer}->cancel + (delete $self->{timer})->cancel if $self->{timer}; $self->SUPER::destroy; @@ -3534,7 +3788,7 @@ sub add { my ($self, $title, $widget, $tooltip) = @_; - Scalar::Util::weaken $self; + CFPlus::weaken $self; $self->{buttonbar}->add (new CFPlus::UI::Button markup => $title, @@ -3628,7 +3882,7 @@ @_, ); - Scalar::Util::weaken (my $this = $self); + CFPlus::weaken (my $this = $self); $self->{timer} = Event->timer (after => 1, interval => 1, cb => sub { $this->reorder }); @@ -3777,7 +4031,7 @@ @_, ); - Scalar::Util::weaken ($self->{root} = $self); + CFPlus::weaken ($self->{root} = $self); $self } @@ -3982,7 +4236,6 @@ for values %{delete $self->{post_alloc_hook}}; } - glViewport 0, 0, $::WIDTH, $::HEIGHT; glClearColor +($::CFG->{fow_intensity}) x 3, 1; glClear GL_COLOR_BUFFER_BIT;