--- deliantra/Deliantra-Client/DC/UI.pm 2007/07/21 13:02:05 1.389 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/07/21 14:01:35 1.397 @@ -743,7 +743,7 @@ ); $self->add (@$children) - if $children; + if $children && @$children; $self } @@ -762,6 +762,7 @@ $_->set_parent ($self) for @widgets; + # TODO: only do this in widgets that need it, e.g. root, fixed use sort 'stable'; $self->{children} = [ @@ -790,7 +791,7 @@ sub clear { my ($self) = @_; - my $children = delete $self->{children}; + my $children = $self->{children}; $self->{children} = []; for (@$children) { @@ -1048,6 +1049,8 @@ my $self; my $hslider = new CFPlus::UI::Slider + col => 0, + row => 1, vertical => 0, range => [0, 0, 1, 0.01], # HACK fix on_changed => sub { @@ -1057,6 +1060,8 @@ ; my $vslider = new CFPlus::UI::Slider + col => 1, + row => 0, vertical => 1, range => [0, 0, 1, 0.01], # HACK fix on_changed => sub { @@ -1077,6 +1082,8 @@ ); $self->{vp} = new CFPlus::UI::ViewPort + col => 0, + row => 0, expand => 1, scroll_x => $self->{scroll_x}, scroll_y => $self->{scroll_y}, @@ -1090,15 +1097,13 @@ }, ; - $self->SUPER::add_at (0, 0, $self->{vp}); + $self->SUPER::add ($self->{vp}); $self->add ($child) if $child; $self } -#TODO# update range on size_allocate depending on child - sub add { my ($self, $widget) = @_; @@ -1114,36 +1119,47 @@ $self->{hslider}->set_range ([$self->{hslider}{range}[0], 0, $w1, $w2, 1]); my $visible = $w1 > $w2; - if ($visible != $self->{hslider}{visible}) { - $visible ? $self->SUPER::add_at (0, 1, $self->{hslider}) - : $self->{hslider}->hide; + if ($visible != $self->{hslider_visible}) { + $self->{hslider_visible} = $visible; + $visible ? $self->SUPER::add ($self->{hslider}) + : $self->SUPER::remove ($self->{hslider}); } my ($h1, $h2) = ($child->{h}, $self->{vp}{h}); $self->{vslider}->set_range ([$self->{vslider}{range}[0], 0, $h1, $h2, 1]); my $visible = $h1 > $h2; - if ($visible != $self->{vslider}{visible}) { - $visible ? $self->SUPER::add_at (1, 0, $self->{vslider}) - : $self->{vslider}->hide; + if ($visible != $self->{vslider_visible}) { + $self->{vslider_visible} = $visible; + $visible ? $self->SUPER::add ($self->{vslider}) + : $self->SUPER::remove ($self->{vslider}); } } -sub update { - my ($self) = @_; - $self->update_slider; - $self->SUPER::update; +sub start_dragging { + my ($self, $ev) = @_; + + $self->grab_focus; + + my $ox = $self->{vp}{view_x}; + my $oy = $self->{vp}{view_y}; + + $self->{motion} = sub { + my ($ev, $x, $y) = @_; + + $ox -= $ev->{xrel}; + $oy -= $ev->{yrel}; + + $self->{vp}->set_offset ($ox, $oy); + }; } sub invoke_mouse_wheel { my ($self, $ev) = @_; - $self->{vslider}->emit (mouse_wheel => $ev) - if $ev->{dy}; - - $self->{hslider}->emit (mouse_wheel => $ev) - if $ev->{dx}; + $self->{vslider}->emit (mouse_wheel => $ev); + $self->{hslider}->emit (mouse_wheel => $ev); 1 } @@ -1151,23 +1167,9 @@ sub invoke_button_down { my ($self, $ev, $x, $y) = @_; - if ($ev->{button} == 2) { - $self->grab_focus; - - my $ox = $self->{vp}{view_x} + $ev->{x}; - my $oy = $self->{vp}{view_y} + $ev->{y}; - - $self->{motion} = sub { - my ($ev, $x, $y) = @_; + $self->start_dragging ($ev); - $self->{vp}->set_offset ($ox - $ev->{x}, $oy - $ev->{y}); - $self->update; - }; - - return 1; - } - - 0 + 1 } sub invoke_button_up { @@ -1583,7 +1585,7 @@ package CFPlus::UI::Table; -our @ISA = CFPlus::UI::Base::; +our @ISA = CFPlus::UI::Container::; use List::Util qw(max sum); @@ -1593,69 +1595,38 @@ my $class = shift; $class->SUPER::new ( - children => [], col_expand => [], row_expand => [], @_, ) } -sub children { - grep $_, map @$_, grep $_, @{ $_[0]{children} } -} - -# TODO: store row/col info in child widget and use standard add/del sub add { - my $self = shift; + my ($self, @widgets) = @_; + + for my $child (@widgets) { + $child->{rowspan} ||= 1; + $child->{colspan} ||= 1; + } - Carp::cluck "please use the add_at method instead of calling add, thank you.\n";#d# - $self->add_at (@_); + $self->SUPER::add (@widgets); } sub add_at { my $self = shift; + my @widgets; + while (@_) { my ($col, $row, $child) = splice @_, 0, 3, (); $child->{row} = $row; $child->{col} = $col; - $child->{rowspan} ||= 1; - $child->{colspan} ||= 1; - - $child->set_parent ($self); - $self->{children}[$row][$col] = $child; + push @widgets, $child; } - $self->{force_realloc} = 1; - $self->{force_size_alloc} = 1; - $self->realloc; -} - -sub remove { - my ($self, $child) = @_; - - for (@{ $self->{children} }) { - for (@{ $_ || [] }) { - $_ = undef if $_ == $child; - } - } -} - -# TODO: move to container class maybe? send children a signal on removal? -sub clear { - my ($self) = @_; - - my @children = $self->children; - delete $self->{children}; - - for (@children) { - delete $_->{parent}; - $_->hide; - } - - $self->realloc; + $self->add (@widgets); } sub get_wh { @@ -1665,18 +1636,25 @@ my @children = $self->children; - for my $widget (sort { $b->{rowspan} * $b->{colspan} <=> $a->{rowspan} * $a->{colspan} } @children) { - my ($r, $c, $w, $h, $rs, $cs) = @$widget{qw(row col req_w req_h rowspan colspan)}; + # first pass, columns + for my $widget (sort { $a->{colspan} <=> $b->{colspan} } @children) { + my ($c, $w, $cs) = @$widget{qw(col req_w colspan)}; my $sw = sum @w[$c .. $c + $cs - 1]; - my $sh = sum @h[$r .. $r + $rs - 1]; if ($w > $sw) { - $_ += ($w - $sw) / $cs for @w[$c .. $c + $cs - 1]; + $_ += ($w - $sw) / ($sw ? $sw / $_ : $cs) for @w[$c .. $c + $cs - 1]; } + } + + # second pass, rows + for my $widget (sort { $a->{rowspan} <=> $b->{rowspan} } @children) { + my ($r, $h, $rs) = @$widget{qw(row req_h rowspan)}; + + my $sh = sum @h[$r .. $r + $rs - 1]; if ($h > $sh) { - $_ += ($h - $sh) / $rs for @h[$r .. $r + $rs - 1]; + $_ += ($h - $sh) / ($sh ? $sh / $_ : $rs) for @h[$r .. $r + $rs - 1]; } } @@ -1719,10 +1697,8 @@ CFPlus::UI::harmonize $hs; - my (@x, @y); - - for (0 .. $#$ws) { $x[$_ + 1] = $x[$_] + $ws->[$_] } - for (0 .. $#$hs) { $y[$_ + 1] = $y[$_] + $hs->[$_] } + my @x; for (0 .. $#$ws) { $x[$_ + 1] = $x[$_] + $ws->[$_] } + 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)}; @@ -1736,30 +1712,6 @@ 1 } -sub find_widget { - my ($self, $x, $y) = @_; - - $x -= $self->{x}; - $y -= $self->{y}; - - my $res; - - for (grep $_, map @$_, grep $_, @{ $self->{children} }) { - $res = $_->find_widget ($x, $y) - and return $res; - } - - $self->SUPER::find_widget ($x + $self->{x}, $y + $self->{y}) -} - -sub _draw { - my ($self) = @_; - - for (grep $_, @{$self->{children}}) { - $_->draw for grep $_, @$_; - } -} - ############################################################################# package CFPlus::UI::Fixed;