--- deliantra/Deliantra-Client/DC/UI.pm 2006/05/27 21:15:57 1.245 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/05/28 01:37:45 1.248 @@ -177,11 +177,9 @@ $widget->{x} = int 0.5 + $widget->{x} * $sx if exists $widget->{x}; $widget->{w} = int 0.5 + $widget->{w} * $sx if exists $widget->{w}; $widget->{req_w} = int 0.5 + $widget->{req_w} * $sx if exists $widget->{req_w}; - $widget->{user_w} = int 0.5 + $widget->{user_w} * $sx if exists $widget->{user_w}; $widget->{y} = int 0.5 + $widget->{y} * $sy if exists $widget->{y}; $widget->{h} = int 0.5 + $widget->{h} * $sy if exists $widget->{h}; $widget->{req_h} = int 0.5 + $widget->{req_h} * $sy if exists $widget->{req_h}; - $widget->{user_h} = int 0.5 + $widget->{user_h} * $sy if exists $widget->{user_h}; } } @@ -216,10 +214,10 @@ 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->{req_x} = $layout->{x} * $::WIDTH; + $self->{req_y} = $layout->{y} * $::HEIGHT; + $self->{def_w} = ($layout->{w} != 0 ? $layout->{w} : 1) * $::WIDTH; + $self->{def_h} = ($layout->{h} != 0 ? $layout->{h} : 1) * $::HEIGHT; } $self @@ -244,22 +242,33 @@ sub show { my ($self) = @_; + return if $self->{parent}; $CFClient::UI::ROOT->add ($self); } -sub show_centered { +sub center { my ($self) = @_; - return if $self->{parent}; - - $self->show; $CFClient::UI::ROOT->on_post_alloc ( - "centered $self" => sub { - $self->move (($::WIDTH - $self->{w}) * 0.5, ($::HEIGHT - $self->{h}) * 0.5); + "center_$self" => sub { + $self->move (($self->{parent}{w} - $self->{w}) * 0.5, ($self->{parent}{h} - $self->{h}) * 0.5); }, ); + + $self->update; +} + +sub set_visible { + my ($self) = @_; + + return if $self->{visible}; + + $self->{root} = $self->{parent}{root}; + $self->{visible} = $self->{parent}{visible} + 1; + + $self->emit (visibility_change => 1); } sub set_invisible { @@ -305,8 +314,8 @@ sub set_size { my ($self, $w, $h) = @_; - $self->{user_w} = $w; - $self->{user_h} = $h; + $self->{def_w} = $w; + $self->{def_h} = $h; $self->check_size; } @@ -502,19 +511,9 @@ Scalar::Util::weaken ($self->{parent} = $parent); - if ($parent->{visible} || 1) { - $self->{root} = $parent->{root}; - $self->{visible} = $parent->{visible} + 1; - - $self->emit (visibility_change => 1) - unless $self->{parent}{visible}; - } - - # TODO: req_w _does_change after ->reconfigure - $self->check_size - unless exists $self->{req_w}; + $self->set_visible; #TODO why breakssssss borked damn if $parent->{visible}; - $self->show; + $self->check_size; } sub check_size { @@ -837,9 +836,12 @@ sub size_request { my ($self) = @_; - @$self{qw(child_w child_h)} = @{$self->child}{qw(req_w req_h)}; + my ($w, $h) = @$self{qw(child_w child_h)} = @{$self->child}{qw(req_w req_h)}; + + $w = 10 if $self->{scroll_x}; + $h = 10 if $self->{scroll_y}; - @$self{qw(child_w child_h)} + ($w, $h) } sub size_allocate { @@ -1006,8 +1008,6 @@ sub new { my $class = shift; - # TODO: user_x, user_y, overwrite moveto? - my $self = $class->SUPER::new ( bg => [1, 1, 1, 1], border_bg => [1, 1, 1, 1], @@ -1078,8 +1078,8 @@ $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->{def_w} = $bw + $dx * ($mx ? -1 : 1); + $self->{def_h} = $bh + $dy * ($my ? -1 : 1); $self->move ($self->{user_x}, $self->{user_y}); $self->check_size; }; @@ -1095,6 +1095,7 @@ $self->{user_x} = $bx + $x - $ox; $self->{user_y} = $by + $y - $oy; + $self->move ($self->{user_x}, $self->{user_y}); $self->update; }; @@ -1303,59 +1304,59 @@ ############################################################################# -package CFClient::UI::HBox; - -# TODO: wrap into common Box base class +package CFClient::UI::Box; our @ISA = CFClient::UI::Container::; sub size_request { my ($self) = @_; - my @alloc = map [$_->size_request], @{$self->{children}}; - - ( - (List::Util::sum map $_->[0], @alloc), - (List::Util::max map $_->[1], @alloc), - ) + $self->{vertical} + ? ( + (List::Util::max map $_->{req_w}, @{$self->{children}}), + (List::Util::sum map $_->{req_h}, @{$self->{children}}), + ) + : ( + (List::Util::sum map $_->{req_w}, @{$self->{children}}), + (List::Util::max map $_->{req_h}, @{$self->{children}}), + ) } sub size_allocate { my ($self, $w, $h) = @_; - ($h, $w) = ($w, $h); - + my $space = $self->{vertical} ? $h : $w; my $children = $self->{children}; - my @h = map $_->{req_w}, @$children; - - my $req_h = List::Util::sum @h; + my @req; - if ($req_h > $h) { - # ah well, not enough space - $_ *= $h / $req_h for @h; + if ($self->{homogeneous}) { + @req = ($space / (@$children || 1)) x @$children; } else { - my $exp = List::Util::sum map $_->{expand}, @$children; - $exp ||= 1; - - for (0 .. $#$children) { - my $child = $children->[$_]; + @req = map $_->{$self->{vertical} ? "req_h" : "req_w"}, @$children; + my $req = List::Util::sum @req; + + if ($req > $space) { + # ah well, not enough space + $_ *= $space / $req for @req; + } else { + my $expand = (List::Util::sum map $_->{expand}, @$children) || 1; + + $space = ($space - $req) / $expand; # remaining space to give away - my $alloc_h = $h[$_]; - $alloc_h += ($h - $req_h) * $child->{expand} / $exp; - $h[$_] = $alloc_h; + $req[$_] += $space * $children->[$_]{expand} + for 0 .. $#$children; } } - CFClient::UI::harmonize \@h; + CFClient::UI::harmonize \@req; - my $y = 0; + my $pos = 0; for (0 .. $#$children) { - my $child = $children->[$_]; - my $h = $h[$_]; - $child->configure ($y, 0, $h, $w); + my $alloc = $req[$_]; + $children->[$_]->configure ($self->{vertical} ? (0, $pos, $w, $alloc) : ($pos, 0, $alloc, $h)); - $y += $h; + $pos += $alloc; } 1 @@ -1363,60 +1364,32 @@ ############################################################################# -package CFClient::UI::VBox; - -# TODO: wrap into common Box base class - -our @ISA = CFClient::UI::Container::; +package CFClient::UI::HBox; -sub size_request { - my ($self) = @_; +our @ISA = CFClient::UI::Box::; - my @alloc = map [$_->size_request], @{$self->{children}}; +sub new { + my $class = shift; - ( - (List::Util::max map $_->[0], @alloc), - (List::Util::sum map $_->[1], @alloc), + $class->SUPER::new ( + vertical => 0, + @_, ) } -sub size_allocate { - my ($self, $w, $h) = @_; - - Carp::confess "negative size" if $w < 0 || $h < 0;#d# - - my $children = $self->{children}; - - my @h = map $_->{req_h}, @$children; - - my $req_h = List::Util::sum @h; - - if ($req_h > $h) { - # ah well, not enough space - $_ *= $h / $req_h for @h; - } else { - my $exp = List::Util::sum map $_->{expand}, @$children; - $exp ||= 1; - - for (0 .. $#$children) { - my $child = $children->[$_]; - - $h[$_] += ($h - $req_h) * $child->{expand} / $exp; - } - } +############################################################################# - CFClient::UI::harmonize \@h; +package CFClient::UI::VBox; - my $y = 0; - for (0 .. $#$children) { - my $child = $children->[$_]; - my $h = $h[$_]; - $child->configure (0, $y, $w, $h); +our @ISA = CFClient::UI::Box::; - $y += $h; - } +sub new { + my $class = shift; - 1 + $class->SUPER::new ( + vertical => 1, + @_, + ) } ############################################################################# @@ -2806,11 +2779,6 @@ } } -sub size_request { - my ($self) = @_; - ($self->{req_w}, $self->{req_h}); -} - ############################################################################# package CFClient::UI::Menu; @@ -3042,8 +3010,7 @@ $Y = $child->{req_y} > 0 ? $child->{req_y} : $h - $H - $child->{req_y} + 1 if exists $child->{req_y}; - $X = $self->{user_x} if exists $self->{user_x}; - $Y = $self->{user_y} if exists $self->{user_y}; + delete @$child{qw(req_x req_y)}; $X = List::Util::max 0, List::Util::min $w - $W, int $X + 0.5; $Y = List::Util::max 0, List::Util::min $h - $H, int $Y + 0.5; @@ -3074,12 +3041,6 @@ sub add { my ($self, @children) = @_; - for (my @widgets = @children; my $w = pop @widgets; ) { - push @widgets, $w->children; - $w->{root} = $self; - $w->{visible} = $self->{visible} + 1; - } - for my $child (@children) { $child->{is_toplevel} = 1; @@ -3089,6 +3050,12 @@ } $self->SUPER::add (@children); + + for (my @widgets = @children; my $w = pop @widgets; ) { + push @widgets, $w->children; + $w->set_visible; + } + } sub remove { @@ -3138,8 +3105,8 @@ 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)} + my ($w, $h) = $widget->{def_w} && $widget->{def_h} + ? @$widget{qw(def_w def_h)} : $widget->size_request; if (delete $widget->{force_alloc}