ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI/Dockbar.pm
Revision: 1.4
Committed: Sun Jan 13 10:37:42 2008 UTC (16 years, 5 months ago) by elmex
Branch: MAIN
CVS Tags: rel-0_9965, rel-0_9964, rel-0_9968, rel-0_9967, rel-0_9966
Changes since 1.3: +0 -2 lines
Log Message:
removed redundant names

File Contents

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