--- deliantra/Deliantra-Client/DC/UI.pm 2006/08/13 16:29:36 1.344 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/08/13 21:46:10 1.345 @@ -2752,6 +2752,23 @@ $self->{children}[1]->set_value ($offset); } +sub current_paragraph { + my ($self) = @_; + + $self->force_uptodate; + $self->{top_paragraph} - 1 +} + +sub scroll_to { + my ($self, $para) = @_; + + $self->force_uptodate; + + $para = List::Util::max 0, List::Util::min $#{$self->{par}}, $para; + + $self->{children}[1]->set_value ($self->{par}[$para]{y}); +} + sub clear { my ($self) = @_; @@ -2792,44 +2809,61 @@ $self->update; } -sub update { +sub force_uptodate { my ($self) = @_; - $self->SUPER::update; + if (delete $self->{need_reflow}) { + my ($W, $H) = @{$self->{children}[0]}{qw(w h)}; - return unless $self->{h} > 0; + my $height = 0; + my $paridx; + my $top_paragraph; + my $top = int $self->{children}[1]{range}[0]; + + for my $para (@{$self->{par}}) { + if ($para->{w} != $W && ($para->{wrapped} || $para->{w} > $W)) { + my $layout = $self->get_layout ($para); + my ($w, $h) = $layout->size; + + $para->{w} = $w + $para->{indent}; + $para->{h} = $h; + $para->{wrapped} = $layout->has_wrapped; + } - delete $self->{texture}; + $para->{y} = $height; - $ROOT->on_post_alloc ($self => sub { - my ($W, $H) = @{$self->{children}[0]}{qw(w h)}; + $paridx++; + $top_paragraph ||= $paridx if $height >= $top; - if (delete $self->{need_reflow}) { - my $height = 0; + $height += $para->{h}; + } - for my $para (@{$self->{par}}) { - if ($para->{w} != $W && ($para->{wrapped} || $para->{w} > $W)) { - my $layout = $self->get_layout ($para); - my ($w, $h) = $layout->size; + $self->{top_paragraph} = $top_paragraph; + $self->{height} = $height; - $para->{w} = $w + $para->{indent}; - $para->{h} = $h; - $para->{wrapped} = $layout->has_wrapped; - } + $self->{children}[1]->set_range ([$self->{children}[1]{range}[0], 0, $height, $H, 1]); - $height += $para->{h}; - } + delete $self->{texture}; + } - $self->{height} = $height; + if (delete $self->{scroll_to_bottom}) { + $self->{children}[1]->set_value (1e10); + } +} - $self->{children}[1]->set_range ([$self->{children}[1]{range}[0], 0, $height, $H, 1]); +sub update { + my ($self) = @_; - delete $self->{texture}; - } + $self->SUPER::update; - if (delete $self->{scroll_to_bottom}) { - $self->{children}[1]->set_value (1e10); - } + return unless $self->{h} > 0; + + delete $self->{texture}; + + $ROOT->on_post_alloc ($self => sub { + $self->force_uptodate; + + my ($W, $H) = @{$self->{children}[0]}{qw(w h)}; $self->{texture} ||= new_from_opengl CFPlus::Texture $W, $H, sub { glClearColor 0, 0, 0, 0; @@ -2840,13 +2874,11 @@ my $y0 = $top; my $y1 = $top + $H; - my $y = 0; - for my $para (@{$self->{par}}) { my $h = $para->{h}; + my $y = $para->{y}; if ($y0 < $y + $h && $y < $y1) { - my $layout = $self->get_layout ($para); $layout->render ($para->{indent}, $y - $y0); @@ -2864,8 +2896,6 @@ } } } - - $y += $h; } }; });