--- deliantra/Deliantra-Client/DC/UI.pm 2007/07/19 13:45:18 1.381 +++ deliantra/Deliantra-Client/DC/UI.pm 2007/07/21 13:29:46 1.390 @@ -115,8 +115,12 @@ if ($GRAB) { if ($ev->{button} == 4 || $ev->{button} == 5) { # mousewheel - $ev->{dx} = 0; - $ev->{dy} = $ev->{button} * 2 - 9; + my $delta = $ev->{button} * 2 - 9; + my $shift = $ev->{mod} & CFPlus::KMOD_SHIFT; + + $ev->{dx} = $shift ? $delta : 0; + $ev->{dy} = $shift ? 0 : $delta; + $GRAB->emit (mouse_wheel => $ev); } else { $GRAB->emit (button_down => $ev) @@ -549,17 +553,8 @@ $self->{parent} && $self->{parent}->emit ($signal, @args) } -sub find_widget { - my ($self, $x, $y) = @_; - - return () unless $self->{can_events}; - - return $self - if $x >= $self->{x} && $x < $self->{x} + $self->{w} - && $y >= $self->{y} && $y < $self->{y} + $self->{h}; - - () -} +#sub find_widget { +# in .xs sub set_parent { my ($self, $parent) = @_; @@ -748,7 +743,7 @@ ); $self->add (@$children) - if $children; + if $children && @$children; $self } @@ -767,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} = [ @@ -965,8 +961,8 @@ my ($w, $h) = @{$self->child}{qw(req_w req_h)}; - $w = 10 if $self->{scroll_x}; - $h = 10 if $self->{scroll_y}; + $w = 1 if $self->{scroll_x}; + $h = 1 if $self->{scroll_y}; ($w, $h) } @@ -1022,7 +1018,7 @@ if ( $x >= $self->{x} && $x < $self->{x} + $self->{w} && $y >= $self->{y} && $y < $self->{y} + $self->{h} ) { - $self->child->find_widget ($x + $self->{view_x}, $y + $self->{view_y}) + $self->child->find_widget ($x + $self->{view_x}, $y + $self->{view_y}) } else { $self->CFPlus::UI::Base::find_widget ($x, $y) } @@ -1053,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 { @@ -1062,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 { @@ -1082,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}, @@ -1095,14 +1097,14 @@ }, ; - $self->SUPER::add (0, 0, $self->{vp}); + $self->SUPER::add ($self->{vp}); $self->add ($child) if $child; $self } -#TODO# update range on size_allocate depending on child +#TODO# update range on size_allocate depending on child? sub add { my ($self, $widget) = @_; @@ -1120,8 +1122,8 @@ my $visible = $w1 > $w2; if ($visible != $self->{hslider}{visible}) { - $visible ? $self->SUPER::add (0, 1, $self->{hslider}) - : $self->{hslider}->hide; + $visible ? $self->SUPER::add ($self->{hslider}) + : $self->SUPER::remove ($self->{hslider}); } my ($h1, $h2) = ($child->{h}, $self->{vp}{h}); @@ -1129,24 +1131,26 @@ my $visible = $h1 > $h2; if ($visible != $self->{vslider}{visible}) { - $visible ? $self->SUPER::add (1, 0, $self->{vslider}) - : $self->{vslider}->hide; + $visible ? $self->SUPER::add ($self->{vslider}) + : $self->SUPER::remove ($self->{vslider}); } } sub update { my ($self) = @_; - $self->SUPER::update; $self->update_slider; + $self->SUPER::update; } sub invoke_mouse_wheel { my ($self, $ev) = @_; - return 0 unless $ev->{dy}; # only vertical movements for now + $self->{vslider}->emit (mouse_wheel => $ev) + if $ev->{dy}; - $self->{vslider}->emit (mouse_wheel => $ev); + $self->{hslider}->emit (mouse_wheel => $ev) + if $ev->{dx}; 1 } @@ -1357,6 +1361,10 @@ map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } qw(d1_border_top.png d1_border_right.png d1_border_left.png d1_border_bottom.png); +my @icon = + map { new_from_file CFPlus::Texture CFPlus::find_rcfile $_, mipmap => 1 } + qw(x1_move.png x1_resize.png); + sub new { my ($class, %arg) = @_; @@ -1534,10 +1542,24 @@ my $border = $self->border; glColor @{ $self->{border_bg} }; - $border[0]->draw_quad_alpha (0, 0, $w, $border); - $border[1]->draw_quad_alpha (0, $border, $border, $ch); - $border[2]->draw_quad_alpha ($w - $border, $border, $border, $ch); - $border[3]->draw_quad_alpha (0, $h - $border, $w, $border); + $border[0]->draw_quad_alpha ( 0, 0, $w, $border); + $border[1]->draw_quad_alpha ( 0, $border, $border, $ch); + $border[2]->draw_quad_alpha ($w - $border, $border, $border, $ch); + $border[3]->draw_quad_alpha ( 0, $h - $border, $w, $border); + + # move + my $w2 = ($w - $border) * .5; + my $h2 = ($h - $border) * .5; + $icon[0]->draw_quad_alpha ( 0, $h2, $border, $border); + $icon[0]->draw_quad_alpha ($w - $border, $h2, $border, $border); + $icon[0]->draw_quad_alpha ($w2 , $h - $border, $border, $border); + + # resize + $icon[1]->draw_quad_alpha ( 0, 0, $border, $border); + $icon[1]->draw_quad_alpha ($w - $border, 0, $border, $border) + unless $self->{has_close_button}; + $icon[1]->draw_quad_alpha ( 0, $h - $border, $border, $border); + $icon[1]->draw_quad_alpha ($w - $border, $h - $border, $border, $border); if (@{$self->{bg}} < 4 || $self->{bg}[3]) { glColor @{ $self->{bg} }; @@ -1568,7 +1590,7 @@ package CFPlus::UI::Table; -our @ISA = CFPlus::UI::Base::; +our @ISA = CFPlus::UI::Container::; use List::Util qw(max sum); @@ -1578,55 +1600,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) = @_; - while (@_) { - my ($x, $y, $child) = splice @_, 0, 3, (); - $child->set_parent ($self); - $self->{children}[$y][$x] = $child; + for my $child (@widgets) { + $child->{rowspan} ||= 1; + $child->{colspan} ||= 1; } - $self->{force_realloc} = 1; - $self->{force_size_alloc} = 1; - $self->realloc; + $self->SUPER::add (@widgets); } -sub remove { - my ($self, $child) = @_; +sub add_at { + my $self = shift; - for (@{ $self->{children} }) { - for (@{ $_ || [] }) { - $_ = undef if $_ == $child; - } - } -} + my @widgets; -# TODO: move to container class maybe? send children a signal on removal? -sub clear { - my ($self) = @_; + while (@_) { + my ($col, $row, $child) = splice @_, 0, 3, (); - my @children = $self->children; - delete $self->{children}; - - for (@children) { - delete $_->{parent}; - $_->hide; + $child->{row} = $row; + $child->{col} = $col; + + push @widgets, $child; } - $self->realloc; + $self->add (@widgets); } sub get_wh { @@ -1634,17 +1639,20 @@ my (@w, @h); - for my $y (0 .. $#{$self->{children}}) { - my $row = $self->{children}[$y] - or next; - - for my $x (0 .. $#$row) { - my $widget = $row->[$x] - or next; - my ($w, $h) = @$widget{qw(req_w req_h)}; + 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)}; - $w[$x] = max $w[$x], $w; - $h[$y] = max $h[$y], $h; + 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]; + } + + if ($h > $sh) { + $_ += ($h - $sh) / $rs for @h[$r .. $r + $rs - 1]; } } @@ -1670,7 +1678,7 @@ my $req_w = (sum @$ws) || 1; my $req_h = (sum @$hs) || 1; - # TODO: nicer code + # now linearly scale the rows/columns to the allocated size my @col_expand = @{$self->{col_expand}}; @col_expand = (1) x @$ws unless @col_expand; my $col_expand = (sum @col_expand) || 1; @@ -1687,55 +1695,21 @@ CFPlus::UI::harmonize $hs; - my $y; + my @x; for (0 .. $#$ws) { $x[$_ + 1] = $x[$_] + $ws->[$_] } + my @y; for (0 .. $#$hs) { $y[$_ + 1] = $y[$_] + $hs->[$_] } - for my $r (0 .. $#{$self->{children}}) { - my $row = $self->{children}[$r] - or next; + for my $widget ($self->children) { + my ($r, $c, $w, $h, $rs, $cs) = @$widget{qw(row col req_w req_h rowspan colspan)}; - my $x = 0; - my $row_h = $hs->[$r]; - - for my $c (0 .. $#$row) { - my $col_w = $ws->[$c]; - - if (my $widget = $row->[$c]) { - $widget->configure ($x, $y, $col_w, $row_h); - } - - $x += $col_w; - } - - $y += $row_h; + $widget->configure ( + $x[$c], $y[$r], + $x[$c + $cs] - $x[$c], $y[$r + $rs] - $y[$r], + ); } 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;