ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI/Dockbar.pm
Revision: 1.6
Committed: Mon May 5 20:22:03 2008 UTC (16 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-0_9972, rel-0_9973, rel-0_9974, rel-0_9975, rel-0_9976, rel-0_9977, rel-0_9971, rel-1_21
Changes since 1.5: +0 -2 lines
Log Message:
*** empty log message ***

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