--- deliantra/Deliantra-Client/DC/UI/Dockable.pm 2007/12/26 21:03:21 1.3 +++ deliantra/Deliantra-Client/DC/UI/Dockable.pm 2008/01/06 16:28:49 1.4 @@ -5,16 +5,178 @@ our @ISA = DC::UI::Bin::; + +# A dockable can be docked into a DC::UI::Dockbar +# Attributes: +# 'can_close' says: This dockable has a close button as tab. +# 'can_undock' says that the dockable tab has a 'undock' button. +# 'title' is the title of the tab label or the title of the undocket window + sub new { my $class = shift; my $self = $class->SUPER::new ( - title => "unset", - can_close => 1, + title => "unset", + can_close => 1, + can_undock => 0, # temporarily deactivated! @_, ); + $self->init; + $self } +# a setup method for the constructor +sub init { + my ($self) = @_; + + my $bb = $self->{c_tab} = DC::UI::ButtonBin->new (tooltip => $self->{tooltip}); + $bb->add (my $vb = DC::UI::Box->new); + $vb->add ( + my $b = + $self->{tab_label} = + DC::UI::Label->new (expand => 1, valign => 0, align => 0) + ); + + if ($self->{can_close}) { + $vb->add ( + my $ib = DC::UI::ImageButton->new (path => 'x1_close.png', scale => 0.3) + ); + $ib->connect (activate => sub { + $self->close; + 0 + }); + } + + if ($self->{can_undock}) { + $vb->add ( + my $ib2 = DC::UI::ImageButton->new (path => 'x1_close.png', scale => 0.3) + ); + $ib2->connect (activate => sub { + $self->emit ("undock"); + 0 + }); + } + + + $self->set_title ($self->{title}); +} + +# This sets the title of the dockable. The title is displayed +sub set_title { + my ($self, $title) = @_; + $self->{title} = $title; + $self->update_tab; +} + +# Returns the title +sub get_title { $_[0]->{title} } + +# This method activates the tab of the dockable if it is docked +sub select_my_tab { + my ($self) = @_; + if ($self->is_docked) { + $self->{dockbar}->select_dockable ($self); + } +} + +# (private) This method is used by Dockbar to tell the dockable +# it's position in the dockbar (if it has one, if it has no position, +# $pos is undef). +sub set_dockbar_pos { + my ($self, $pos) = @_; + $self->{dockbar_pos} = $pos; + $self->update_tab; +} + +# (private) This method tells the dockable that it is 'active', which means: +# it is docked and it's tab has been activated and it is currently shown. +sub set_dockbar_tab_active { + my ($self, $active) = @_; + $self->{dockbar_active} = $active; + $self->update_tab; +} + +# (private) This method updates the tab and other things of the dockable +# whenever something has been changed (title, color, ...) +sub update_tab { + my ($self) = @_; + # TODO: set color according to dockbar_active + + my $oldcolor = $self->{tab_label}->{fg}; + if ($self->is_docked_active) { + $self->{tab_label}->{fg} = $self->{active_fg} || [1, 1, 1]; + } else { + $self->{tab_label}->{fg} = $self->{inactive_fg} || [1, 1, 1,]; + } + if (join (',', @$oldcolor) ne join (',', @{$self->{tab_label}->{fg}})) { + # update colors + $self->{tab_label}->realloc; + $self->{tab_label}->update; + } + + $self->{tab_label}->set_markup ( + $self->get_title + . (defined $self->{dockbar_pos} + ? "-" . ($self->{dockbar_pos} + 1) + : "") + ); +} + +# This method sets the active foreground color of the dockable tab +sub set_active_fg { + my ($self, $fg) = @_; + $self->{active_fg} = $fg; + $self->update_tab; +} + +# This method sets the inactive foreground color of the dockable tab +sub set_inactive_fg { + my ($self, $fg) = @_; + $self->{inactive_fg} = $fg; + $self->update_tab; +} + +# (private) This method is used by the Dockbar to tell the Dockable which +# Dockbar it belongs to. Do not call this method yourself, use the dockbars +# add_dock and remove_dock methods instead. +sub set_dockbar { + my ($self, $dockbar) = @_; + $self->{dockbar} = $dockbar; + Scalar::Util::weaken $self->{dockbar}; +} + +# This method is called when someone wants to 'activate' the dockable, +# the meaning of being 'activated' is given by subclasses that inherit +# from Dockable. Eg. In ChatView the 'activation' means that the entry field +# of for chat is activated for input. +sub activate { + my ($self) = @_; + $self->emit ("activate"); +} + +# Returns whether this dockable is docked on a Dockbar. +sub is_docked { + my ($self) = @_; + $self->{dockbar} or return 0; + return $self->{dockbar}->is_docked ($self); +} + +# Returns whether this dockable is docked _and_ it's tab +# is active. +sub is_docked_active { + my ($self) = @_; + $self->{dockbar} or return 0; + return $self->{dockbar_active}; +} + +# This method is called when the Dockable wants to be closed, which means +# that it's window is closed or tab is removed from the dockbar and it +# is removed from the dockbar. +sub close { + my ($self) = @_; + $self->emit ("close_dock"); +} + 1