--- deliantra/Deliantra-Client/DC/UI.pm 2007/07/24 18:39:39 1.418 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/08/22 21:27:13 1.433 @@ -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; } } @@ -1029,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 { @@ -1040,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 { @@ -1062,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}, @@ -1221,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; } @@ -1600,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); @@ -1615,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; } @@ -1632,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]; @@ -1643,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]; @@ -1696,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], @@ -1925,6 +1910,12 @@ $self->SUPER::realloc; } +sub clear { + my ($self) = @_; + + $self->set_text (""); +} + sub set_text { my ($self, $text) = @_; @@ -2040,6 +2031,8 @@ $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}); }; # unless ($self->{list}) { @@ -2051,7 +2044,7 @@ # # CFPlus::OpenGL::glCallList $self->{list}; - $self->{layout}->render ($self->{ox}, $self->{oy}, $self->{style}); + $self->{layout}->draw; } #sub destroy { @@ -2076,6 +2069,7 @@ $class->SUPER::new ( fg => [1, 1, 1], bg => [0, 0, 0, 0.2], + outline => [0.6, 0.3, 0.1], active_bg => [0, 0, 1, .2], active_fg => [1, 1, 1], active_outline => [1, 1, 0], @@ -2228,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; @@ -2256,14 +2245,18 @@ glLineWidth 3; glColor @{$self->{active_outline}}; - glTranslate -.375, -.375; - glBegin GL_LINE_LOOP; - glVertex 0, 0; - glVertex $self->{w}, 0; - glVertex $self->{w}, $self->{h}; - glVertex 0, $self->{h}; - glEnd; + 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; } } @@ -2637,6 +2630,12 @@ ); } +sub invoke_button_down { + my ($self, $ev, $x, $y) = @_; + + 1 +} + sub invoke_button_up { my ($self, $ev, $x, $y) = @_; @@ -2784,6 +2783,130 @@ ############################################################################# +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, + label => "%d%%", + %arg, + ); + + $self->set_value ($arg{value} || -1); + + $self +} + +sub set_label { + my ($self, $label) = @_; + + return if $self->{label} eq $label; + $self->{label} = $label; + + $self->CFPlus::UI::Progress::set_value (0 + delete $self->{value}); +} + +sub set_value { + my ($self, $value) = @_; + + if ($self->{value} ne $value) { + $self->{value} = $value; + + if ($value < 0) { + $self->set_text ("-"); + } else { + $self->set_text (sprintf $self->{label}, $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::; @@ -3290,6 +3413,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; @@ -3490,20 +3614,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; @@ -3537,13 +3651,17 @@ $self->{timer} = Event->timer ( parked => 1, cb => sub { - return unless $::CONN && $widget; + return unless $::CONN; + + my $w = $widget + or return; - ++$widget->{frame}; - $widget->update_face; - $widget->update; + ++$w->{frame}; + $w->update_face; - $widget->update_timer; + # somehow, $widget can go away + $w->update; + $w->update_timer; }, ); @@ -3574,13 +3692,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 }); + } + } + } } } } @@ -3589,15 +3712,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 }); } } @@ -3822,14 +3946,17 @@ 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 @_, ); @@ -3913,6 +4040,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; @@ -4190,7 +4333,7 @@ sub update { my ($self) = @_; - $::WANT_REFRESH++; + $::WANT_REFRESH->start; } sub add {