--- deliantra/Deliantra-Client/DC/UI.pm 2007/04/23 19:17:41 1.366 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/07/15 22:39:30 1.373 @@ -270,6 +270,10 @@ %$self = (); } +sub TO_JSON { + { __widget_ref__ => $_[0]{s_id} } +} + sub show { my ($self) = @_; @@ -318,8 +322,8 @@ return if $self->{visible} == $visible; - $visible ? $self->hide - : $self->show; + $visible ? $self->show + : $self->hide; } sub toggle_visibility { @@ -1031,7 +1035,7 @@ package CFPlus::UI::ScrolledWindow; -our @ISA = CFPlus::UI::HBox::; +our @ISA = CFPlus::UI::Table::; sub new { my ($class, %arg) = @_; @@ -1040,22 +1044,45 @@ my $self; - my $slider = new CFPlus::UI::Slider + my $hslider = new CFPlus::UI::Slider + 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 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 + expand => 1, + scroll_x => $self->{scroll_x}, + scroll_y => $self->{scroll_y}, + ; + + $self->SUPER::add (0, 0, $self->{vp}); + $self->SUPER::add (1, 0, $self->{vslider}) if $self->{scroll_y}; + $self->SUPER::add (0, 1, $self->{hslider}) if $self->{scroll_x}; + $self->add ($child) if $child; $self @@ -1074,7 +1101,7 @@ return 0 unless $ev->{dy}; # only vertical movements - $self->{slider}->emit (mouse_wheel => $ev); + $self->{vslider}->emit (mouse_wheel => $ev); 1 } @@ -1082,14 +1109,21 @@ sub update_slider { my ($self) = @_; - $self->{slider}->set_range ([$self->{slider}{range}[0], 0, $self->{vp}->child->{h}, $self->{vp}{h}, 1]); + 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]); + #$self->{hslider}->set_visibility ($w1 != $w2); + + my ($h1, $h2) = ($child->{h}, $self->{vp}{h}); + $self->{vslider}->set_range ([$self->{vslider}{range}[0], 0, $h1, $h2, 1]); + #$self->{vslider}->set_visibility ($h1 != $h2); } sub update { my ($self) = @_; $self->SUPER::update; - $self->update_slider; } @@ -1097,7 +1131,6 @@ my ($self, $w, $h) = @_; $self->update_slider; - $self->SUPER::invoke_size_allocate ($w, $h) } @@ -1479,6 +1512,7 @@ $class->SUPER::new ( col_expand => [], + row_expand => [], @_, ) } @@ -1563,16 +1597,21 @@ my $req_w = (sum @$ws) || 1; my $req_h = (sum @$hs) || 1; - # TODO: nicer code && do row_expand + # TODO: nicer code 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; + + my @row_expand = @{$self->{row_expand}}; + @row_expand = (1) x @$ws unless @row_expand; + my $row_expand = (sum @row_expand) || 1; + + $hs->[$_] += $row_expand[$_] / $row_expand * ($h - $req_h) for 0 .. $#$hs; + CFPlus::UI::harmonize $hs; my $y; @@ -1972,6 +2011,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) { @@ -3289,6 +3330,8 @@ my $class = shift; my $self = $class->SUPER::new ( + size_w => 32, + size_h => 8, aspect => 1, can_events => 0, @_, @@ -3302,17 +3345,49 @@ hard => 1, interval => $self->{animspeed}, cb => sub { + return unless $::CONN; + ++$widget->{frame}; - $widget->update; + $self->update_face; + $self->update; }, ); + + $self->update_face; } $self } +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 { @@ -3330,16 +3405,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;