--- deliantra/Deliantra-Client/DC/UI.pm 2007/07/21 23:17:35 1.406 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/08/21 23:42:02 1.432 @@ -275,7 +275,7 @@ } sub TO_JSON { - { __widget_ref__ => $_[0]{s_id} } + { __w_ => $_[0]{s_id} } } sub show { @@ -609,6 +609,7 @@ return if CFPlus::in_destruct; + local $@; eval { $self->destroy }; warn "exception during widget destruction: $@" if $@ & $@ != /during global destruction/; @@ -627,8 +628,6 @@ sub new { my $class = shift; - # range [value, low, high, page] - $class->SUPER::new ( #bg => [0, 0, 0, 0.2], #active_bg => [1, 1, 1, 0.5], @@ -649,14 +648,7 @@ glEnable GL_BLEND; glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; glColor_premultiply @$color; - - glBegin GL_QUADS; - glVertex 0 , 0; - glVertex 0 , $h; - glVertex $w, $h; - glVertex $w, 0; - glEnd; - + glRect 0, 0, $w, $h; glDisable GL_BLEND; } } @@ -727,6 +719,8 @@ $self->realloc; + $self->emit (c_add => \@widgets); + map $_+0, @widgets } @@ -735,12 +729,15 @@ } sub remove { - my ($self, $child) = @_; + my ($self, @widgets) = @_; - delete $child->{parent}; - $child->hide; + $self->emit (c_remove => \@widgets); - $self->{children} = [ grep $_ != $child, @{ $self->{children} } ]; + for my $child (@widgets) { + delete $child->{parent}; + $child->hide; + $self->{children} = [ grep $_ != $child, @{ $self->{children} } ]; + } $self->realloc; } @@ -778,7 +775,7 @@ sub _draw { my ($self) = @_; - $_->draw for @{$self->{children}}; + $_->draw for $self->visible_children; } ############################################################################# @@ -798,7 +795,7 @@ sub add { my ($self, $child) = @_; - $self->SUPER::remove ($_) for @{ $self->{children} }; + $self->clear; $self->SUPER::add ($child); } @@ -953,6 +950,24 @@ } } +sub set_center { + my ($self, $x, $y) = @_; + + $self->set_offset ($x - $self->{w} * .5, $y - $self->{h} * .5); +} + +sub make_visible { + my ($self, $x, $y, $border) = @_; + + if ( $x < $self->{view_x} + $self->{w} * $border + || $x > $self->{view_x} + $self->{w} * (1 - $border) + || $y < $self->{view_y} + $self->{h} * $border + || $y > $self->{view_y} + $self->{h} * (1 - $border) + ) { + $self->set_center ($x, $y); + } +} + # hmm, this does not work for topleft of $self... but we should not ask for that sub coord2local { my ($self, $x, $y) = @_; @@ -1006,8 +1021,8 @@ my $self; my $hslider = new CFPlus::UI::Slider - col => 0, - row => 1, + c_col => 0, + c_row => 1, vertical => 0, range => [0, 0, 1, 0.01], # HACK fix on_changed => sub { @@ -1017,8 +1032,8 @@ ; my $vslider = new CFPlus::UI::Slider - col => 1, - row => 0, + c_col => 1, + c_row => 0, vertical => 1, range => [0, 0, 1, 0.01], # HACK fix on_changed => sub { @@ -1039,8 +1054,8 @@ ); $self->{vp} = new CFPlus::UI::ViewPort - col => 0, - row => 0, + c_col => 0, + c_row => 0, expand => 1, scroll_x => $self->{scroll_x}, scroll_y => $self->{scroll_y}, @@ -1072,6 +1087,10 @@ $self->{vp}->add ($self->{child} = $widget); } +sub set_offset { shift->{vp}->set_offset (@_) } +sub set_center { shift->{vp}->set_center (@_) } +sub make_visible { shift->{vp}->make_visible (@_) } + sub update_slider { my ($self) = @_; @@ -1194,14 +1213,7 @@ glEnable GL_BLEND; glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; glColor_premultiply @{ $self->{bg} }; - - glBegin GL_QUADS; - glVertex 0 , 0; - glVertex 0 , $h; - glVertex $w, $h; - glVertex $w, 0; - glEnd; - + glRect 0, 0, $w, $h; glDisable GL_BLEND; } @@ -1573,8 +1585,8 @@ my ($self, @widgets) = @_; for my $child (@widgets) { - $child->{rowspan} ||= 1; - $child->{colspan} ||= 1; + $child->{c_rowspan} ||= 1; + $child->{c_colspan} ||= 1; } $self->SUPER::add (@widgets); @@ -1588,8 +1600,8 @@ while (@_) { my ($col, $row, $child) = splice @_, 0, 3, (); - $child->{row} = $row; - $child->{col} = $col; + $child->{c_row} = $row; + $child->{c_col} = $col; push @widgets, $child; } @@ -1605,8 +1617,8 @@ my @children = $self->children; # first pass, columns - for my $widget (sort { $a->{colspan} <=> $b->{colspan} } @children) { - my ($c, $w, $cs) = @$widget{qw(col req_w colspan)}; + for my $widget (sort { $a->{c_colspan} <=> $b->{c_colspan} } @children) { + my ($c, $w, $cs) = @$widget{qw(c_col req_w c_colspan)}; my $sw = sum @w[$c .. $c + $cs - 1]; @@ -1616,8 +1628,8 @@ } # second pass, rows - for my $widget (sort { $a->{rowspan} <=> $b->{rowspan} } @children) { - my ($r, $h, $rs) = @$widget{qw(row req_h rowspan)}; + for my $widget (sort { $a->{c_rowspan} <=> $b->{c_rowspan} } @children) { + my ($r, $h, $rs) = @$widget{qw(c_row req_h c_rowspan)}; my $sh = sum @h[$r .. $r + $rs - 1]; @@ -1669,7 +1681,7 @@ my @y; for (0 .. $#$hs) { $y[$_ + 1] = $y[$_] + $hs->[$_] } for my $widget ($self->children) { - my ($r, $c, $w, $h, $rs, $cs) = @$widget{qw(row col req_w req_h rowspan colspan)}; + my ($r, $c, $w, $h, $rs, $cs) = @$widget{qw(c_row c_col req_w req_h c_rowspan c_colspan)}; $widget->configure ( $x[$c], $y[$r], @@ -1688,19 +1700,10 @@ our @ISA = CFPlus::UI::Container::; -sub add_fixed { - my ($self, $child, $posmode, $x, $y, $sizemode, $w, $h) = @_; - - $child->{_fixed} = [$posmode, $x, $y, $sizemode, $w, $h]; - $self->SUPER::add ($child); -} - sub _scale($$$) { - my ($mode, $val, $max) = @_; + my ($rel, $val, $max) = @_; - $mode eq "abs" ? $val - : $mode eq "rel" ? $val * $max - : 0 + $rel ? $val * $max : $val } sub size_request { @@ -1710,14 +1713,12 @@ # determine overall size by querying abs widgets for my $child ($self->visible_children) { - my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + unless ($child->{c_rel}) { + my $x = $child->{c_x}; + my $y = $child->{c_y}; - 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; + $x1 = min $x1, $x; $x2 = max $x2, $x + $child->{req_w}; + $y1 = min $y1, $y; $y2 = max $y2, $y + $child->{req_h}; } } @@ -1726,16 +1727,12 @@ # 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}; + if ($child->{c_rel}) { + my $x = _scale $child->{c_rel}, $child->{c_x}, $W; + my $y = _scale $child->{c_rel}, $child->{c_y}, $H; - $x1 = min $x1, $x; $x2 = max $x2, $x + $w; - $y1 = min $y1, $y; $y2 = max $y2, $y + $h; + $x1 = min $x1, $x; $x2 = max $x2, $x + $child->{req_w}; + $y1 = min $y1, $y; $y2 = max $y2, $y + $child->{req_h}; } } @@ -1749,14 +1746,13 @@ my ($self, $W, $H) = @_; for my $child ($self->visible_children) { - my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + my $x = _scale $child->{c_rel}, $child->{c_x}, $W; + my $y = _scale $child->{c_rel}, $child->{c_y}, $H; - $x = _scale $pos, $x, $W; - $y = _scale $pos, $x, $H; - $w = _scale $size, $w, $W; - $h = _scale $size, $h, $H; + $x += $child->{c_halign} * $child->{req_w}; + $y += $child->{c_valign} * $child->{req_h}; - $child->configure ($x, $y, $w, $h); + $child->configure (int $x, int $y, $child->{req_w}, $child->{req_h}); } 1 @@ -1771,14 +1767,16 @@ sub size_request { my ($self) = @_; + my @children = $self->visible_children; + $self->{vertical} ? ( - (List::Util::max map $_->{req_w}, @{$self->{children}}), - (List::Util::sum map $_->{req_h}, @{$self->{children}}), + (List::Util::max map $_->{req_w}, @children), + (List::Util::sum map $_->{req_h}, @children), ) : ( - (List::Util::sum map $_->{req_w}, @{$self->{children}}), - (List::Util::max map $_->{req_h}, @{$self->{children}}), + (List::Util::sum map $_->{req_w}, @children), + (List::Util::max map $_->{req_h}, @children), ) } @@ -1912,6 +1910,12 @@ $self->SUPER::realloc; } +sub clear { + my ($self) = @_; + + $self->set_text (""); +} + sub set_text { my ($self, $text) = @_; @@ -2027,10 +2031,29 @@ $self->{oy} = int ($self->{valign} < 0 ? $self->{padding_y} : $self->{valign} > 0 ? $self->{h} - $size->[1] - $self->{padding_y} : ($self->{h} - $size->[1]) * 0.5); + + $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); }; - $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); -} +# unless ($self->{list}) { +# $self->{list} = CFPlus::OpenGL::glGenList; +# CFPlus::OpenGL::glNewList $self->{list}; +# $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); +# CFPlus::OpenGL::glEndList; +# } +# +# CFPlus::OpenGL::glCallList $self->{list}; + + $self->{layout}->draw; +} + +#sub destroy { +# my ($self) = @_; +# +# CFPlus::OpenGL::glDeleteList delete $self->{list} if $self->{list}; +# +# $self->SUPER::destroy; +#} ############################################################################# @@ -2046,8 +2069,10 @@ $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], + outline => [0.6, 0.3, 0.1], + active_bg => [0, 0, 1, .2], + active_fg => [1, 1, 1], + active_outline => [1, 1, 0], can_hover => 1, can_focus => 1, valign => 0, @@ -2197,12 +2222,7 @@ glEnable GL_BLEND; glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; - glBegin GL_QUADS; - glVertex 0 , 0; - glVertex 0 , $self->{h}; - glVertex $self->{w}, $self->{h}; - glVertex $self->{w}, 0; - glEnd; + glRect 0, 0, $self->{w}, $self->{h}; glDisable GL_BLEND; $self->SUPER::_draw; @@ -2214,13 +2234,29 @@ my $text = substr $self->{text}, 0, $self->{cursor}; utf8::encode $text; - @$self{qw(cur_x cur_y cur_h)} = $self->{layout}->cursor_pos (length $text) + @$self{qw(cur_x cur_y cur_h)} = $self->{layout}->cursor_pos (length $text); } + glColor_premultiply @{$self->{active_fg}}; glBegin GL_LINES; glVertex 0.5 + $self->{cur_x} + $self->{ox}, $self->{cur_y} + $self->{oy}; glVertex 0.5 + $self->{cur_x} + $self->{ox}, $self->{cur_y} + $self->{oy} + $self->{cur_h}; glEnd; + + glLineWidth 3; + glColor @{$self->{active_outline}}; + glRect_lineloop 0, 0, $self->{w} - 1, $self->{h} - 1; + glLineWidth 1; + + } else { + glColor @{$self->{outline}}; + glTranslate .375, .375; + glBegin GL_LINE_STRIP; + glVertex 0, $self->{h} * .5; + glVertex 0, $self->{h} - 3; + glVertex $self->{w} - 1, $self->{h} - 3; + glVertex $self->{w} - 1, $self->{h} * .5; + glEnd; } } @@ -2316,6 +2352,55 @@ ############################################################################# +package CFPlus::UI::ButtonBin; + +our @ISA = CFPlus::UI::Bin::; + +use CFPlus::OpenGL; + +my @tex = + map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } + qw(b1_button_inactive.png b1_button_active.png); + +sub new { + my $class = shift; + + $class->SUPER::new ( + can_hover => 1, + align => 0, + valign => 0, + can_events => 1, + @_ + ) +} + +sub invoke_button_up { + my ($self, $ev, $x, $y) = @_; + + $self->emit ("activate") + if $x >= 0 && $x < $self->{w} + && $y >= 0 && $y < $self->{h}; + + 1 +} + +sub _draw { + my ($self) = @_; + + glEnable GL_TEXTURE_2D; + glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + glColor 0, 0, 0, 1; + + my $tex = $tex[$GRAB == $self]; + $tex->draw_quad_alpha (0, 0, $self->{w}, $self->{h}); + + glDisable GL_TEXTURE_2D; + + $self->SUPER::_draw; +} + +############################################################################# + package CFPlus::UI::Button; our @ISA = CFPlus::UI::Label::; @@ -2459,6 +2544,7 @@ my $self = $class->SUPER::new ( can_events => 0, + scale => 1, @_, ); @@ -2493,7 +2579,7 @@ sub size_request { my ($self) = @_; - ($self->{tex}{w}, $self->{tex}{h}) + (int $self->{tex}{w} * $self->{scale}, int $self->{tex}{h} * $self->{scale}) } sub _draw { @@ -2513,7 +2599,7 @@ glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; - $tex->draw_quad (0, 0, $w, $h); + $tex->draw_quad_alpha (0, 0, $w, $h); glDisable GL_TEXTURE_2D; } @@ -2544,6 +2630,12 @@ ); } +sub invoke_button_down { + my ($self, $ev, $x, $y) = @_; + + 1 +} + sub invoke_button_up { my ($self, $ev, $x, $y) = @_; @@ -2691,6 +2783,119 @@ ############################################################################# +package CFPlus::UI::Progress; + +our @ISA = CFPlus::UI::Label::; + +use CFPlus::OpenGL; + +sub new { + my ($class, %arg) = @_; + + my $self = $class->SUPER::new ( + fg => [1, 1, 1], + bg => [0, 0, 1, 0.2], + bar => [0.7, 0.5, 0.1, 0.8], + outline => [0.4, 0.3, 0], + fontsize => 0.9, + valign => 0, + align => 0, + can_events => 1, + ellipsise => 1, + %arg, + ); + + $self->set_value ($arg{value} || -1); + + $self +} + +sub set_value { + my ($self, $value) = @_; + + if ($self->{value} != $value) { + $self->{value} = $value; + + if ($value < 0) { + $self->set_text ("-"); + } else { + $self->set_text (sprintf "%d%%", $value * 100); + } + $self->update; + } +} + +sub _draw { + my ($self) = @_; + + glEnable GL_BLEND; + glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; + + if ($self->{value} >= 0) { + my $s = 3 + ($self->{w} - 6) * $self->{value}; + + glColor_premultiply @{$self->{bar}}; + glRect 2, 2, $s, $self->{h} - 2; + glColor_premultiply @{$self->{bg}}; + glRect $s + 1, 0, $self->{w} - 2, $self->{h} - 2; + } + + glColor_premultiply @{$self->{outline}}; + glRect_lineloop 1, 1, $self->{w} - 2, $self->{h} - 2; + + glDisable GL_BLEND; + + { + local $self->{bg}; # do not draw background + $self->SUPER::_draw; + } +} + +############################################################################# + +package CFPlus::UI::ExperienceProgress; + +our @ISA = CFPlus::UI::Progress::; + +sub new { + my ($class, %arg) = @_; + + my $self = $class->SUPER::new ( + %arg + ); + + $::CONN->{on_exp_update}{$self+0} = sub { $self->set_value ($self->{value}) } + if $::CONN; + + $self +} + +sub DESTROY { + my ($self) = @_; + + delete $::CONN->{on_exp_update}{$self+0} + if $::CONN; + + $self->SUPER::DESTROY; +} + +sub set_value { + my ($self, $lvl, $exp) = @_; + + my $v = -1; + + if ($::CONN && (my $table = $::CONN->{exp_table})) { + my $l0 = $table->[$lvl - 1]; + my $l1 = $table->[$lvl]; + + $v = ($exp - $l0) / ($l1 - $l0); + } + + $self->SUPER::set_value ($v); +} + +############################################################################# + package CFPlus::UI::Gauge; our @ISA = CFPlus::UI::VBox::; @@ -2825,7 +3030,9 @@ $self->{click} = [$self->{range}[0], $self->{vertical} ? $y : $x]; - $self->invoke_mouse_motion ($ev, $x, $y) + $self->invoke_mouse_motion ($ev, $x, $y); + + 1 } sub invoke_mouse_motion { @@ -2855,7 +3062,7 @@ $self->set_value ($self->{range}[0] + $delta * $self->{range}[3] * $pagepart); - ! ! $delta + 1 } sub update { @@ -2996,7 +3203,7 @@ sub size_request { my ($self) = @_; - my ($empty, $slider) = @{ $self->{children} }; + my ($empty, $slider) = $self->visible_children; local $self->{children} = [$empty, $slider]; $self->SUPER::size_request @@ -3195,6 +3402,7 @@ my $layout = $self->get_layout ($para); $layout->render ($para->{indent}, $y - $y0); + $layout->draw; if (my @w = @{ $para->{widget} }) { my @s = $layout->get_shapes; @@ -3395,20 +3603,10 @@ my ($w, $h) = @$self{qw(w h)}; glColor 1, 0.8, 0.4; - glBegin GL_QUADS; - glVertex 0 , 0; - glVertex 0 , $h; - glVertex $w, $h; - glVertex $w, 0; - glEnd; + glRect 0, 0, $w, $h; glColor 0, 0, 0; - glBegin GL_LINE_LOOP; - glVertex 0 , 0; - glVertex 0 , $h; - glVertex $w, $h; - glVertex $w, 0; - glEnd; + glRect_lineloop 0, 0, $w, $h; glTranslate 2 - 0.375, 2 - 0.375; @@ -3442,13 +3640,17 @@ $self->{timer} = Event->timer ( parked => 1, cb => sub { - return unless $::CONN && $widget; + return unless $::CONN; - ++$widget->{frame}; - $widget->update_face; - $widget->update; + my $w = $widget + or return; - $widget->update_timer; + ++$w->{frame}; + $w->update_face; + + # somehow, $widget can go away + $w->update; + $w->update_timer; }, ); @@ -3479,13 +3681,18 @@ 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 ]; - $self->{tex} = $::CONN->{texture}[ $::CONN->{faceid}[$self->{face}] ]; + if ($::CONN) { + if (my $anim = $::CONN->{anim}[$self->{anim}]) { + if ($anim && @$anim) { + $self->{face} = $anim->[ $self->{frame} % @$anim ]; + delete $self->{face_change_cb}; + + if (my $tex = $self->{tex} = $::CONN->{texture}[ $::CONN->{face}[$self->{face}]{id} ]) { + unless ($tex->{name} || $tex->{loading}) { + $tex->upload (sub { $self->reconfigure }); + } + } + } } } } @@ -3494,15 +3701,16 @@ my ($self) = @_; if ($::CONN) { - if (my $faceid = $::CONN->{faceid}[$self->{face}]) { - if (my $tex = $::CONN->{texture}[$faceid]) { - $self->{tex} = $tex; - return ($self->{size_w} || $tex->{w}, $self->{size_h} || $tex->{h}); - } else { - $self->{wait_face} ||= $::CONN->connect_face_update ($faceid, sub { - $self->realloc; - }); + if (my $faceid = $::CONN->{face}[$self->{face}]{id}) { + if (my $tex = $self->{tex} = $::CONN->{texture}[$faceid]) { + if ($tex->{name}) { + return ($self->{size_w} || $tex->{w}, $self->{size_h} || $tex->{h}); + } elsif (!$tex->{loading}) { + $tex->upload (sub { $self->reconfigure }); + } } + + $self->{face_change_cb} ||= $::CONN->on_face_change ($self->{face}, sub { $self->reconfigure }); } } @@ -3592,7 +3800,7 @@ (new CFPlus::UI::Label markup => $right, align => +1), ], ; - + } else { $widget = new CFPlus::UI::Label can_hover => 1, @@ -3727,36 +3935,85 @@ package CFPlus::UI::Notebook; +use CFPlus::OpenGL; + our @ISA = CFPlus::UI::VBox::; sub new { my $class = shift; my $self = $class->SUPER::new ( - buttonbar => (new CFPlus::UI::Buttonbar), - multiplexer => (new CFPlus::UI::Multiplexer expand => 1), + buttonbar => (new CFPlus::UI::Buttonbar), + multiplexer => (new CFPlus::UI::Multiplexer expand => 1), + active_outline => [1, 1, 0], # filter => # will be put between multiplexer and $self @_, ); - + $self->{filter}->add ($self->{multiplexer}) if $self->{filter}; $self->SUPER::add ($self->{buttonbar}, $self->{filter} || $self->{multiplexer}); + { + Scalar::Util::weaken (my $wself = $self); + + $self->{multiplexer}->connect (c_add => sub { + my ($mplex, $widgets) = @_; + + for my $child (@$widgets) { + Scalar::Util::weaken $child; + $child->{c_tab_} ||= do { + my $tab = + (UNIVERSAL::isa $child->{c_tab}, "CFPlus::UI::Base") + ? $child->{c_tab} + : new CFPlus::UI::Button markup => $child->{c_tab}[0], tooltip => $child->{c_tab}[1]; + + $tab->connect (activate => sub { + $wself->set_current_page ($child); + }); + + $tab + }; + + $self->{buttonbar}->add ($child->{c_tab_}); + } + }); + + $self->{multiplexer}->connect (c_remove => sub { + my ($mplex, $widgets) = @_; + + for my $child (@$widgets) { + $wself->{buttonbar}->remove ($child->{c_tab_}); + } + }); + } + $self } sub add { - my ($self, $title, $widget, $tooltip) = @_; + my ($self, @widgets) = @_; - CFPlus::weaken $self; + $self->{multiplexer}->add (@widgets) +} - $self->{buttonbar}->add (new CFPlus::UI::Button - markup => $title, - tooltip => $tooltip, - on_activate => sub { $self->set_current_page ($widget) }, - ); +sub remove { + my ($self, @widgets) = @_; + + $self->{multiplexer}->remove (@widgets) +} + +sub pages { + my ($self) = @_; + $self->{multiplexer}->children +} + +sub add_tab { + my ($self, $title, $widget, $tooltip) = @_; - $self->{multiplexer}->add ($widget); + $title = [$title, $tooltip] unless ref $title; + $widget->{c_tab} = $title; + + $self->add ($widget); } sub get_current_page { @@ -3772,6 +4029,22 @@ $self->emit (page_changed => $self->{multiplexer}{current}); } +sub _draw { + my ($self) = @_; + + $self->SUPER::_draw (); + + if (my $cur = $self->{multiplexer}{current}) { + if ($cur = $cur->{c_tab_}) { + glTranslate $cur->{x}, $cur->{y}; + glLineWidth 3; + glColor @{$self->{active_outline}}; + glRect_lineloop 1, 1, $cur->{w} - 2, $cur->{h} - 2; + glLineWidth 1; + } + } +} + ############################################################################# package CFPlus::UI::Selector; @@ -4049,7 +4322,7 @@ sub update { my ($self) = @_; - $::WANT_REFRESH++; + $::WANT_REFRESH->start; } sub add {