--- deliantra/Deliantra-Client/DC/UI.pm 2007/12/28 15:05:33 1.458 +++ deliantra/Deliantra-Client/DC/UI.pm 2010/02/04 20:01:09 1.479 @@ -1,10 +1,11 @@ package DC::UI; -use utf8; -use strict; +use common::sense; use List::Util (); +use Guard (); + use DC; use DC::Pod; use DC::Texture; @@ -191,7 +192,7 @@ my ($sx, $sy) = @_; for my $widget (values %WIDGET) { - if ($widget->{is_toplevel}) { + if ($widget->{is_toplevel} || $widget->{c_rescale}) { $widget->{x} += int $widget->{w} * 0.5 if $widget->{x} =~ /^[0-9.]+$/; $widget->{y} += int $widget->{h} * 0.5 if $widget->{y} =~ /^[0-9.]+$/; @@ -288,6 +289,9 @@ return if $self->{visible}; + $self->{parent} && $self->{parent}{root}#d# + or return ::clienterror ("set_visible called without parent ($self->{parent}) or root\n" => 1); + $self->{root} = $self->{parent}{root}; $self->{visible} = $self->{parent}{visible} + 1; @@ -295,7 +299,7 @@ $self->realloc if !exists $self->{req_w}; - $_->set_visible for $self->children; + $_->set_visible for $self->visible_children; } sub set_invisible { @@ -370,10 +374,18 @@ sub get_max_wh { my ($self) = @_; - return $self->{parent}->get_max_wh - if $self->{parent}; + my ($w, $h) = @$self{qw(max_w max_h)}; - ($::WIDTH, $::HEIGHT) + if ($w <= 0 || $h <= 0) { + my ($mw, $mh) = $self->{parent} + ? $self->{parent}->get_max_wh + : ($::WIDTH, $::HEIGHT); + + $w = $mw if $w <= 0; + $h = $mh if $h <= 0; + } + + ($w, $h) } sub size_request { @@ -521,7 +533,7 @@ push @{ $self->{signal_cb}{$signal} }, $cb; - defined wantarray and DC::guard { + defined wantarray and Guard::guard { @{ $self->{signal_cb}{$signal} } = grep $_ != $cb, @{ $self->{signal_cb}{$signal} }; } @@ -645,11 +657,18 @@ ) } +sub set_bg { + my ($self, $bg) = @_; + + $self->{bg} = $bg; + $self->update; +} + sub _draw { my ($self) = @_; - my $color = $FOCUS == $self && $self->{active_bg} - ? $self->{active_bg} + my $color = $FOCUS == $self + ? $self->{active_bg} || $self->{bg} : $self->{bg}; if ($color && (@$color < 4 || $color->[3])) { @@ -1243,14 +1262,14 @@ if ((exists $arg{label}) && !ref $arg{label}) { $arg{label} = new DC::UI::Label align => 1, - valign => 0, + valign => 0.5, text => $arg{label}, fontsize => ($arg{border} || 0.8) * 0.75; } my $self = $class->SUPER::new ( # label => "", - fg => [0.6, 0.3, 0.1], + fg => undef, border => 0.8, style => 'single', %arg, @@ -1313,7 +1332,7 @@ $child->draw; - glColor @{$self->{fg}}; + glColor @{$self->{fg} || $DC::THEME{fancyframe}}; glBegin GL_LINE_STRIP; glVertex $border * 1.5 , $border * 0.5 + 0.5; glVertex $border * 0.5 + 0.5, $border * 0.5 + 0.5; @@ -1338,15 +1357,15 @@ use DC::OpenGL; my $bg = - new_from_file DC::Texture DC::find_rcfile "d1_bg.png", + new_from_resource DC::Texture "d1_bg.png", mipmap => 1, wrap => 1; my @border = - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + 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); my @icon = - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw(x1_move.png x1_resize.png); sub new { @@ -1355,7 +1374,7 @@ my $self = $class->SUPER::new ( bg => [1, 1, 1, 1], border_bg => [1, 1, 1, 1], - border => 0.6, + border => 0.8, can_events => 1, min_w => 64, min_h => 32, @@ -1363,7 +1382,7 @@ ); $self->{title_widget} = new DC::UI::Label - align => 0, + align => 0.5, valign => 1, text => $self->{title}, fontsize => $self->{border}, @@ -1534,25 +1553,27 @@ 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); - - # 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 ($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); + + # 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} }; @@ -1891,9 +1912,9 @@ ellipsise => 3, # end layout => (new DC::Layout), fontsize => 1, - align => -1, - valign => -1, - padding_x => 2, + align => 0.5, + valign => 0.5, + padding_x => 4, padding_y => 2, can_events => 0, %arg @@ -1969,7 +1990,7 @@ my ($max_w, $max_h) = $self->get_max_wh; $self->{layout}->set_font ($self->{font}) if $self->{font}; - $self->{layout}->set_width ($self->{max_w} || $max_w || -1); + $self->{layout}->set_width ($max_w); $self->{layout}->set_ellipsise ($self->{ellipsise}); $self->{layout}->set_single_paragraph_mode ($self->{ellipsise}); $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); @@ -1978,7 +1999,7 @@ if (exists $self->{template}) { $self->{template}->set_font ($self->{font}) if $self->{font}; - $self->{template}->set_width ($self->{max_w} || -1); + $self->{template}->set_width ($max_w); $self->{template}->set_height ($self->{fontsize} * $::FONTSIZE); my ($w2, $h2) = $self->{template}->size; @@ -2044,13 +2065,8 @@ }; unless (exists $self->{ox}) { - $self->{ox} = int ($self->{align} < 0 ? $self->{padding_x} - : $self->{align} > 0 ? $self->{w} - $size->[0] - $self->{padding_x} - : ($self->{w} - $size->[0]) * 0.5); - - $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->{ox} = $self->{padding_x} + int $self->{align} * ($self->{w} - $size->[0] - $self->{padding_x} * 2); + $self->{oy} = $self->{padding_y} + int $self->{valign} * ($self->{h} - $size->[1] - $self->{padding_y} * 2); $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); }; @@ -2089,13 +2105,14 @@ $class->SUPER::new ( fg => [1, 1, 1], bg => [0, 0, 0, 0.2], - outline => [0.6, 0.3, 0.1], + outline => undef, active_bg => [0, 0, 1, .2], active_fg => [1, 1, 1], active_outline => [1, 1, 0], can_hover => 1, can_focus => 1, - valign => 0, + align => 0, + valign => 0.5, can_events => 1, ellipsise => 0, padding_x => 4, @@ -2156,9 +2173,9 @@ $self->{cursor} = List::Util::max 0, List::Util::min $self->{cursor}, length $text; - if ($uni == 8) { + if ($sym == DC::SDLK_BACKSPACE) { substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; - } elsif ($uni == 127) { + } elsif ($sym == DC::SDLK_DELETE) { substr $text, $self->{cursor}, 1, ""; } elsif ($sym == DC::SDLK_LEFT) { --$self->{cursor} if $self->{cursor}; @@ -2271,7 +2288,7 @@ glLineWidth 1; } else { - glColor @{$self->{outline}}; + glColor @{$self->{outline} || $DC::THEME{entry_outline}}; glBegin GL_LINE_STRIP; glVertex .5, $self->{h} * .5; glVertex .5, $self->{h} - 2.5; @@ -2289,6 +2306,16 @@ use DC::OpenGL; +sub new { + my $class = shift; + + $class->SUPER::new ( + history_pointer => -1, + @_ + ) +} + + sub invoke_key_down { my ($self, $ev) = @_; @@ -2322,7 +2349,10 @@ if ($self->{history_pointer} >= 0) { $self->set_text ($self->{history}->[$self->{history_pointer}]); } else { - $self->set_text ($self->{history_saveback}); + if (defined $self->{history_saveback}) { + $self->set_text ($self->{history_saveback}); + $self->{history_saveback} = undef; + } } } else { @@ -2390,7 +2420,7 @@ use DC::OpenGL; my @tex = - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw(b1_button_inactive.png b1_button_active.png); sub new { @@ -2398,8 +2428,8 @@ $class->SUPER::new ( can_hover => 1, - align => 0, - valign => 0, + align => 0.5, + valign => 0.5, can_events => 1, @_ ) @@ -2439,7 +2469,7 @@ use DC::OpenGL; my @tex = - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw(b1_button_inactive.png b1_button_active.png); sub new { @@ -2451,8 +2481,8 @@ fg => [1.0, 1.0, 1.0], active_fg => [0.8, 0.8, 0.8], can_hover => 1, - align => 0, - valign => 0, + align => 0.5, + valign => 0.5, can_events => 1, @_ ) @@ -2492,7 +2522,7 @@ our @ISA = DC::UI::DrawBG::; my @tex = - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw(c1_checkbox_bg.png c1_checkbox_active.png); use DC::OpenGL; @@ -2501,6 +2531,7 @@ my $class = shift; $class->SUPER::new ( + fontsize => 1, padding_x => 2, padding_y => 2, fg => [1, 1, 1], @@ -2516,7 +2547,7 @@ sub size_request { my ($self) = @_; - (6) x 2 + ($self->{fontsize} * $::FONTSIZE) x 2 } sub toggle { @@ -2564,7 +2595,7 @@ package DC::UI::Image; -our @ISA = DC::UI::Base::; +our @ISA = DC::UI::DrawBG::; use DC::OpenGL; @@ -2583,7 +2614,7 @@ or Carp::croak "'path' or 'tex' attributes required"; $self->{tex} ||= $texture_cache{$self->{path}} ||= - new_from_file DC::Texture DC::find_rcfile $self->{path}, mipmap => 1; + new_from_resource DC::Texture $self->{path}, mipmap => 1; DC::weaken $texture_cache{$self->{path}}; @@ -2607,6 +2638,13 @@ $self->new (path => $path) } +sub set_texture { + my ($self, $tex) = @_; + + $self->{tex} = $tex; + $self->update; +} + sub size_request { my ($self) = @_; @@ -2616,6 +2654,8 @@ sub _draw { my ($self) = @_; + $self->SUPER::_draw; + my $tex = $self->{tex}; my ($w, $h) = ($self->{w}, $self->{h}); @@ -2643,8 +2683,6 @@ use DC::OpenGL; -my %textures; - sub new { my $class = shift; @@ -2654,8 +2692,8 @@ fg => [1, 1, 1], active_fg => [0, 0, 1], can_hover => 1, - align => 0, - valign => 0, + align => 0.5, + valign => 0.5, can_events => 1, @_ ); @@ -2689,19 +2727,19 @@ my %tex = ( food => [ - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw/g1_food_gauge_empty.png g1_food_gauge_full.png/ ], grace => [ - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw/g1_grace_gauge_empty.png g1_grace_gauge_full.png g1_grace_gauge_overflow.png/ ], hp => [ - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw/g1_hp_gauge_empty.png g1_hp_gauge_full.png/ ], mana => [ - map { new_from_file DC::Texture DC::find_rcfile $_, mipmap => 1 } + map { new_from_resource DC::Texture $_, mipmap => 1 } qw/g1_mana_gauge_empty.png g1_mana_gauge_full.png g1_mana_gauge_overflow.png/ ], ); @@ -2824,13 +2862,15 @@ my ($class, %arg) = @_; my $self = $class->SUPER::new ( + padding_x => 2, + padding_y => 2, 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, + valign => 0.5, + align => 0.5, can_events => 1, ellipsise => 1, label => "%d%%", @@ -2873,17 +2913,24 @@ glEnable GL_BLEND; glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; + my $px = $self->{padding_x}; + my $py = $self->{padding_y}; + if ($self->{value} >= 0) { - my $s = int 2 + ($self->{w} - 4) * $self->{value}; + my $s = int $px + ($self->{w} - $px * 2) * $self->{value}; glColor_premultiply @{$self->{bar}}; - glRect 2, 2, $s, $self->{h} - 2; + glRect $px, $py, $s, $self->{h} - $py; glColor_premultiply @{$self->{bg}}; - glRect $s, 2, $self->{w} - 2, $self->{h} - 2; + glRect $s , $py, $self->{w} - $px, $self->{h} - $py; } glColor_premultiply @{$self->{outline}}; - glRect_lineloop 1.5, 1.5, $self->{w} - 1.5, $self->{h} - 1.5; + + $px -= .5; + $py -= .5; + + glRect_lineloop $px, $py, $self->{w} - $px, $self->{h} - $py; glDisable GL_BLEND; @@ -2902,17 +2949,21 @@ sub new { my ($class, %arg) = @_; + my $tt = exists $arg{tooltip} ? "$arg{tooltip}\n\n" : ""; + my $self = $class->SUPER::new ( + %arg, tooltip => sub { my ($self) = @_; - sprintf "level %d\n%s points\n%s next level\n%s to go", + sprintf "%slevel %d\n%s points\n%s next level\n%s to go, %d%% done", + $tt, $self->{lvl}, ::formsep ($self->{exp}), ::formsep ($self->{nxt}), ::formsep ($self->{nxt} - $self->{exp}), + $self->_percent * 100, }, - %arg ); $::CONN->{on_exp_update}{$self+0} = sub { $self->set_value ($self->{value}) } @@ -2930,24 +2981,27 @@ $self->SUPER::DESTROY; } -sub set_value { - my ($self, $lvl, $exp) = @_; +sub _percent { + my ($self) = @_; - $self->{lvl} = $lvl; - $self->{exp} = $exp; + my $table = $::CONN && $::CONN->{exp_table} + or return -1; - my $v = -1; + my $l0 = $table->[$self->{lvl} - 1]; + my $l1 = $table->[$self->{lvl}]; - if ($::CONN && (my $table = $::CONN->{exp_table})) { - my $l0 = $table->[$lvl - 1]; - my $l1 = $table->[$lvl]; + $self->{nxt} = $l1; - $self->{nxt} = $l1; + ($self->{exp} - $l0) / ($l1 - $l0) +} - $v = ($exp - $l0) / ($l1 - $l0); - } +sub set_value { + my ($self, $lvl, $exp) = @_; - $self->SUPER::set_value ($v); + $self->{lvl} = $lvl; + $self->{exp} = $exp; + + $self->SUPER::set_value ($self->_percent); } ############################################################################# @@ -2966,9 +3020,9 @@ %arg, ); - $self->add ($self->{value} = new DC::UI::Label valign => +1, align => 0, template => "999"); + $self->add ($self->{value} = new DC::UI::Label valign => 1, align => 0.5, template => "999"); $self->add ($self->{gauge} = new DC::UI::VGauge type => $self->{type}, expand => 1, can_hover => 1); - $self->add ($self->{max} = new DC::UI::Label valign => -1, align => 0, template => "999"); + $self->add ($self->{max} = new DC::UI::Label valign => 0, align => 0.5, template => "999"); $self } @@ -3008,7 +3062,7 @@ our @ISA = DC::UI::DrawBG::; my @tex = - map { new_from_file DC::Texture DC::find_rcfile $_ } + map { new_from_resource DC::Texture $_ } qw(s1_slider.png s1_slider_bg.png); sub new { @@ -3055,12 +3109,10 @@ my ($old_value, $lo, $hi, $page, $unit) = @{$self->{range}}; - $hi = $lo + 1 if $hi <= $lo; - - $page = $hi - $lo if $page > $hi - $lo; + $hi = $lo if $hi < $lo; - $value = $lo if $value < $lo; $value = $hi - $page if $value > $hi - $page; + $value = $lo if $value < $lo; $value = $lo + $unit * int +($value - $lo + $unit * 0.5) / $unit if $unit; @@ -3134,10 +3186,10 @@ unless ($self->{knob_w}) { $self->set_value ($self->{range}[0]); - my ($value, $lo, $hi, $page) = @{$self->{range}}; - my $range = ($hi - $page - $lo) || 1e-100; + my ($value, $lo, $hi, $page, $unit) = @{$self->{range}}; + my $range = ($hi - $page - $lo) || 1e-10; - my $knob_w = List::Util::min 1, $page / ($hi - $lo) || 0.1; + my $knob_w = List::Util::min 1, $page / (($hi - $lo) || 1e-10) || 24 / $self->{w}; $self->{offset} = List::Util::max $self->{inner_pad}, $knob_w * 0.5; $self->{scale} = 1 - 2 * $self->{offset} || 1e-100; @@ -3306,7 +3358,7 @@ $layout->set_shapes ( map - +(0, $_->baseline_shift +$_->{padding_y} - $_->{h}, $_->{w}, $_->{h}), + +(0, $_->baseline_shift + $_->{padding_y} - $_->{h}, $_->{w}, $_->{h}), @{$para->{widget}} ); @@ -3607,10 +3659,12 @@ $tip =~ s/\n+$//; $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, - style => 1, # FLAG_INVERSE + style => $DC::THEME{tooltip_style}, # FLAG_INVERSE ellipsise => 0, font => ($widget->{tooltip_font} || $::FONT_PROP), ); @@ -3657,10 +3711,10 @@ my ($w, $h) = @$self{qw(w h)}; - glColor 1, 0.8, 0.4; + glColor @{ $DC::THEME{tooltip_bg} }; glRect 0, 0, $w, $h; - glColor 0, 0, 0; + glColor @{ $DC::THEME{tooltip_border} }; glRect_lineloop .5, .5, $w + .5, $h + .5; glTranslate 2, 2; @@ -3687,27 +3741,7 @@ @_, ); - if ($self->{anim} && $self->{animspeed}) { - DC::weaken (my $widget = $self); - - $self->{animspeed} = List::Util::max 0.05, $self->{animspeed}; - $self->{timer} = EV::periodic_ns 0, $self->{animspeed}, undef, sub { - return unless $::CONN; - - my $w = $widget - or return; - - ++$w->{frame}; - $w->update_face; - - # somehow, $widget can go away - $w->update; - $w->update_timer; - }; - - $self->update_face; - $self->update_timer; - } + $self->update_anim; $self } @@ -3743,6 +3777,34 @@ } } +sub update_anim { + my ($self) = @_; + + if ($self->{anim} && $self->{animspeed}) { + DC::weaken (my $widget = $self); + + $self->{animspeed} = List::Util::max 0.05, $self->{animspeed}; + $self->{timer} = EV::periodic_ns 0, $self->{animspeed}, undef, sub { + return unless $::CONN; + + my $w = $widget + or return; + + ++$w->{frame}; + $w->update_face; + + # somehow, $widget can go away + $w->update; + $w->update_timer; + }; + + $self->update_face; + $self->update_timer; + } else { + delete $self->{timer}; + } +} + sub size_request { my ($self) = @_; @@ -3771,6 +3833,27 @@ $self->SUPER::update; } +sub set_face { + my ($self, $face) = @_; + + $self->{face} = $face; + $self->reconfigure; +} + +sub set_anim { + my ($self, $anim) = @_; + + $self->{anim} = $anim; + $self->update_anim; +} + +sub set_animspeed { + my ($self, $animspeed) = @_; + + $self->{animspeed} = $animspeed; + $self->update_anim; +} + sub invoke_visibility_change { my ($self) = @_; @@ -3842,8 +3925,8 @@ can_events => 1, tooltip => $tooltip, children => [ - (new DC::UI::Label markup => $left, expand => 1), - (new DC::UI::Label markup => $right, align => +1), + (new DC::UI::Label markup => $left , align => 0, expand => 1), + (new DC::UI::Label markup => $right, align => 1), ], ; @@ -3851,6 +3934,7 @@ $widget = new DC::UI::Label can_hover => 1, can_events => 1, + align => 0, markup => $widget, tooltip => $tooltip; } @@ -3875,7 +3959,15 @@ $self->{button} = $ev->{button}; $self->show; - $self->move_abs ($ev->{x} - $self->{w} * 0.5, $ev->{y} - $self->{h} * 0.5); + + my $x = $ev->{x}; + my $y = $ev->{y}; + + $self->{root}->on_post_alloc ($self => sub { + $self->move_abs ($x - $self->{w} * 0.25, $y - $self->{border} * $::FONTSIZE * .5); + }); + + 1 # so it can be used inside event handlers } sub invoke_mouse_motion { @@ -3917,8 +4009,7 @@ @_, ); - $self->{current} = $self->{children}[0] - if @{ $self->{children} }; + $self->set_current_page (0); $self } @@ -3928,8 +4019,8 @@ $self->SUPER::add (@widgets); - $self->{current} = $self->{children}[0] - if @{ $self->{children} }; + $self->set_current_page (0) + if @widgets == @{ $self->{children} }; } sub get_current_page { @@ -3945,28 +4036,35 @@ ? $page_or_widget : $self->{children}[$page_or_widget]; - $self->{current} = $widget; - $self->{current}->configure (0, 0, $self->{w}, $self->{h}); + $self->{current}->set_invisible if $self->{current} && $self->{visible}; - $self->emit (page_changed => $self->{current}); + if (($self->{current} = $widget)) { + $self->{current}->set_visible if $self->{current} && $self->{visible}; + $self->{current}->configure (0, 0, $self->{w}, $self->{h}); + + $self->emit (page_changed => $self->{current}); + } $self->realloc; } sub visible_children { - $_[0]{current} + $_[0]{current} || () } sub size_request { my ($self) = @_; - $self->{current}->size_request + $self->{current} + ? $self->{current}->size_request + : (0, 0) } sub invoke_size_allocate { my ($self, $w, $h) = @_; - $self->{current}->configure (0, 0, $w, $h); + $self->{current}->configure (0, 0, $w, $h) + if $self->{current}; 1 } @@ -3974,7 +4072,8 @@ sub _draw { my ($self) = @_; - $self->{current}->draw; + $self->{current}->draw + if $self->{current}; } ############################################################################# @@ -4053,6 +4152,18 @@ $self->{multiplexer}->children } +sub page_index { + my ($self, $widget) = @_; + + my $i = 0; + for ($self->pages) { + if ($_ eq $widget) { return $i }; + $i++; + } + + undef +} + sub add_tab { my ($self, $title, $widget, $tooltip) = @_; @@ -4182,7 +4293,7 @@ sub reorder { my ($self) = @_; - my $NOW = Time::HiRes::time; + my $NOW = EV::time; # freeze display when hovering over any label return if $DC::UI::TOOLTIP->{owner} @@ -4224,6 +4335,7 @@ tooltip_width => 0.67, fontsize => $item->{fontsize} || $self->{fontsize}, max_w => $::WIDTH * 0.44, + align => 0, fg => [@{ $item->{fg} }], can_events => 1, can_hover => 1 @@ -4242,6 +4354,10 @@ push @widgets, $label; } + my $hash = join ",", @widgets; + return if $hash eq $self->{last_widget_hash}; + $self->{last_widget_hash} = $hash; + $self->clear; $self->SUPER::add (reverse @widgets); } @@ -4457,8 +4573,11 @@ my ($w, $h) = $widget->size_request; - $w = max $widget->{min_w}, $w + $widget->{padding_x} * 2; - $h = max $widget->{min_h}, $h + $widget->{padding_y} * 2; + $w += $widget->{padding_x} * 2; + $h += $widget->{padding_y} * 2; + + $w = max $widget->{min_w}, $w; + $h = max $widget->{min_h}, $h; $w = min $widget->{max_w}, $w if exists $widget->{max_w}; $h = min $widget->{max_h}, $h if exists $widget->{max_h}; @@ -4548,8 +4667,7 @@ package DC::UI; -$ROOT = new DC::UI::Root; +$ROOT = new DC::UI::Root; $TOOLTIP = new DC::UI::Tooltip z => 900; 1 -