ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI/Dockbar.pm
Revision: 1.7
Committed: Wed Oct 29 16:02:10 2008 UTC (15 years, 9 months ago) by elmex
Branch: MAIN
CVS Tags: rel-0_9978
Changes since 1.6: +2 -1 lines
Log Message:
fixed Alt-x tab closing problem.

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 elmex 1.1 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 root 1.3 # switching to a page
176 elmex 1.1 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 elmex 1.7 my $curdock = $self->{notebook}->get_current_page;
203     $curdock->emit ('close_dock');
204 elmex 1.1 }
205    
206     # "activates" the current page
207     sub activate_current {
208     my ($self) = @_;
209     $self->{notebook}->get_current_page->activate
210     }
211    
212     1