--- deliantra/Deliantra-Client/DC/UI.pm 2006/05/25 16:35:42 1.235 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/05/27 20:46:54 1.243 @@ -7,15 +7,35 @@ use List::Util (); use CFClient; +use CFClient::Texture; our ($FOCUS, $HOVER, $GRAB); # various widgets +our $LAYOUT; our $ROOT; our $TOOLTIP; our $BUTTON_STATE; our %WIDGET; # all widgets, weak-referenced +sub get_layout { + for (grep { $_->{name} } values %WIDGET) { + $LAYOUT->{$_->{name}} = { + x => $_->{x} / $::WIDTH, + y => $_->{y} / $::HEIGHT, + w => $_->{w} / $::WIDTH, + h => $_->{h} / $::HEIGHT + }; + } + + return $LAYOUT; +} + +sub set_layout { + my ($layout) = @_; + $LAYOUT = $layout; +} + sub check_tooltip { if (!$GRAB) { for (my $widget = $HOVER; $widget; $widget = $widget->{parent}) { @@ -188,13 +208,20 @@ }, $class; for (keys %$self) { - if (/^connect_(.*)$/) { + if (/^on_(.*)$/) { $self->connect ($1 => delete $self->{$_}); } } Scalar::Util::weaken ($CFClient::UI::WIDGET{$self+0} = $self); + if (my $layout = $CFClient::UI::LAYOUT->{$self->{name}}) { + $self->{user_x} = $layout->{x} * $::WIDTH; + $self->{user_y} = $layout->{y} * $::HEIGHT; + $self->{user_w} = ($layout->{w} != 0 ? $layout->{w} : 1) * $::WIDTH; + $self->{user_h} = ($layout->{h} != 0 ? $layout->{h} : 1) * $::HEIGHT; + } + $self } @@ -230,6 +257,7 @@ # broken show/hide model + delete $self->{root}; delete $self->{visible}; undef $GRAB if $GRAB == $self; @@ -460,6 +488,9 @@ Scalar::Util::weaken ($self->{parent} = $parent); + $self->{root} = $parent->{root}; + $self->{visible} = $parent->{visible} + 1; + # TODO: req_w _does_change after ->reconfigure $self->check_size unless exists $self->{req_w}; @@ -620,7 +651,7 @@ $self->{children} = [ grep $_ != $child, @{ $self->{children} } ]; - $self->check_size; + $self->check_size (1); $self->update; } @@ -855,9 +886,9 @@ my $self; my $slider = new CFClient::UI::Slider - vertical => 1, - range => [0, 0, 1, 0.01], # HACK fix - connect_changed => sub { + vertical => 1, + range => [0, 0, 1, 0.01], # HACK fix + on_changed => sub { $self->{vp}->set_offset (0, $_[1]); }, ; @@ -875,6 +906,16 @@ $self } +sub update { + my ($self) = @_; + + $self->SUPER::update; + + # todo: overwrite size_allocate of child + my $child = $self->{vp}->child; + $self->{slider}->set_range ([$self->{slider}{range}[0], 0, $child->{h}, $self->{vp}{h}, 1]); +} + sub size_allocate { my ($self, $w, $h) = @_; @@ -1012,9 +1053,11 @@ my $dx = $ev->{x} - $ox; my $dy = $ev->{y} - $oy; + $self->{user_x} = $wx + $dx * $mx; + $self->{user_y} = $wy + $dy * $my; $self->{user_w} = $bw + $dx * ($mx ? -1 : 1); $self->{user_h} = $bh + $dy * ($my ? -1 : 1); - $self->move ($wx + $dx * $mx, $wy + $dy * $my); + $self->move ($self->{user_x}, $self->{user_y}); $self->check_size; }; @@ -1027,7 +1070,9 @@ ($x, $y) = ($ev->{x}, $ev->{y}); - $self->move ($bx + $x - $ox, $by + $y - $oy); + $self->{user_x} = $bx + $x - $ox; + $self->{user_y} = $by + $y - $oy; + $self->move ($self->{user_x}, $self->{user_y}); $self->update; }; } @@ -1103,20 +1148,20 @@ ) } +sub children { + grep $_, map @$_, grep $_, @{ $_[0]{children} } +} + sub add { my ($self, $x, $y, $child) = @_; $child->set_parent ($self); $self->{children}[$y][$x] = $child; - $child->check_size; -} - -sub children { - grep $_, map @$_, grep $_, @{ $_[0]{children} } + $self->check_size (1); } -# TODO: move to container class maybe? send childs a signal on removal? +# TODO: move to container class maybe? send children a signal on removal? sub clear { my ($self) = @_; @@ -1128,6 +1173,7 @@ $_->hide; } + $self->check_size (1); $self->update; } @@ -1169,8 +1215,8 @@ my ($ws, $hs) = $self->get_wh; - my $req_w = sum @$ws; - my $req_h = sum @$hs; + my $req_w = (sum @$ws) || 1; + my $req_h = (sum @$hs) || 1; # TODO: nicer code && do row_expand my @col_expand = @{$self->{col_expand}}; @@ -2134,9 +2180,10 @@ sub set_range { my ($self, $range) = @_; - $self->{range} = $range; + ($range, $self->{range}) = ($self->{range}, $range); - $self->update; + $self->update + if "@$range" ne "@{$self->{range}}"; } sub set_value { @@ -2529,8 +2576,8 @@ my $class = shift; my $self = $class->SUPER::new ( - state => 0, - connect_activate => \&toggle_flopper, + state => 0, + on_activate => \&toggle_flopper, @_ ); @@ -2749,8 +2796,6 @@ $row++; } - -# $range->{range} = [$self->{pos}, 0, $self->{max_pos}, $page]; } sub size_request { @@ -2952,6 +2997,7 @@ my $class = shift; $class->SUPER::new ( + visible => 1, @_, ) } @@ -3019,8 +3065,8 @@ for (my @widgets = @children; my $w = pop @widgets; ) { push @widgets, $w->children; - $w->{root} = $self; - $w->{visible} = 1; + $w->{root} = $self; + $w->{visible} = $self->{visible} + 1; } for my $child (@children) { @@ -3067,16 +3113,19 @@ } if ($self->{check_size}) { - my @queue = ([], []); + my @queue; for (;;) { if ($self->{check_size}) { - # heuristic: check containers last - push @{ $queue[ ! ! $_->isa ("CFClient::UI::Container") ] }, $_ - for values %{delete $self->{check_size}} + #TODO use array-of-depth approach + + @queue = sort { $a->{visible} <=> $b->{visible} } + @queue, values %{delete $self->{check_size}}; } - my $widget = (pop @{ $queue[0] }) || (pop @{ $queue[1] }) || last; + my $widget = pop @queue || last; + + defined $widget->{visible} or last; # do not resize invisible widgets my ($w, $h) = $widget->{user_w} && $widget->{user_h} ? @$widget{qw(user_w user_h)}