OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/panels/docked_panel_strip.h" | 5 #include "chrome/browser/ui/panels/docked_panel_strip.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 const int DockedPanelStrip::kPanelMinHeight = 20; | 55 const int DockedPanelStrip::kPanelMinHeight = 20; |
56 | 56 |
57 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) | 57 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
58 : PanelStrip(PanelStrip::DOCKED), | 58 : PanelStrip(PanelStrip::DOCKED), |
59 panel_manager_(panel_manager), | 59 panel_manager_(panel_manager), |
60 minimized_panel_count_(0), | 60 minimized_panel_count_(0), |
61 are_titlebars_up_(false), | 61 are_titlebars_up_(false), |
62 disable_layout_refresh_(false), | 62 disable_layout_refresh_(false), |
63 delayed_titlebar_action_(NO_ACTION), | 63 delayed_titlebar_action_(NO_ACTION), |
64 titlebar_action_factory_(this) { | 64 titlebar_action_factory_(this) { |
65 dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = | 65 dragging_panel_current_iterator_ = panels_.end(); |
66 panels_.end(); | |
67 } | 66 } |
68 | 67 |
69 DockedPanelStrip::~DockedPanelStrip() { | 68 DockedPanelStrip::~DockedPanelStrip() { |
70 DCHECK(panels_.empty()); | 69 DCHECK(panels_.empty()); |
71 DCHECK(panels_in_temporary_layout_.empty()); | 70 DCHECK(panels_in_temporary_layout_.empty()); |
72 DCHECK_EQ(0, minimized_panel_count_); | 71 DCHECK_EQ(0, minimized_panel_count_); |
73 } | 72 } |
74 | 73 |
75 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) { | 74 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) { |
76 if (display_area_ == display_area) | 75 if (display_area_ == display_area) |
(...skipping 16 matching lines...) Expand all Loading... | |
93 int max_panel_width = GetMaxPanelWidth(); | 92 int max_panel_width = GetMaxPanelWidth(); |
94 int max_panel_height = GetMaxPanelHeight(); | 93 int max_panel_height = GetMaxPanelHeight(); |
95 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), | 94 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), |
96 gfx::Size(max_panel_width, max_panel_height)); | 95 gfx::Size(max_panel_width, max_panel_height)); |
97 | 96 |
98 gfx::Size restored_size = panel->restored_size(); | 97 gfx::Size restored_size = panel->restored_size(); |
99 int height = restored_size.height(); | 98 int height = restored_size.height(); |
100 int width = restored_size.width(); | 99 int width = restored_size.width(); |
101 | 100 |
102 if (panel->initialized()) { | 101 if (panel->initialized()) { |
103 // Bump panels in the strip to make room for this panel. | 102 // Make sure we have sufficient space for this panel. We might bump |
104 // Prevent layout refresh when panel is removed from this strip. | 103 // panels in the strip to make room for this panel. |
105 disable_layout_refresh_ = true; | 104 EnsureAvailableSpace(width); |
106 PanelStrip* overflow_strip = panel_manager_->overflow_strip(); | 105 int x = GetRightMostAvailablePosition() - width; |
107 int x; | |
108 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { | |
109 DCHECK(!panels_.empty()); | |
110 panels_.back()->MoveToStrip(overflow_strip); | |
111 } | |
112 disable_layout_refresh_ = false; | |
113 | 106 |
114 Panel::ExpansionState expansion_state_to_restore; | 107 Panel::ExpansionState expansion_state_to_restore; |
115 if (panel->expansion_state() == Panel::EXPANDED) { | 108 if (panel->expansion_state() == Panel::EXPANDED) { |
116 expansion_state_to_restore = Panel::EXPANDED; | 109 expansion_state_to_restore = Panel::EXPANDED; |
117 } else { | 110 } else { |
118 if (are_titlebars_up_ || panel->IsDrawingAttention()) { | 111 if (are_titlebars_up_ || panel->IsDrawingAttention()) { |
119 expansion_state_to_restore = Panel::TITLE_ONLY; | 112 expansion_state_to_restore = Panel::TITLE_ONLY; |
120 height = panel->TitleOnlyHeight(); | 113 height = panel->TitleOnlyHeight(); |
121 } else { | 114 } else { |
122 expansion_state_to_restore = Panel::MINIMIZED; | 115 expansion_state_to_restore = Panel::MINIMIZED; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 FROM_HERE, | 163 FROM_HERE, |
171 base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, | 164 base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, |
172 base::Unretained(this), | 165 base::Unretained(this), |
173 panel), | 166 panel), |
174 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( | 167 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( |
175 kMoveNewPanelToOverflowDelayMs))); | 168 kMoveNewPanelToOverflowDelayMs))); |
176 } | 169 } |
177 panel->Initialize(gfx::Rect(x, y, width, height)); | 170 panel->Initialize(gfx::Rect(x, y, width, height)); |
178 } | 171 } |
179 | 172 |
180 // Set panel properties for this strip. | 173 // Insert the panel to the end. |
174 InsertPanelToCollection(panel, panels_.end()); | |
jennb
2012/03/03 02:19:33
Don't refactor out the insertion logic as no other
jianli
2012/03/07 19:14:31
Done. Added OnPanelAdded.
| |
175 } | |
176 | |
177 void DockedPanelStrip::InsertPanelToCollection( | |
178 Panel* panel, Panels::iterator position) { | |
181 panel->SetAppIconVisibility(true); | 179 panel->SetAppIconVisibility(true); |
180 panel->SetAlwaysOnTop(true); | |
182 | 181 |
183 if (panel->has_temporary_layout()) | 182 if (panel->has_temporary_layout()) |
184 panels_in_temporary_layout_.insert(panel); | 183 panels_in_temporary_layout_.insert(panel); |
185 else | 184 else |
186 panels_.push_back(panel); | 185 panels_.insert(position, panel); |
186 } | |
187 | |
188 void DockedPanelStrip::EnsureAvailableSpace(int width) { | |
189 // Prevent layout refresh when panel is removed from this strip. | |
190 disable_layout_refresh_ = true; | |
191 PanelStrip* overflow_strip = panel_manager_->overflow_strip(); | |
192 int x; | |
193 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { | |
194 DCHECK(!panels_.empty()); | |
195 panels_.back()->MoveToStrip(overflow_strip); | |
196 } | |
197 disable_layout_refresh_ = false; | |
187 } | 198 } |
188 | 199 |
189 int DockedPanelStrip::GetMaxPanelWidth() const { | 200 int DockedPanelStrip::GetMaxPanelWidth() const { |
190 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); | 201 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
191 } | 202 } |
192 | 203 |
193 int DockedPanelStrip::GetMaxPanelHeight() const { | 204 int DockedPanelStrip::GetMaxPanelHeight() const { |
194 return display_area_.height(); | 205 return display_area_.height(); |
195 } | 206 } |
196 | 207 |
(...skipping 13 matching lines...) Expand all Loading... | |
210 } | 221 } |
211 | 222 |
212 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 223 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
213 if (iter == panels_.end()) | 224 if (iter == panels_.end()) |
214 return false; | 225 return false; |
215 | 226 |
216 if (panel->expansion_state() != Panel::EXPANDED) | 227 if (panel->expansion_state() != Panel::EXPANDED) |
217 DecrementMinimizedPanels(); | 228 DecrementMinimizedPanels(); |
218 | 229 |
219 // Removing an element from the list will invalidate the iterator that refers | 230 // Removing an element from the list will invalidate the iterator that refers |
220 // to it. So we need to check if the dragging panel iterators are affected. | 231 // to it. If the dragging panel is being removed, set the dragging iterator to |
221 bool update_original_dragging_iterator_after_erase = false; | 232 // the end of the list. |
222 if (dragging_panel_original_iterator_ != panels_.end()) { | 233 if (dragging_panel_current_iterator_ == iter) |
223 if (dragging_panel_current_iterator_ == iter) { | 234 dragging_panel_current_iterator_ = panels_.end(); |
224 // If the dragging panel is being removed, set both dragging iterators to | |
225 // the end of the list. | |
226 dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = | |
227 panels_.end(); | |
228 } else if (dragging_panel_original_iterator_ == iter) { | |
229 // If |dragging_panel_original_iterator_| refers to the element being | |
230 // removed, set the flag so that the iterator can be updated to next | |
231 // element. | |
232 update_original_dragging_iterator_after_erase = true; | |
233 } | |
234 } | |
235 | 235 |
236 iter = panels_.erase(iter); | 236 iter = panels_.erase(iter); |
237 | 237 |
238 if (update_original_dragging_iterator_after_erase) | 238 // Update the saved panel placement if needed. This is because we might remove |
239 dragging_panel_original_iterator_ = iter; | 239 // |saved_panel_placement_.panel_to_place_before_|. |
240 if (saved_panel_placement_.panel && | |
241 saved_panel_placement_.panel_to_place_before_ == panel) { | |
242 saved_panel_placement_.panel_to_place_before_ = | |
243 (iter == panels_.end()) ? NULL : *iter; | |
244 } | |
240 | 245 |
241 if (!disable_layout_refresh_) | 246 if (!disable_layout_refresh_) |
242 RefreshLayout(); | 247 RefreshLayout(); |
243 | 248 |
244 return true; | 249 return true; |
245 } | 250 } |
246 | 251 |
247 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { | 252 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { |
248 // Panels with temporary layout cannot be shown as active. | 253 // Panels with temporary layout cannot be shown as active. |
249 return !panel->has_temporary_layout(); | 254 return !panel->has_temporary_layout(); |
250 } | 255 } |
251 | 256 |
257 void DockedPanelStrip::SavePanelPlacement(Panel* panel) { | |
258 DCHECK(!saved_panel_placement_.panel); | |
259 | |
260 saved_panel_placement_.panel = panel; | |
261 | |
262 // To recover panel to its original placement, we only need to track the panel | |
263 // that is placed after it. | |
264 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | |
265 DCHECK(iter != panels_.end()); | |
266 ++iter; | |
267 saved_panel_placement_.panel_to_place_before_ = | |
268 (iter == panels_.end()) ? NULL : *iter; | |
269 } | |
270 | |
271 void DockedPanelStrip::LoadSavedPanelPlacement() { | |
272 DCHECK(saved_panel_placement_.panel); | |
273 | |
274 Panel* panel = saved_panel_placement_.panel; | |
275 saved_panel_placement_.panel = NULL; | |
jennb
2012/03/03 02:19:33
leave it and call Discard at end of this method.
jianli
2012/03/07 19:14:31
Done.
| |
276 | |
277 // Find next panel after this panel. | |
278 Panels::iterator iter = std::find(panels_.begin(), panels_.end(), panel); | |
279 DCHECK(iter != panels_.end()); | |
280 Panels::iterator next_iter = iter; | |
281 next_iter++; | |
282 Panel* next_panel = (next_iter == panels_.end()) ? NULL : *iter; | |
283 | |
284 // If this panel is already in the right position, nothing to do. | |
285 if (next_panel == saved_panel_placement_.panel_to_place_before_) | |
286 return; | |
287 | |
288 // Remove this panel from its current position. | |
289 panels_.erase(iter); | |
290 | |
291 // Insert this panel into its previous position. | |
292 if (saved_panel_placement_.panel_to_place_before_) { | |
293 Panels::iterator iter_to_insert_before = std::find(panels_.begin(), | |
294 panels_.end(), saved_panel_placement_.panel_to_place_before_); | |
295 DCHECK(iter_to_insert_before != panels_.end()); | |
296 panels_.insert(iter_to_insert_before, panel); | |
297 } else { | |
298 panels_.push_back(panel); | |
299 } | |
300 | |
301 // This will automatically update all affected panels due to the insertion. | |
302 RefreshLayout(); | |
303 } | |
304 | |
305 void DockedPanelStrip::DiscardSavedPanelPlacement() { | |
306 DCHECK(saved_panel_placement_.panel); | |
307 saved_panel_placement_.panel = NULL; | |
308 } | |
309 | |
252 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { | 310 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
253 // Only the panels having temporary layout can't be dragged. | 311 // Only the panels having temporary layout can't be dragged. |
254 return !panel->has_temporary_layout(); | 312 return !panel->has_temporary_layout(); |
255 } | 313 } |
256 | 314 |
257 Panel* DockedPanelStrip::dragging_panel() const { | 315 Panel* DockedPanelStrip::dragging_panel() const { |
258 return dragging_panel_current_iterator_ == panels_.end() ? NULL : | 316 return dragging_panel_current_iterator_ == panels_.end() ? NULL : |
259 *dragging_panel_current_iterator_; | 317 *dragging_panel_current_iterator_; |
260 } | 318 } |
261 | 319 |
262 void DockedPanelStrip::StartDraggingPanel(Panel* panel) { | 320 void DockedPanelStrip::StartDraggingPanelLocally(Panel* panel) { |
263 dragging_panel_current_iterator_ = | 321 dragging_panel_current_iterator_ = |
264 find(panels_.begin(), panels_.end(), panel); | 322 find(panels_.begin(), panels_.end(), panel); |
265 DCHECK(dragging_panel_current_iterator_ != panels_.end()); | 323 DCHECK(dragging_panel_current_iterator_ != panels_.end()); |
266 dragging_panel_original_iterator_ = dragging_panel_current_iterator_; | |
267 } | 324 } |
268 | 325 |
269 void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { | 326 void DockedPanelStrip::DragPanelLocally(Panel* panel, |
327 int delta_x, | |
328 int delta_y) { | |
329 DCHECK_EQ(dragging_panel(), panel); | |
270 if (!delta_x) | 330 if (!delta_x) |
271 return; | 331 return; |
272 | 332 |
273 // Moves this panel to the dragging position. | 333 // Moves this panel to the dragging position. |
274 gfx::Rect new_bounds(panel->GetBounds()); | 334 gfx::Rect new_bounds(panel->GetBounds()); |
275 new_bounds.set_x(new_bounds.x() + delta_x); | 335 new_bounds.set_x(new_bounds.x() + delta_x); |
276 panel->SetPanelBounds(new_bounds); | 336 panel->SetPanelBounds(new_bounds); |
277 | 337 |
278 // Checks and processes other affected panels. | 338 // Checks and processes other affected panels. |
279 if (delta_x > 0) | 339 if (delta_x > 0) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 break; | 392 break; |
333 | 393 |
334 // Swaps the contents and makes |dragging_panel_current_iterator_| refers | 394 // Swaps the contents and makes |dragging_panel_current_iterator_| refers |
335 // to the new position. | 395 // to the new position. |
336 *dragging_panel_current_iterator_ = current_panel; | 396 *dragging_panel_current_iterator_ = current_panel; |
337 *current_panel_iterator = dragging_panel; | 397 *current_panel_iterator = dragging_panel; |
338 dragging_panel_current_iterator_ = current_panel_iterator; | 398 dragging_panel_current_iterator_ = current_panel_iterator; |
339 } | 399 } |
340 } | 400 } |
341 | 401 |
342 void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { | 402 void DockedPanelStrip::EndDraggingPanelLocally(Panel* panel, bool cancelled) { |
343 if (cancelled) { | 403 DCHECK_EQ(dragging_panel(), panel); |
344 if (dragging_panel_current_iterator_ != dragging_panel_original_iterator_) { | |
345 // Find out if the dragging panel should be moved toward the end/beginning | |
346 // of the list. | |
347 bool move_towards_end_of_list = true; | |
348 for (Panels::iterator iter = dragging_panel_original_iterator_; | |
349 iter != panels_.end(); ++iter) { | |
350 if (iter == dragging_panel_current_iterator_) { | |
351 move_towards_end_of_list = false; | |
352 break; | |
353 } | |
354 } | |
355 | 404 |
356 // Move the dragging panel back to its original position by swapping it | 405 dragging_panel_current_iterator_ = panels_.end(); |
357 // with its adjacent element until it reach its original position. | 406 |
358 while (dragging_panel_current_iterator_ != | 407 // If the drag is cancelled, we don't want to move the dragging panel to the |
jennb
2012/03/03 02:19:33
Maybe explain a bit about what is expected to happ
jianli
2012/03/07 19:14:31
Done.
| |
359 dragging_panel_original_iterator_) { | 408 // finalized position. |
360 Panels::iterator next_iter = dragging_panel_current_iterator_; | 409 if (!cancelled) |
361 if (move_towards_end_of_list) | 410 RefreshLayout(); |
362 ++next_iter; | 411 } |
363 else | 412 |
364 --next_iter; | 413 void DockedPanelStrip::AddDraggingPanel(Panel* panel, |
365 iter_swap(dragging_panel_current_iterator_, next_iter); | 414 const gfx::Point& position) { |
366 dragging_panel_current_iterator_ = next_iter; | 415 DCHECK_NE(this, panel->panel_strip()); |
367 } | 416 panel->set_panel_strip(this); |
368 } | 417 |
418 gfx::Rect new_bounds(panel->GetBounds()); | |
419 new_bounds.set_origin(position); | |
420 panel->SetPanelBounds(new_bounds); | |
421 | |
422 EnsureAvailableSpace(panel->GetBounds().width()); | |
423 | |
424 int x = panel->GetBounds().x(); | |
425 Panels::iterator iter = panels_.begin(); | |
426 for (; iter != panels_.end(); ++iter) { | |
427 Panel* current_panel = *iter; | |
jennb
2012/03/03 02:19:33
I was confusing current_panel with the panel you'r
jianli
2012/03/07 19:14:31
Dropped the temporary vars.
| |
428 gfx::Rect current_bounds = current_panel->GetBounds(); | |
429 if (x > current_bounds.x()) | |
430 break; | |
369 } | 431 } |
432 InsertPanelToCollection(panel, iter); | |
370 | 433 |
371 dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = | 434 StartDraggingPanelLocally(panel); |
372 panels_.end(); | |
373 | 435 |
436 // This will automatically update all affected panels due to the insertion. | |
374 RefreshLayout(); | 437 RefreshLayout(); |
375 } | 438 } |
376 | 439 |
377 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { | 440 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { |
378 gfx::Size size = panel->restored_size(); | 441 gfx::Size size = panel->restored_size(); |
379 Panel::ExpansionState expansion_state = panel->expansion_state(); | 442 Panel::ExpansionState expansion_state = panel->expansion_state(); |
380 Panel::ExpansionState old_state = panel->old_expansion_state(); | 443 Panel::ExpansionState old_state = panel->old_expansion_state(); |
381 switch (expansion_state) { | 444 switch (expansion_state) { |
382 case Panel::EXPANDED: | 445 case Panel::EXPANDED: |
383 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) | 446 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
747 DCHECK(panels_in_temporary_layout_.empty()); | 810 DCHECK(panels_in_temporary_layout_.empty()); |
748 | 811 |
749 // Make a copy of the iterator as closing panels can modify the vector. | 812 // Make a copy of the iterator as closing panels can modify the vector. |
750 Panels panels_copy = panels_; | 813 Panels panels_copy = panels_; |
751 | 814 |
752 // Start from the bottom to avoid reshuffling. | 815 // Start from the bottom to avoid reshuffling. |
753 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 816 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
754 iter != panels_copy.rend(); ++iter) | 817 iter != panels_copy.rend(); ++iter) |
755 (*iter)->Close(); | 818 (*iter)->Close(); |
756 } | 819 } |
OLD | NEW |