--- deliantra/Deliantra-Client/DC/UI.pm 2006/04/25 11:18:49 1.174 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/04/29 16:17:09 1.181 @@ -671,6 +671,13 @@ glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; $self->child->draw; +# glColorMask 1, 1, 1, 0; +# glEnable GL_BLEND; +# glBlendFunc GL_SRC_ALPHA, GL_ZERO; +# glRasterPos 0, 0; +# glCopyPixels 0, 0, $self->{w}, $self->{h}; +# glDisable GL_BLEND; +# glColorMask 1, 1, 1, 1; }; } @@ -783,7 +790,7 @@ my $self = $class->SUPER::new ( bg => [1, 1, 1, 1], border_bg => [1, 1, 1, 1], - border => 0.8, + border => 0.6, can_events => 1, @_ ); @@ -792,7 +799,7 @@ align => 0, valign => 1, text => $self->{title}, - fontsize => 1; + fontsize => $self->{border}; $self } @@ -827,27 +834,33 @@ sub button_down { my ($self, $ev, $x, $y) = @_; + my ($w, $h) = @$self{qw(w h)}; my $border = $self->border; - if ($x < $self->{w} && $x >= $self->{w} - $border - && $y < $self->{h} && $y >= $self->{h} - $border) { + my $lr = ($x >= 0 && $x < $border) || ($x > $w - $border && $x < $w); + my $td = ($y >= 0 && $y < $border) || ($y > $h - $border && $y < $h); + if ($lr & $td) { + my ($wx, $wy) = ($self->{x}, $self->{y}); my ($ox, $oy) = ($ev->{x}, $ev->{y}); my ($bw, $bh) = ($self->{w}, $self->{h}); + my $mx = $x < $border; + my $my = $y < $border; + $self->{motion} = sub { my ($ev, $x, $y) = @_; - ($x, $y) = ($ev->{x}, $ev->{y}); + my $dx = $ev->{x} - $ox; + my $dy = $ev->{y} - $oy; - $self->{user_w} = $bw + $x - $ox; - $self->{user_h} = $bh + $y - $oy; + $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->check_size; }; - } elsif ($x >= 0 && $x < $self->{w} - && $y >= 0 && $y < $border) { - + } elsif ($lr ^ $td) { my ($ox, $oy) = ($ev->{x}, $ev->{y}); my ($bx, $by) = ($self->{x}, $self->{y}); @@ -893,23 +906,26 @@ $tex[2]->draw_quad ($w - $border, $border, $border, $ch); $tex[4]->draw_quad (0, $h - $border, $w, $border); - my $bg = $tex[0]; + if (@{$self->{bg}} < 4 || $self->{bg}[3]) { + my $bg = $tex[0]; - # TODO: repeat texture not scale - my $rep_x = $cw / $bg->{w}; - my $rep_y = $ch / $bg->{h}; - - glColor @{ $self->{bg} }; - - $bg->{s} = $rep_x; - $bg->{t} = $rep_y; - $bg->{wrap_mode} = 1; - $bg->draw_quad ($border, $border, $cw, $ch); + # TODO: repeat texture not scale + my $rep_x = $cw / $bg->{w}; + my $rep_y = $ch / $bg->{h}; + + glColor @{ $self->{bg} }; + + $bg->{s} = $rep_x; + $bg->{t} = $rep_y; + $bg->{wrap_mode} = 1; + $bg->draw_quad ($border, $border, $cw, $ch); - glDisable GL_TEXTURE_2D; - glDisable GL_BLEND; + glDisable GL_TEXTURE_2D; + glDisable GL_BLEND; + } $self->{title}->draw if $self->{title}; + $self->child->draw; } @@ -2078,9 +2094,7 @@ ], ); - $self->{children}[1]->connect (changed => sub { - $self->update; - }); + $self->{children}[1]->connect (changed => sub { $self->update }); $self } @@ -2098,7 +2112,7 @@ my $layout = $self->{layout}; $layout->set_height ($self->{fontsize} * $::FONTSIZE); - $layout->set_width ($self->{w}); + $layout->set_width ($self->{children}[0]{w}); $layout->set_text ($text); ($layout->size)[1] @@ -2161,8 +2175,8 @@ delete $self->{texture}; } - $self->{texture} ||= new_from_opengl CFClient::Texture $self->{w}, $self->{h}, sub { - glClearColor 0, 0, 0, 1; + $self->{texture} ||= new_from_opengl CFClient::Texture $self->{children}[0]{w}, $self->{children}[0]{h}, sub { + glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; glEnable GL_BLEND; @@ -2204,13 +2218,14 @@ sub _draw { my ($self) = @_; - if ($self->{texture}) { - glEnable GL_TEXTURE_2D; - glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; - glColor 1, 1, 1, 1; - $self->{texture}->draw_quad (0, 0, $self->{w}, $self->{h}); - glDisable GL_TEXTURE_2D; - } + glEnable GL_BLEND; + glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; + glEnable GL_TEXTURE_2D; + glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; + glColor 1, 1, 1, 1; + $self->{texture}->draw_quad (0, 0, $self->{children}[0]{w}, $self->{children}[0]{h}); + glDisable GL_TEXTURE_2D; + glDisable GL_BLEND; $self->{children}[1]->draw; @@ -2389,11 +2404,12 @@ (32, 8) } -sub draw { +sub _draw { my ($self) = @_; my $tex = $::CONN->{texture}[$::CONN->{faceid}[$self->{face}]]; + # TODO animation if ($tex) { glEnable GL_BLEND; glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; @@ -2408,6 +2424,78 @@ ############################################################################# +package CFClient::UI::Menu; + +our @ISA = CFClient::UI::FancyFrame::; + +use CFClient::OpenGL; + +sub new { + my $class = shift; + + my $self = $class->SUPER::new ( + items => [], + z => 100, + @_, + ); + + $self->add ($self->{vbox} = new CFClient::UI::VBox); + + for my $item (@{ $self->{items} }) { + my ($widget, $cb) = @$item; + + # handle various types of items, only text for now + if (!ref $widget) { + $widget = new CFClient::UI::Label + can_hover => 1, + can_events => 1, + text => $widget; + } + + $self->{item}{$widget} = $item; + + $self->{vbox}->add ($widget); + } + + $self +} + +# popup given the event (must be a mouse button down event currently) +sub popup { + my ($self, $ev) = @_; + + $self->emit ("popdown"); + + # maybe save $GRAB? must be careful about events... + $GRAB = $self; + $self->{button} = $ev->{button}; + + $self->show; + $self->move ($ev->{x} - $self->{w} * 0.5, $ev->{y} - $self->{h} * 0.5); +} + +sub mouse_motion { + my ($self, $ev, $x, $y) = @_; + + # TODO: should use vbox->fdind_widget or so + $HOVER = $ROOT->find_widget ($ev->{x}, $ev->{y}); + $self->{hover} = $self->{item}{$HOVER}; +} + +sub button_up { + my ($self, $ev, $x, $y) = @_; + + if ($ev->{button} == $self->{button}) { + undef $GRAB; + $self->hide; + + $self->emit ("popdown"); + $self->{hover}[1]->() if $self->{hover}; + } +} + +############################################################################# + package CFClient::UI::Root; our @ISA = CFClient::UI::Container::; @@ -2489,6 +2577,111 @@ ############################################################################# +package CFClient::UI::Inventory; + +our @ISA = CFClient::UI::Container::; + +use CFClient::OpenGL; + +sub new { + my $class = shift; + + my $self = $class->SUPER::new (@_); + + $self +} + +sub size_allocate { + my ($self, $w, $h) = @_; + + $self->{w} = $w; + $self->{h} = $h; + + $self->check_size; +} + +sub set_items { + my ($self, $items) = @_; + my @items = sort { $a->{type} <=> $b->{type} } @$items; + + $self->{real_items} = \@items; + + for my $item (@items) { + my $desc = $item->{nrof} < 2 + ? $item->{name} + : "$item->{nrof} $item->{name_pl}"; + + $self->add (my $hb = new CFClient::UI::HBox); + + $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; # what information source to use for face size? + # it should be configurable I guess... + $range->{range} = [$self->{pos}, 0, $self->{max_pos}, $page]; + $range->update; +} + +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; +} + +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->draw; + + $hrem -= $chld->{h}; + $y += $chld->{h}; + } else { + last + } + } +} + + +############################################################################# + package CFClient::UI; $ROOT = new CFClient::UI::Root;