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

# User Rev Content
1 elmex 1.1 package DC::UI::Dockbar;
2 root 1.3
3 elmex 1.1 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 elmex 1.2 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 elmex 1.1 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 root 1.3 # switching to a page
178 elmex 1.1 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