--- deliantra/Deliantra-Client/DC/UI.pm 2006/04/28 05:17:21 1.179 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/05/03 19:56:05 1.184 @@ -239,6 +239,7 @@ $self->size_allocate ($w, $h); $self->update; + $self->emit (size_allocate => $w, $h); } } @@ -249,7 +250,7 @@ sub children { } -# call when resoltuion changes etc. +# call when resolution changes etc. sub reconfigure { my ($self) = @_; @@ -541,6 +542,7 @@ ]; $child->check_size; + $self->update; } sub children { @@ -569,6 +571,9 @@ delete $_->{parent}; $_->hide; } + + $self->check_size; + $self->update; } sub find_widget { @@ -664,13 +669,18 @@ $self->update; } +sub _render { + $_[0]{children}[0]->draw; +} + sub render_child { my ($self) = @_; $self->{texture} = new_from_opengl CFClient::Texture $self->{w}, $self->{h}, sub { glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; - $self->child->draw; + + $self->_render; # glColorMask 1, 1, 1, 0; # glEnable GL_BLEND; # glBlendFunc GL_SRC_ALPHA, GL_ZERO; @@ -707,23 +717,91 @@ our @ISA = CFClient::UI::Window::; -sub new { die } - sub size_request { my ($self) = @_; @$self{qw(child_w child_h)} = @{$self->child}{qw(req_w req_h)}; - $self->child->size_allocate (0, 0, @$self{qw(child_w child_h)}); + $self->child->configure (0, 0, @$self{qw(child_w child_h)}); @$self{qw(child_w child_h)} } -sub _draw { +sub size_allocate { + my ($self, $w, $h) = @_; + + $self->update; +} + +sub set_offset { + my ($self, $x, $y) = @_; + + $self->{view_x} = int $x; + $self->{view_y} = int $y; + + $self->update; +} + +# hmm, this does not work for topleft of $self... but we should not aks for that +sub _topleft { + my ($self, $x, $y) = @_; + + $self->SUPER::_topleft ($x - $self->{view_x}, $y - $self->{view_y}) +} + +sub find_widget { + my ($self, $x, $y) = @_; + + 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}) + } else { + $self->CFClient::UI::Base::find_widget ($x, $y) + } +} + +sub _render { my ($self) = @_; - $self->{children}[1]->draw; + CFClient::OpenGL::glTranslate -$self->{view_x}, -$self->{view_y}; + + $self->SUPER::_render; } +############################################################################# + +package CFClient::UI::ScrolledWindow; + +our @ISA = CFClient::UI::HBox::; + +sub new { + my $class = shift; + + my $self; + + my $slider = new CFClient::UI::Slider + vertical => 1, + range => [0, 0, 1, 0.01], # HACK fix + connect_changed => sub { + $self->{vp}->set_offset (0, $_[1] * ($self->{vp}{child_h} - $self->{vp}{h})); + }, + ; + + $self = $class->SUPER::new ( + vp => (new CFClient::UI::ViewPort), + slider => $slider, + @_, + ); + + $self->{vp}->add ($self->{scrolled}); + $self->add ($self->{vp}); + $self->add ($self->{slider}); + + $self +} + +#TODO# update range on size_allocate depeneing on child +# update viewport offset on scroll ############################################################################# @@ -1959,8 +2037,8 @@ fg => [1, 1, 1], active_fg => [0, 0, 0], range => [0, 0, 100, 10], - req_w => 20, - req_h => 20, + req_w => $::WIDTH / 80, + req_h => $::WIDTH / 80, vertical => 0, can_hover => 1, inner_pad => 5, @@ -2477,7 +2555,7 @@ sub mouse_motion { my ($self, $ev, $x, $y) = @_; - # TODO: should use vbox->fdind_widget or so + # TODO: should use vbox->find_widget or so $HOVER = $ROOT->find_widget ($ev->{x}, $ev->{y}); $self->{hover} = $self->{item}{$HOVER}; } @@ -2577,33 +2655,90 @@ ############################################################################# -package CFClient::UI::Inventory; - -our @ISA = CFClient::UI::Container::; +package CFClient::UI::InventoryItem; -use CFClient::OpenGL; +our @ISA = CFClient::UI::HBox::; sub new { my $class = shift; - my $self = $class->SUPER::new (@_); + my %args = @_; + + my $item = $args{item}; + + my $desc = $item->{nrof} < 2 + ? $item->{name} + : "$item->{nrof} $item->{name_pl}"; + + + my $self = $class->SUPER::new ( + can_hover => 1, + can_events => 1, + tooltip => (CFClient::UI::Label->escape ($desc) + . "\nleftclick - pick up\nmiddle click - apply\nrightclick - menu"), + connect_button_down => sub { + my ($self, $ev, $x, $y) = @_; + + # todo: maybe put examine on 1? but should just be a tooltip :( + if ($ev->{button} == 1) { + $::CONN->send ("move $::CONN->{player}{tag} $item->{tag} 0"); + } elsif ($ev->{button} == 2) { + $::CONN->send ("apply $item->{tag}"); + } elsif ($ev->{button} == 3) { + CFClient::UI::Menu->new ( + items => [ + ["examine", sub { $::CONN->send ("examine $item->{tag}") }], + [ + $item->{flags} & Crossfire::Protocol::F_LOCKED ? "lock" : "unlock", + sub { $::CONN->send ("lock $item->{tag}") }, + ], + ["mark", sub { $::CONN->send ("mark $item->{tag}") }], + ["apply", sub { $::CONN->send ("apply $item->{tag}") }], + ["drop", sub { $::CONN->send ("move 0 $item->{tag} 0") }], + ], + )->popup ($ev); + } + + 1 + }, + %args + ); + $self->add(new CFClient::UI::Face + can_events => 0, + face => $item->{face}, + anim => $item->{anim}, + animspeed => $item->{animspeed}); + $self->add(new CFClient::UI::Label + can_events => 0, + text => $desc); $self } -sub size_allocate { - my ($self, $w, $h) = @_; +############################################################################# - $self->{w} = $w; - $self->{h} = $h; +package CFClient::UI::Inventory; - $self->check_size; +our @ISA = CFClient::UI::ScrolledWindow::; + +sub new { + my $class = shift; + + my $self = $class->SUPER::new ( + scrolled => (new CFClient::UI::VBox), + @_, + ); + + $self } sub set_items { my ($self, $items) = @_; - my @items = values %{$items}; - @items = sort { $a->{type} <=> $b->{type} } @items; + + $self->{scrolled}->clear; + return unless $items; + + my @items = sort { $a->{type} <=> $b->{type} } @$items; $self->{real_items} = \@items; @@ -2612,76 +2747,17 @@ ? $item->{name} : "$item->{nrof} $item->{name_pl}"; - $self->add (my $hb = new CFClient::UI::HBox); + $self->{scrolled}->add (new CFClient::UI::InventoryItem item => $item); + } - $hb->add (my $f = new CFClient::UI::Face - can_events => 0, - face => $item->{face}, - anim => $item->{anim}, - animspeed => $item->{animspeed}, - expand => 1 - ); - $hb->add (new CFClient::UI::Label text => $desc, expand => 1); - } - - $self->{max_pos} = (scalar @items) - 1; - - my $range = $self->{range}; - my $page = $self->{h} / 32; # waht information souce to use for face size? - # it should be configurable i guess... - $range->{range} = [$self->{pos}, 0, $self->{max_pos}, $page]; - $range->update; +# $range->{range} = [$self->{pos}, 0, $self->{max_pos}, $page]; } sub size_request { my ($self) = @_; - (100, 200) -} - -sub set_range { - my ($self, $range) = @_; - - $self->{range} = $range; - $range->connect (changed => sub { $self->update }); - - my $page = $self->{h} / 32; # waht information souce to use for face size? - # it should be configurable i guess... - - $range->{range} = [$self->{pos}, 0, $self->{max_pos}, $page]; - $range->update; - - $self->update; + ($self->{req_w}, $self->{req_h}); } -sub _draw { - my ($self) = @_; - - my ($w, $h) = ($self->{w}, $self->{h}); - - $self->{pos} = int $self->{range}{range}[0]; - - my $y = 0; - my $cnt = 0; - my $hrem = $self->{h}; # horiz. remaining space - - for (my $i = $self->{pos}; $i < @{$self->{children} || []}; $i++) { - my $chld = $self->{children}->[$i]; - - if ($hrem >= $chld->{h}) { - $chld->configure (0, $y, $chld->{w}, $chld->{h}); - - $chld->show; - $chld->draw; - - $hrem -= $chld->{h}; - $y += $chld->{h}; - } else { - last - } - } -} - - ############################################################################# package CFClient::UI;