ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI/Dockbar.pm
Revision: 1.1
Committed: Sun Jan 6 16:28:49 2008 UTC (16 years, 6 months ago) by elmex
Branch: MAIN
Log Message:
committed the big Dockbar patch.

File Contents

# User Rev Content
1 elmex 1.1 package DC::UI::Dockbar;
2     use DC::UI::Dockable;
3    
4     use strict;
5     use utf8;
6    
7     our @ISA = DC::UI::Toplevel::;
8    
9     sub new {
10     my $class = shift;
11    
12     my $self = $class->SUPER::new (
13     name => "message_window2",
14     title => "Messages XXX",
15     border_bg => [1, 1, 1, 1],
16     x => "max",
17     y => 20,
18     force_w => $::WIDTH * 0.4,
19     force_h => $::HEIGHT * 0.5,
20     has_close_button => 1,
21    
22     child => (my $nb = DC::UI::Notebook->new (expand => 1)),
23     @_,
24     );
25    
26     $self->{notebook} = $nb;
27    
28     $nb->connect (page_changed => sub {
29     my ($nb, $page) = @_;
30     $self->update_active ($page);
31     0
32     });
33    
34     $self
35     }
36    
37     # This method is which you want to call to add a Dockable
38     sub add_dock {
39     my ($self, $dockable) = @_;
40     $self->{docks}->{"$dockable"} = $dockable;
41     delete $self->{dock_windows}->{"$dockable"};
42    
43     $dockable->set_dockbar ($self);
44    
45     # TODO: capture the guards to remove these connections
46     $dockable->connect (dock => sub {
47     my ($dockable) = @_;
48     #d# warn "DOCKABLE DOCK";
49     $self->dock ($dockable);
50     0
51     });
52    
53     $dockable->connect (undock => sub {
54     my ($dockable) = @_;
55     #d# warn "DOCKABLE UNDOCK";
56     $self->undock ($dockable);
57     0
58     });
59    
60     $dockable->connect (close_dock => sub {
61     my ($dockable) = @_;
62     $self->remove_dock ($dockable);
63     0
64     });
65    
66     $self->dock ($dockable);
67     }
68    
69     # This method will remove the dockable from the Dockbar. Which means that the
70     # window for this dockable is also removed (if it was undocked).
71     sub remove_dock {
72     my ($self, $dockable) = @_;
73    
74     $self->undock_window ($dockable);
75     $self->undock_notebook ($dockable);
76     delete $self->{docks}->{"$dockable"};
77     $dockable->set_dockbar (undef);
78     }
79    
80     # This method makes sure the dockable is 'docked' into the Dockbar
81     # and eg. removes the free floating window it maybe has.
82     sub dock {
83     my ($self, $dockable) = @_;
84     $self->undock_window ($dockable);
85    
86     # here the assumption is done that $dockable is inserted at the end of the
87     # notebook tabs, so that the other tabs dont have to be updated
88     $self->{notebook}->add ($dockable);
89     $dockable->set_dockbar_pos ($self->{notebook}->page_index ($dockable));
90     $self->update_active;
91     }
92    
93     # (private) This method updates all docked tabs and tells them whether their
94     # tab is 'active'.
95     sub update_active {
96     my ($self, $page) = @_;
97    
98     unless ($page) {
99     $page = $self->{notebook}->get_current_page;
100     }
101    
102     for ($self->{notebook}->pages) {
103     $_->set_dockbar_tab_active ($_ eq $page);
104     }
105     }
106    
107     # This method undocks the dockable (if it isn't already undocked) and
108     # creates a floating window for it.
109     sub undock {
110     my ($self, $dockable) = @_;
111     return if $self->{dock_windows}->{"$dockable"};
112    
113     $self->undock_notebook ($dockable);
114     my $win =
115     $self->{dock_windows}->{"$dockable"} =
116     DC::UI::Toplevel->new (
117     title => $dockable->get_title,
118     child => $dockable,
119     force_w => 100, force_h => 100,
120     x => 100, y => 100,
121     has_close_button => 1,
122     );
123    
124     $win->connect (delete => sub {
125     $self->dock ($dockable);
126     0
127     });
128    
129     $win->show;
130     }
131    
132     # (private) This method does the cleanup stuff when the dockable is docked
133     # into the dockbar and had a floating window.
134     sub undock_window {
135     my ($self, $dockable) = @_;
136     my $win =
137     $self->{dock_windows}->{"$dockable"}
138     or return;
139    
140     $win->remove ($dockable);
141     delete $self->{dock_windows}->{"$dockable"};
142     $win->hide; # XXX: neccessary?
143     }
144    
145     # (private) This method does the cleanup stuff which is neccessary when the
146     # dockable is removed from the notebook.
147     sub undock_notebook {
148     my ($self, $dockable) = @_;
149     $self->{notebook}->remove ($dockable);
150     my $nextpage = ($self->{notebook}->pages)[0];
151     $self->{notebook}->set_current_page ($nextpage)
152     if $nextpage;
153     $dockable->set_dockbar_pos (undef);
154     $dockable->set_dockbar_tab_active (undef);
155     $self->update_dockbar_positions;
156     }
157    
158     # (private) This method updates the position of the dockables in the dockbar.
159     sub update_dockbar_positions {
160     my ($self) = @_;
161     my $i = 0;
162     for ($self->{notebook}->pages) {
163     $_->set_dockbar_pos ($i++);
164     }
165     }
166    
167     # Returns all Dockables of this Dockbar
168     sub dockables {
169     my ($self) = @_;
170     values %{$self->{docks}}
171     }
172    
173     # Returns whether the dockable is currently docked. (and not
174     # a floating window).
175     sub is_docked {
176     my ($self, $dockable) = @_;
177     return not exists $self->{dock_windows}->{"$dockable"};
178     }
179    
180     # switiching to a page
181     sub user_switch_to_page {
182     my ($self, $page) = @_;
183     $page = $page eq '0' ? 10 : $page;
184    
185     my @tabs = $self->{notebook}->pages;
186    
187     for (my $i = 0; $i < ($page - 1); $i++) {
188     shift @tabs;
189     }
190    
191     my $page = shift @tabs;
192     return unless $page;
193    
194     $self->{notebook}->set_current_page ($page);
195     }
196    
197     # This method activates the tab of the dockable if it is docked.
198     sub select_dockable {
199     my ($self, $dockable) = @_;
200     return unless exists $self->{docks}->{"$dockable"};
201     $self->{notebook}->set_current_page ($dockable);
202     }
203    
204     # close current tab
205     sub close_current_tab {
206     my ($self) = @_;
207     $self->remove_dock ($self->{notebook}->get_current_page);
208     }
209    
210     # "activates" the current page
211     sub activate_current {
212     my ($self) = @_;
213     $self->{notebook}->get_current_page->activate
214     }
215    
216     1