--- deliantra/Deliantra-Client/DC/UI.pm 2007/07/15 22:39:30 1.373 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/07/16 12:36:48 1.374 @@ -1080,8 +1080,6 @@ ; $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; @@ -1099,7 +1097,7 @@ sub invoke_mouse_wheel { my ($self, $ev) = @_; - return 0 unless $ev->{dy}; # only vertical movements + return 0 unless $ev->{dy}; # only vertical movements for now $self->{vslider}->emit (mouse_wheel => $ev); @@ -1113,11 +1111,21 @@ 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 $visible = $w1 > $w2; + if ($visible != $self->{hslider}{visible}) { + $visible ? $self->SUPER::add (0, 1, $self->{hslider}) + : $self->{hslider}->hide; + } 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); + + my $visible = $h1 > $h2; + if ($visible != $self->{vslider}{visible}) { + $visible ? $self->SUPER::add (1, 0, $self->{vslider}) + : $self->{vslider}->hide; + } } sub update { @@ -1511,6 +1519,7 @@ my $class = shift; $class->SUPER::new ( + children => [], col_expand => [], row_expand => [], @_, @@ -1521,6 +1530,7 @@ grep $_, map @$_, grep $_, @{ $_[0]{children} } } +# TODO: store row/col info in child widget and use standard add/del sub add { my ($self) = shift; @@ -1530,7 +1540,7 @@ $self->{children}[$y][$x] = $child; } - $self->{force_realloc} = 1; + $self->{force_realloc} = 1; $self->{force_size_alloc} = 1; $self->realloc; } @@ -1538,7 +1548,11 @@ sub remove { my ($self, $child) = @_; - # TODO: not yet implemented + for (@{ $self->{children} }) { + for (@{ $_ || [] }) { + $_ = undef if $_ == $child; + } + } } # TODO: move to container class maybe? send children a signal on removal? @@ -1664,6 +1678,88 @@ } ############################################################################# + +package CFPlus::UI::Fixed; + +use List::Util qw(min max); + +our @ISA = CFPlus::UI::Container::; + +sub add { + 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) = @_; + + $mode eq "abs" ? $val + : $mode eq "rel" ? $val * $max + : 0 +} + +sub size_request { + my ($self) = @_; + + my ($x1, $y1, $x2, $y2) = (0, 0, 0, 0); + + # determine overall size by querying abs widgets + for my $child ($self->visible_children) { + my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + + 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; + } + } + + my $W = $x2 - $x1; + my $H = $y2 - $y1; + + # 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}; + + $x1 = min $x1, $x; $x2 = max $x2, $x + $w; + $y1 = min $y1, $y; $y2 = max $y2, $y + $h; + } + } + + my $W = $x2 - $x1; + my $H = $y2 - $y1; + + ($W, $H) +} + +sub invoke_size_allocate { + my ($self, $W, $H) = @_; + + for my $child ($self->visible_children) { + my ($pos, $x, $y, $size, $w, $h) = @{ $child->{_fixed} }; + + $x = _scale $pos, $x, $W; + $y = _scale $pos, $x, $H; + $w = _scale $size, $w, $child->{req_w}; + $h = _scale $size, $h, $child->{req_h}; + + $child->configure ($x, $y, $w, $h); + } + + 1 +} + +############################################################################# package CFPlus::UI::Box;