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