--- deliantra/Deliantra-Client/DC/UI.pm 2006/06/24 00:24:09 1.313 +++ deliantra/Deliantra-Client/DC/UI.pm 2006/07/05 01:53:24 1.322 @@ -425,10 +425,9 @@ return if $FOCUS == $self; return unless $self->{can_focus}; - my $focus = $FOCUS; $FOCUS = $self; + $FOCUS = $self; - $focus->update if $focus; - $FOCUS->update; + $self->update; 0 } @@ -438,9 +437,9 @@ return unless $FOCUS == $self; - my $focus = $FOCUS; undef $FOCUS; + undef $FOCUS; - $focus->update if $focus; #? + $self->update; $::MAPWIDGET->grab_focus #d# focus mapwidget if no other widget has focus unless $FOCUS; @@ -451,6 +450,7 @@ sub grab_focus { my ($self) = @_; + $FOCUS->emit ("focus_out") if $FOCUS; $self->emit ("focus_in"); } @@ -988,34 +988,36 @@ $self } +#TODO# update range on size_allocate depending on child + sub add { my ($self, $widget) = @_; $self->{vp}->add ($self->{child} = $widget); } +sub update_slider { + my ($self) = @_; + + $self->{slider}->set_range ([$self->{slider}{range}[0], 0, $self->{vp}->child->{h}, $self->{vp}{h}, 1]); +} + 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]); + $self->update_slider; } sub invoke_size_allocate { my ($self, $w, $h) = @_; - my $child = $self->{vp}->child; - $self->{slider}->set_range ([$self->{slider}{range}[0], 0, $child->{h}, $self->{vp}{h}, 1]); + $self->update_slider; $self->SUPER::invoke_size_allocate ($w, $h) } -#TODO# update range on size_allocate depending on child -# update viewport offset on scroll - ############################################################################# package CFClient::UI::Frame; @@ -1096,7 +1098,7 @@ $self->{close_button} = new CFClient::UI::ImageButton path => 'x1_close.png', - on_activate => sub { $self->hide }; + on_activate => sub { $self->emit ("delete") }; $self->CFClient::UI::Container::add ($self->{close_button}); } @@ -1155,6 +1157,14 @@ 1 } +sub invoke_delete { + my ($self) = @_; + + $self->hide; + + 1 +} + sub invoke_button_down { my ($self, $ev, $x, $y) = @_; @@ -1528,7 +1538,7 @@ #markup => initial narkup #max_w => maximum pixel width ellipsise => 3, # end - layout => (new CFClient::Layout), + layout => (new CFClient::Layout 2), fontsize => 1, align => -1, valign => -1, @@ -1539,7 +1549,7 @@ ); if (exists $self->{template}) { - my $layout = new CFClient::Layout; + my $layout = new CFClient::Layout 2; $layout->set_text (delete $self->{template}); $self->{template} = $layout; } @@ -1583,7 +1593,6 @@ return if $self->{text} eq "T$text"; $self->{text} = "T$text"; - $self->{layout} = new CFClient::Layout if $self->{layout}->is_rgba; $self->{layout}->set_text ($text); delete $self->{size_req}; @@ -1599,7 +1608,6 @@ my $rgba = $markup =~ /span.*(?:foreground|background)/; - $self->{layout} = new CFClient::Layout $rgba if $self->{layout}->is_rgba != $rgba; $self->{layout}->set_markup ($markup); delete $self->{size_req}; @@ -1654,6 +1662,7 @@ my ($self, $fontsize) = @_; $self->{fontsize} = $fontsize; + delete $self->{size_req}; delete $self->{texture}; $self->realloc; @@ -1663,6 +1672,7 @@ my ($self) = @_; delete $self->{size_req}; + delete $self->{texture}; $self->SUPER::reconfigure; } @@ -1672,7 +1682,7 @@ $self->SUPER::_draw; # draw background, if applicable - my $tex = $self->{texture} ||= do { + my $size = $self->{texture} ||= do { $self->{layout}->set_foreground (@{$self->{fg}}); $self->{layout}->set_font ($self->{font}) if $self->{font}; $self->{layout}->set_width ($self->{w}); @@ -1680,34 +1690,23 @@ $self->{layout}->set_single_paragraph_mode ($self->{ellipsise}); $self->{layout}->set_height ($self->{fontsize} * $::FONTSIZE); - new_from_layout CFClient::Texture $self->{layout} + $self->{size_req} }; unless (exists $self->{ox}) { $self->{ox} = int ($self->{align} < 0 ? $self->{padding_x} - : $self->{align} > 0 ? $self->{w} - $tex->{w} - $self->{padding_x} - : ($self->{w} - $tex->{w}) * 0.5); + : $self->{align} > 0 ? $self->{w} - $size->[0] - $self->{padding_x} + : ($self->{w} - $size->[0]) * 0.5); $self->{oy} = int ($self->{valign} < 0 ? $self->{padding_y} - : $self->{valign} > 0 ? $self->{h} - $tex->{h} - $self->{padding_y} - : ($self->{h} - $tex->{h}) * 0.5); + : $self->{valign} > 0 ? $self->{h} - $size->[1] - $self->{padding_y} + : ($self->{h} - $size->[1]) * 0.5); }; - glEnable GL_TEXTURE_2D; - - my $w = List::Util::min $self->{w} + 4, $tex->{w}; - my $h = List::Util::min $self->{h} + 2, $tex->{h}; + my $w = List::Util::min $self->{w} + 4, $size->[0]; + my $h = List::Util::min $self->{h} + 2, $size->[1]; - if ($tex->{format} == GL_ALPHA) { - glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE; - glColor @{$self->{fg}}; - $tex->draw_quad_alpha ($self->{ox}, $self->{oy}, $w, $h); - } else { - glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; - $tex->draw_quad_alpha_premultiplied ($self->{ox}, $self->{oy}, $w, $h); - } - - glDisable GL_TEXTURE_2D; + $self->{layout}->render ($self->{ox}, $self->{oy}); } ############################################################################# @@ -2059,13 +2058,20 @@ (6) x 2 } +sub toggle { + my ($self) = @_; + + $self->{state} = !$self->{state}; + $self->emit (changed => $self->{state}); + $self->update; +} + sub invoke_button_down { my ($self, $ev, $x, $y) = @_; if ($x >= $self->{padding_x} && $x < $self->{w} - $self->{padding_x} && $y >= $self->{padding_y} && $y < $self->{h} - $self->{padding_y}) { - $self->{state} = !$self->{state}; - $self->emit (changed => $self->{state}); + $self->toggle; } else { return 0 } @@ -2246,6 +2252,9 @@ my $h1 = $self->{h} * (1 - $ycut1); my $h2 = $self->{h} * (1 - $ycut2); + my $h3 = $self->{h}; + + $_ = $_ * (284-4)/288 + 4/288 for ($h1, $h2, $h3); glEnable GL_BLEND; glBlendFuncSeparate GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, @@ -2274,8 +2283,8 @@ glBindTexture GL_TEXTURE_2D, $t3->{name}; glBegin GL_QUADS; glTexCoord 0 , $t3->{t} * (1 - $ycut2); glVertex 0 , $h2; - glTexCoord 0 , $t3->{t}; glVertex 0 , $self->{h}; - glTexCoord $t3->{s}, $t3->{t}; glVertex $w, $self->{h}; + glTexCoord 0 , $t3->{t}; glVertex 0 , $h3; + glTexCoord $t3->{s}, $t3->{t}; glVertex $w, $h3; glTexCoord $t3->{s}, $t3->{t} * (1 - $ycut2); glVertex $w, $h2; glEnd; } @@ -2554,7 +2563,7 @@ #font => default_font @_, - layout => (new CFClient::Layout 1), + layout => (new CFClient::Layout 2), par => [], height => 0, children => [ @@ -2725,10 +2734,6 @@ my $y = 0; - glEnable GL_BLEND; - #TODO# not correct in windows where rgba is forced off - glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; - for my $para (@{$self->{par}}) { my $h = $para->{h}; @@ -2736,15 +2741,11 @@ my $layout = $self->get_layout ($para); - my ($w, $h, $data, $format, $internalformat) = $layout->render; - - glRasterPos $para->{indent}, $y - $y0; - glDrawPixels $w, $h, $format, GL_UNSIGNED_BYTE, $data; + $layout->render ($para->{indent}, $y - $y0); if (my @w = @{ $para->{widget} }) { my @s = $layout->get_shapes; - glDisable GL_BLEND; for (@w) { my ($dx, $dy) = splice @s, 0, 2, (); @@ -2753,15 +2754,11 @@ $_->draw; } - glEnable GL_BLEND; - glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA; } } $y += $h; } - - glDisable GL_BLEND; }; }); } @@ -3067,11 +3064,26 @@ # handle various types of items, only text for now if (!ref $widget) { - $widget = new CFClient::UI::Label - can_hover => 1, - can_events => 1, - markup => $widget, - tooltip => $tooltip + if ($widget =~ /\t/) { + my ($left, $right) = split /\t/, $widget, 2; + + $widget = new CFClient::UI::HBox + can_hover => 1, + can_events => 1, + tooltip => $tooltip, + children => [ + (new CFClient::UI::Label markup => $left, expand => 1), + (new CFClient::UI::Label markup => $right, align => +1), + ], + ; + + } else { + $widget = new CFClient::UI::Label + can_hover => 1, + can_events => 1, + markup => $widget, + tooltip => $tooltip; + } } $self->{item}{$widget} = $item; @@ -3150,6 +3162,12 @@ if @{ $self->{children} }; } +sub get_current_page { + my ($self) = @_; + + $self->{current} +} + sub set_current_page { my ($self, $page_or_widget) = @_; @@ -3225,6 +3243,12 @@ $self->{multiplexer}->add ($widget); } +sub get_current_page { + my ($self) = @_; + + $self->{multiplexer}->get_current_page +} + sub set_current_page { my ($self, $page) = @_; @@ -3410,7 +3434,9 @@ }; } - $self->reorder; + $ROOT->on_refresh (reorder => sub { + $self->reorder; + }); } sub reconfigure { @@ -3435,13 +3461,13 @@ package CFClient::UI::Inventory; -our @ISA = CFClient::UI::ScrolledWindow::; +our @ISA = CFClient::UI::Table::; sub new { my $class = shift; my $self = $class->SUPER::new ( - child => (new CFClient::UI::Table col_expand => [0, 1, 0]), + col_expand => [0, 1, 0], @_, ); @@ -3451,13 +3477,13 @@ sub set_items { my ($self, $items) = @_; - $self->{child}->clear; + $self->clear; return unless $items; my @items = sort { ($a->{type} <=> $b->{type}) or ($a->{name} cmp $b->{name}) - } @$items; + } values %$items; $self->{real_items} = \@items; @@ -3465,9 +3491,9 @@ for my $item (@items) { CFClient::Item::update_widgets $item; - $self->{child}->add (0, $row, $item->{face_widget}); - $self->{child}->add (1, $row, $item->{desc_widget}); - $self->{child}->add (2, $row, $item->{weight_widget}); + $self->add (0, $row, $item->{face_widget}); + $self->add (1, $row, $item->{desc_widget}); + $self->add (2, $row, $item->{weight_widget}); $row++; } @@ -3475,214 +3501,6 @@ ############################################################################# -package CFClient::UI::BindEditor; - -our @ISA = CFClient::UI::FancyFrame::; - -sub new { - my $class = shift; - - my $self = $class->SUPER::new (binding => [], commands => [], @_); - - $self->add (my $vb = new CFClient::UI::VBox); - - - $vb->add ($self->{rec_btn} = new CFClient::UI::Button - text => "start recording", - tooltip => "Start/Stops recording of actions." - ."All subsequent actions after the recording started will be captured." - ."The actions are displayed after the record was stopped." - ."To bind the action you have to click on the 'Bind' button", - on_activate => sub { - unless ($self->{recording}) { - $self->start; - } else { - $self->stop; - } - }); - - $vb->add (new CFClient::UI::Label text => "Actions:"); - $vb->add ($self->{cmdbox} = new CFClient::UI::VBox); - - $vb->add (new CFClient::UI::Label text => "Bound to: "); - $vb->add (my $hb = new CFClient::UI::HBox); - $hb->add ($self->{keylbl} = new CFClient::UI::Label expand => 1); - $hb->add (new CFClient::UI::Button - text => "bind", - tooltip => "This opens a query where you have to press the key combination to bind the recorded actions", - on_activate => sub { - $self->ask_for_bind; - }); - - $vb->add (my $hb = new CFClient::UI::HBox); - $hb->add (new CFClient::UI::Button - text => "ok", - expand => 1, - tooltip => "This closes the binding editor and saves the binding", - on_activate => sub { - $self->hide; - $self->commit; - }); - - $hb->add (new CFClient::UI::Button - text => "cancel", - expand => 1, - tooltip => "This closes the binding editor without saving", - on_activate => sub { - $self->hide; - $self->{binding_cancel}->() - if $self->{binding_cancel}; - }); - - $self->update_binding_widgets; - - $self -} - -sub cfg_bind { - my ($self, $mod, $sym, $cmds) = @_; - $::CFG->{profile}{default}{bindings}{$mod}{$sym} = $cmds; - ::update_bindings (); -} - -sub cfg_unbind { - my ($self, $mod, $sym, $cmds) = @_; - delete $::CFG->{profile}{default}{bindings}{$mod}{$sym}; - ::update_bindings (); -} - -sub commit { - my ($self) = @_; - my ($mod, $sym, $cmds) = $self->get_binding; - if ($sym != 0 && @$cmds > 0) { - $::STATUSBOX->add ("Bound actions to '".CFClient::Binder::keycombo_to_name ($mod, $sym) - ."'. Don't forget 'Save Config'!"); - $self->{binding_change}->($mod, $sym, $cmds) - if $self->{binding_change}; - } else { - $::STATUSBOX->add ("No action bound, no key or action specified!"); - $self->{binding_cancel}->() - if $self->{binding_cancel}; - } -} - -sub start { - my ($self) = @_; - - $self->{rec_btn}->set_text ("stop recording"); - $self->{recording} = 1; - $self->clear_command_list; - $::CONN->start_record if $::CONN; -} - -sub stop { - my ($self) = @_; - - $self->{rec_btn}->set_text ("start recording"); - $self->{recording} = 0; - - my $rec; - $rec = $::CONN->stop_record if $::CONN; - return unless ref $rec eq 'ARRAY'; - $self->set_command_list ($rec); -} - - -sub ask_for_bind_and_commit { - my ($self) = @_; - $self->ask_for_bind (1); -} - -sub ask_for_bind { - my ($self, $commit, $end_cb) = @_; - - CFClient::Binder::open_binding_dialog (sub { - my ($mod, $sym) = @_; - $self->{binding} = [$mod, $sym]; # XXX: how to stop that memleak? - $self->update_binding_widgets; - $self->commit if $commit; - $end_cb->() if $end_cb; - }); -} - -# $mod and $sym are the modifiers and key symbol -# $cmds is a array ref of strings (the commands) -# $cb is the callback that is executed on OK -# $ccb is the callback that is executed on CANCEL and -# when the binding was unsuccessful on OK -sub set_binding { - my ($self, $mod, $sym, $cmds, $cb, $ccb) = @_; - - $self->clear_command_list; - $self->{recording} = 0; - $self->{rec_btn}->set_text ("start recording"); - - $self->{binding} = [$mod, $sym]; - $self->{commands} = $cmds; - - $self->{binding_change} = $cb; - $self->{binding_cancel} = $ccb; - - $self->update_binding_widgets; -} - -# this is a shortcut method that asks for a binding -# and then just binds it. -sub do_quick_binding { - my ($self, $cmds, $end_cb) = @_; - $self->set_binding (undef, undef, $cmds, sub { $self->cfg_bind (@_) }); - $self->ask_for_bind (1, $end_cb); -} - -sub update_binding_widgets { - my ($self) = @_; - my ($mod, $sym, $cmds) = $self->get_binding; - $self->{keylbl}->set_text (CFClient::Binder::keycombo_to_name ($mod, $sym)); - $self->set_command_list ($cmds); -} - -sub get_binding { - my ($self) = @_; - return ( - $self->{binding}->[0], - $self->{binding}->[1], - [ grep { defined $_ } @{$self->{commands}} ] - ); -} - -sub clear_command_list { - my ($self) = @_; - $self->{cmdbox}->clear (); -} - -sub set_command_list { - my ($self, $cmds) = @_; - - $self->{cmdbox}->clear (); - $self->{commands} = $cmds; - - my $idx = 0; - - for (@$cmds) { - $self->{cmdbox}->add (my $hb = new CFClient::UI::HBox); - - my $i = $idx; - $hb->add (new CFClient::UI::Label text => $_); - $hb->add (new CFClient::UI::Button - text => "delete", - tooltip => "Deletes the action from the record", - on_activate => sub { - $self->{cmdbox}->remove ($hb); - $cmds->[$i] = undef; - }); - - - $idx++ - } -} - -############################################################################# - package CFClient::UI::SpellList; our @ISA = CFClient::UI::Table::; @@ -3741,7 +3559,7 @@ } elsif ($ev->{button} == 3) { (new CFClient::UI::Menu items => [ - ["bind cast $spell->{name} to a key" => sub { $::BIND_EDITOR->do_quick_binding (["cast $spell->{name}"]) }], + ["bind cast $spell->{name} to a key" => sub { $::BIND_EDITOR->do_quick_binding (["cast $spell->{name}"]) }], ["bind invoke $spell->{name} to a key" => sub { $::BIND_EDITOR->do_quick_binding (["invoke $spell->{name}"]) }], ], )->popup ($ev);