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/panel_strip.h" | 5 #include "chrome/browser/ui/panels/panel_strip.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 gfx::Rect old_area = display_area_; | 74 gfx::Rect old_area = display_area_; |
75 display_area_ = new_area; | 75 display_area_ = new_area; |
76 | 76 |
77 if (panels_.empty()) | 77 if (panels_.empty()) |
78 return; | 78 return; |
79 | 79 |
80 Rearrange(); | 80 Rearrange(); |
81 } | 81 } |
82 | 82 |
83 void PanelStrip::AddPanel(Panel* panel) { | 83 void PanelStrip::AddPanel(Panel* panel) { |
84 DCHECK_NE(Panel::IN_OVERFLOW, panel->expansion_state()); | 84 DCHECK_NE(Panel::IN_OVERFLOW, panel->layout_state()); |
85 | 85 |
86 // Always update limits, even for exiting panels, in case the maximums changed | 86 // Always update limits, even for exiting panels, in case the maximums changed |
87 // while panel was out of the strip. | 87 // while panel was out of the strip. |
88 int max_panel_width = GetMaxPanelWidth(); | 88 int max_panel_width = GetMaxPanelWidth(); |
89 int max_panel_height = GetMaxPanelHeight(); | 89 int max_panel_height = GetMaxPanelHeight(); |
90 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), | 90 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), |
91 gfx::Size(max_panel_width, max_panel_height)); | 91 gfx::Size(max_panel_width, max_panel_height)); |
92 | 92 |
93 gfx::Size restored_size = panel->restored_size(); | 93 gfx::Size restored_size = panel->restored_size(); |
94 int height = restored_size.height(); | 94 int height = restored_size.height(); |
95 int width = restored_size.width(); | 95 int width = restored_size.width(); |
96 | 96 |
97 if (panel->initialized()) { | 97 if (panel->initialized()) { |
98 // Bump panels in the strip to make room for this panel. | 98 // Bump panels in the strip to make room for this panel. |
99 int x; | 99 int x; |
100 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { | 100 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { |
101 DCHECK(!panels_.empty()); | 101 DCHECK(!panels_.empty()); |
102 panels_.back()->SetExpansionState(Panel::IN_OVERFLOW); | 102 panels_.back()->SetLayoutState(Panel::IN_OVERFLOW); |
103 } | 103 } |
104 int y = display_area_.bottom() - height; | 104 int y = display_area_.bottom() - height; |
105 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | 105 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
| 106 |
| 107 if (panel->expansion_state() != Panel::EXPANDED) |
| 108 IncrementMinimizedPanels(); |
106 } else { | 109 } else { |
107 // Initialize the newly created panel. Does not bump any panels from strip. | 110 // Initialize the newly created panel. Does not bump any panels from strip. |
108 if (height == 0 && width == 0) { | 111 if (height == 0 && width == 0) { |
109 // Auto resizable is enabled only if no initial size is provided. | 112 // Auto resizable is enabled only if no initial size is provided. |
110 panel->SetAutoResizable(true); | 113 panel->SetAutoResizable(true); |
111 } else { | 114 } else { |
112 if (height == 0) | 115 if (height == 0) |
113 height = width / kPanelDefaultWidthToHeightRatio; | 116 height = width / kPanelDefaultWidthToHeightRatio; |
114 if (width == 0) | 117 if (width == 0) |
115 width = height * kPanelDefaultWidthToHeightRatio; | 118 width = height * kPanelDefaultWidthToHeightRatio; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // If we're in the process of dragging, delay the removal. | 189 // If we're in the process of dragging, delay the removal. |
187 if (dragging_panel_index_ != kInvalidPanelIndex) { | 190 if (dragging_panel_index_ != kInvalidPanelIndex) { |
188 panels_pending_to_remove_.push_back(panel); | 191 panels_pending_to_remove_.push_back(panel); |
189 return true; | 192 return true; |
190 } | 193 } |
191 | 194 |
192 DoRemove(panel); | 195 DoRemove(panel); |
193 | 196 |
194 // Don't rearrange the strip if a panel is being moved from the panel strip | 197 // Don't rearrange the strip if a panel is being moved from the panel strip |
195 // to the overflow strip. | 198 // to the overflow strip. |
196 if (panel->expansion_state() != Panel::IN_OVERFLOW) | 199 if (panel->layout_state() == Panel::DOCKED) |
197 Rearrange(); | 200 Rearrange(); |
198 | 201 |
199 return true; | 202 return true; |
200 } | 203 } |
201 | 204 |
202 void PanelStrip::DelayedRemove() { | 205 void PanelStrip::DelayedRemove() { |
203 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) | 206 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) |
204 DoRemove(panels_pending_to_remove_[i]); | 207 DoRemove(panels_pending_to_remove_[i]); |
205 panels_pending_to_remove_.clear(); | 208 panels_pending_to_remove_.clear(); |
206 Rearrange(); | 209 Rearrange(); |
207 } | 210 } |
208 | 211 |
209 bool PanelStrip::DoRemove(Panel* panel) { | 212 bool PanelStrip::DoRemove(Panel* panel) { |
210 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 213 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
211 if (iter == panels_.end()) | 214 if (iter == panels_.end()) |
212 return false; | 215 return false; |
213 | 216 |
214 if (panel->expansion_state() == Panel::TITLE_ONLY || | 217 if (panel->expansion_state() != Panel::EXPANDED) |
215 panel->expansion_state() == Panel::MINIMIZED) | |
216 DecrementMinimizedPanels(); | 218 DecrementMinimizedPanels(); |
217 | 219 |
218 panels_.erase(iter); | 220 panels_.erase(iter); |
219 panel_manager_->OnPanelRemoved(panel); | 221 panel_manager_->OnPanelRemoved(panel); |
220 return true; | 222 return true; |
221 } | 223 } |
222 | 224 |
223 void PanelStrip::StartDragging(Panel* panel) { | 225 void PanelStrip::StartDragging(Panel* panel) { |
224 for (size_t i = 0; i < panels_.size(); ++i) { | 226 for (size_t i = 0; i < panels_.size(); ++i) { |
225 if (panels_[i] == panel) { | 227 if (panels_[i] == panel) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 } else { | 346 } else { |
345 panels_[dragging_panel_index_]->SetPanelBounds( | 347 panels_[dragging_panel_index_]->SetPanelBounds( |
346 dragging_panel_bounds_); | 348 dragging_panel_bounds_); |
347 } | 349 } |
348 | 350 |
349 dragging_panel_index_ = kInvalidPanelIndex; | 351 dragging_panel_index_ = kInvalidPanelIndex; |
350 | 352 |
351 DelayedRemove(); | 353 DelayedRemove(); |
352 } | 354 } |
353 | 355 |
354 void PanelStrip::OnPanelExpansionStateChanged(Panel* panel) { | 356 void PanelStrip::OnPanelLayoutStateChanged(Panel* panel, |
| 357 Panel::LayoutState old_state) { |
| 358 Panel::LayoutState layout_state = panel->layout_state(); |
| 359 switch (layout_state) { |
| 360 case Panel::DOCKED: |
| 361 if (old_state == Panel::IN_OVERFLOW) { |
| 362 panel_manager_->panel_overflow_strip()->Remove(panel); |
| 363 AddPanel(panel); |
| 364 panel->SetAppIconVisibility(true); |
| 365 panel->set_draggable(true); |
| 366 UpdateBoundsPerExpansionState(panel); |
| 367 } |
| 368 break; |
| 369 case Panel::DETACHED: |
| 370 case Panel::IN_OVERFLOW: |
| 371 DCHECK_EQ(Panel::DOCKED, old_state); |
| 372 break; |
| 373 default: |
| 374 NOTREACHED(); |
| 375 break; |
| 376 } |
| 377 } |
| 378 |
| 379 void PanelStrip::OnPanelExpansionStateChanged(Panel* panel, |
| 380 Panel::ExpansionState old_state) { |
| 381 DCHECK_EQ(Panel::DOCKED, panel->layout_state()); |
| 382 |
| 383 switch (panel->expansion_state()) { |
| 384 case Panel::EXPANDED: |
| 385 DecrementMinimizedPanels(); |
| 386 break; |
| 387 case Panel::TITLE_ONLY: |
| 388 case Panel::MINIMIZED: |
| 389 if (old_state == Panel::EXPANDED) |
| 390 IncrementMinimizedPanels(); |
| 391 break; |
| 392 default: |
| 393 NOTREACHED(); |
| 394 break; |
| 395 } |
| 396 |
| 397 UpdateBoundsPerExpansionState(panel); |
| 398 } |
| 399 |
| 400 void PanelStrip::UpdateBoundsPerExpansionState(Panel* panel) { |
355 gfx::Size size = panel->restored_size(); | 401 gfx::Size size = panel->restored_size(); |
356 Panel::ExpansionState expansion_state = panel->expansion_state(); | 402 Panel::ExpansionState expansion_state = panel->expansion_state(); |
357 Panel::ExpansionState old_state = panel->old_expansion_state(); | |
358 if (old_state == Panel::IN_OVERFLOW) { | |
359 panel_manager_->panel_overflow_strip()->Remove(panel); | |
360 AddPanel(panel); | |
361 panel->SetAppIconVisibility(true); | |
362 panel->set_draggable(true); | |
363 } | |
364 switch (expansion_state) { | 403 switch (expansion_state) { |
365 case Panel::EXPANDED: | 404 case Panel::EXPANDED: |
366 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) | |
367 DecrementMinimizedPanels(); | |
368 break; | 405 break; |
369 case Panel::TITLE_ONLY: | 406 case Panel::TITLE_ONLY: |
370 size.set_height(panel->TitleOnlyHeight()); | 407 size.set_height(panel->TitleOnlyHeight()); |
371 if (old_state == Panel::EXPANDED || old_state == Panel::IN_OVERFLOW) | |
372 IncrementMinimizedPanels(); | |
373 break; | 408 break; |
374 case Panel::MINIMIZED: | 409 case Panel::MINIMIZED: |
375 size.set_height(Panel::kMinimizedPanelHeight); | 410 size.set_height(Panel::kMinimizedPanelHeight); |
376 if (old_state == Panel::EXPANDED || old_state == Panel::IN_OVERFLOW) | |
377 IncrementMinimizedPanels(); | |
378 break; | |
379 case Panel::IN_OVERFLOW: | |
380 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) | |
381 DecrementMinimizedPanels(); | |
382 break; | 411 break; |
383 default: | 412 default: |
384 NOTREACHED(); | 413 NOTREACHED(); |
385 break; | 414 break; |
386 } | 415 } |
387 | 416 |
388 int bottom = GetBottomPositionForExpansionState(expansion_state); | 417 int bottom = GetBottomPositionForExpansionState(expansion_state); |
389 gfx::Rect bounds = panel->GetBounds(); | 418 gfx::Rect bounds = panel->GetBounds(); |
390 panel->SetPanelBounds( | 419 panel->SetPanelBounds( |
391 gfx::Rect(bounds.right() - size.width(), | 420 gfx::Rect(bounds.right() - size.width(), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 if (new_height > panel->max_size().height()) | 453 if (new_height > panel->max_size().height()) |
425 new_height = panel->max_size().height(); | 454 new_height = panel->max_size().height(); |
426 if (new_height < panel->min_size().height()) | 455 if (new_height < panel->min_size().height()) |
427 new_height = panel->min_size().height(); | 456 new_height = panel->min_size().height(); |
428 | 457 |
429 // Update restored size. | 458 // Update restored size. |
430 gfx::Size new_size(new_width, new_height); | 459 gfx::Size new_size(new_width, new_height); |
431 if (new_size != panel->restored_size()) | 460 if (new_size != panel->restored_size()) |
432 panel->set_restored_size(new_size); | 461 panel->set_restored_size(new_size); |
433 | 462 |
434 // Only need to adjust bounds height when panel is expanded. | 463 Panel::LayoutState layout_state = panel->layout_state(); |
435 gfx::Rect bounds = panel->GetBounds(); | 464 gfx::Rect bounds = panel->GetBounds(); |
436 Panel::ExpansionState expansion_state = panel->expansion_state(); | 465 int delta_x = bounds.width() - new_width; |
437 if (new_height != bounds.height() && | 466 |
438 expansion_state == Panel::EXPANDED) { | 467 // Only need to update bounds when the panel is docked or detached. |
439 bounds.set_y(bounds.bottom() - new_height); | 468 if (layout_state != Panel::IN_OVERFLOW) { |
440 bounds.set_height(new_height); | 469 // Height is only affected when panel is expanded. |
| 470 if (new_height != bounds.height() && |
| 471 panel->expansion_state() == Panel::EXPANDED) { |
| 472 bounds.set_y(bounds.bottom() - new_height); |
| 473 bounds.set_height(new_height); |
| 474 } |
| 475 |
| 476 if (delta_x != 0) { |
| 477 bounds.set_width(new_width); |
| 478 bounds.set_x(bounds.x() + delta_x); |
| 479 } |
| 480 |
| 481 if (bounds != panel->GetBounds()) |
| 482 panel->SetPanelBounds(bounds); |
441 } | 483 } |
442 | 484 |
443 // Only need to adjust width if panel is in the panel strip. | 485 // If the panel is docked, rearrange if panel's width is changed. |
444 int delta_x = bounds.width() - new_width; | 486 // If the panel is in overflow, rearrange if panel's width is smaller because |
445 if (delta_x != 0 && expansion_state != Panel::IN_OVERFLOW) { | 487 // we might have sufficient space in the docking area to fit the shrunken |
446 bounds.set_width(new_width); | 488 // overflow panel. |
447 bounds.set_x(bounds.x() + delta_x); | 489 if ((layout_state == Panel::DOCKED && delta_x != 0) || |
448 } | 490 (layout_state == Panel::IN_OVERFLOW && delta_x < 0)) |
449 | |
450 if (bounds != panel->GetBounds()) | |
451 panel->SetPanelBounds(bounds); | |
452 | |
453 // Only need to rearrange if panel's width changed. | |
454 if (delta_x != 0) | |
455 Rearrange(); | 491 Rearrange(); |
456 } | 492 } |
457 | 493 |
458 bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { | 494 bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
459 // We should always bring up the titlebar if the mouse is over the | 495 // We should always bring up the titlebar if the mouse is over the |
460 // visible auto-hiding bottom bar. | 496 // visible auto-hiding bottom bar. |
461 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); | 497 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); |
462 if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && | 498 if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && |
463 desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) == | 499 desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) == |
464 AutoHidingDesktopBar::VISIBLE && | 500 AutoHidingDesktopBar::VISIBLE && |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 | 686 |
651 // TODO(jianli): remove the guard when overflow support is enabled on other | 687 // TODO(jianli): remove the guard when overflow support is enabled on other |
652 // platforms. http://crbug.com/105073 | 688 // platforms. http://crbug.com/105073 |
653 #if defined(OS_WIN) | 689 #if defined(OS_WIN) |
654 // Add/remove panels from/to overflow. A change in work area or the | 690 // Add/remove panels from/to overflow. A change in work area or the |
655 // resize/removal of a panel may affect how many panels fit in the strip. | 691 // resize/removal of a panel may affect how many panels fit in the strip. |
656 if (panel_index < panels_.size()) { | 692 if (panel_index < panels_.size()) { |
657 // Move panels to overflow in reverse to maintain their order. | 693 // Move panels to overflow in reverse to maintain their order. |
658 for (size_t overflow_index = panels_.size() - 1; | 694 for (size_t overflow_index = panels_.size() - 1; |
659 overflow_index >= panel_index; --overflow_index) | 695 overflow_index >= panel_index; --overflow_index) |
660 panels_[overflow_index]->SetExpansionState(Panel::IN_OVERFLOW); | 696 panels_[overflow_index]->SetLayoutState(Panel::IN_OVERFLOW); |
661 } else { | 697 } else { |
662 // Attempt to add more panels from overflow to the strip. | 698 // Attempt to add more panels from overflow to the strip. |
663 PanelOverflowStrip* overflow_strip = panel_manager_->panel_overflow_strip(); | 699 PanelOverflowStrip* overflow_strip = panel_manager_->panel_overflow_strip(); |
664 Panel* overflow_panel; | 700 Panel* overflow_panel; |
665 while ((overflow_panel = overflow_strip->first_panel()) && | 701 while ((overflow_panel = overflow_strip->first_panel()) && |
666 GetRightMostAvailablePosition() >= | 702 GetRightMostAvailablePosition() >= |
667 display_area_.x() + overflow_panel->restored_size().width()) { | 703 display_area_.x() + overflow_panel->restored_size().width()) { |
668 // We need to get back to the previous expansion state. | 704 // We need to get back to the previous expansion state. |
669 Panel::ExpansionState expansion_state_to_restore = | 705 Panel::ExpansionState expansion_state_to_restore = |
670 overflow_panel->old_expansion_state(); | 706 overflow_panel->expansion_state(); |
671 if (expansion_state_to_restore == Panel::MINIMIZED || | 707 if (expansion_state_to_restore != Panel::EXPANDED) { |
672 expansion_state_to_restore == Panel::TITLE_ONLY) { | |
673 expansion_state_to_restore = are_titlebars_up_ ? Panel::TITLE_ONLY | 708 expansion_state_to_restore = are_titlebars_up_ ? Panel::TITLE_ONLY |
674 : Panel::MINIMIZED; | 709 : Panel::MINIMIZED; |
675 } | 710 } |
| 711 overflow_panel->SetLayoutState(Panel::DOCKED); |
676 overflow_panel->SetExpansionState(expansion_state_to_restore); | 712 overflow_panel->SetExpansionState(expansion_state_to_restore); |
677 } | 713 } |
678 } | 714 } |
679 #endif | 715 #endif |
680 } | 716 } |
681 | 717 |
682 void PanelStrip::DelayedMovePanelToOverflow(Panel* panel) { | 718 void PanelStrip::DelayedMovePanelToOverflow(Panel* panel) { |
683 if (panels_in_temporary_layout_.erase(panel)) { | 719 if (panels_in_temporary_layout_.erase(panel)) { |
684 DCHECK(panel->has_temporary_layout()); | 720 DCHECK(panel->has_temporary_layout()); |
685 panel->SetExpansionState(Panel::IN_OVERFLOW); | 721 panel->SetLayoutState(Panel::IN_OVERFLOW); |
686 } | 722 } |
687 } | 723 } |
688 | 724 |
689 void PanelStrip::RemoveAll() { | 725 void PanelStrip::RemoveAll() { |
690 // This should only be called at the end of tests to clean up. | 726 // This should only be called at the end of tests to clean up. |
691 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 727 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
692 DCHECK(panels_in_temporary_layout_.empty()); | 728 DCHECK(panels_in_temporary_layout_.empty()); |
693 | 729 |
694 // Make a copy of the iterator as closing panels can modify the vector. | 730 // Make a copy of the iterator as closing panels can modify the vector. |
695 Panels panels_copy = panels_; | 731 Panels panels_copy = panels_; |
696 | 732 |
697 // Start from the bottom to avoid reshuffling. | 733 // Start from the bottom to avoid reshuffling. |
698 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 734 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
699 iter != panels_copy.rend(); ++iter) | 735 iter != panels_copy.rend(); ++iter) |
700 (*iter)->Close(); | 736 (*iter)->Close(); |
701 } | 737 } |
702 | 738 |
703 bool PanelStrip::is_dragging_panel() const { | 739 bool PanelStrip::is_dragging_panel() const { |
704 return dragging_panel_index_ != kInvalidPanelIndex; | 740 return dragging_panel_index_ != kInvalidPanelIndex; |
705 } | 741 } |
OLD | NEW |