Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chrome/browser/ui/panels/docked_panel_strip.cc

Issue 9560002: Cleanup to keep panel from manipulating its panel strip assignment directly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: removed unneeded includes Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/panels/overflow_panel_strip.h"
15 #include "chrome/browser/ui/panels/panel_manager.h" 14 #include "chrome/browser/ui/panels/panel_manager.h"
16 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" 15 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
17 #include "chrome/common/chrome_notification_types.h" 16 #include "chrome/common/chrome_notification_types.h"
18 #include "content/public/browser/notification_service.h" 17 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h" 18 #include "content/public/browser/notification_source.h"
20 19
21 namespace { 20 namespace {
22 // Width to height ratio is used to compute the default width or height 21 // Width to height ratio is used to compute the default width or height
23 // when only one value is provided. 22 // when only one value is provided.
24 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio 23 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 gfx::Rect old_area = display_area_; 78 gfx::Rect old_area = display_area_;
80 display_area_ = display_area; 79 display_area_ = display_area;
81 80
82 if (panels_.empty()) 81 if (panels_.empty())
83 return; 82 return;
84 83
85 RefreshLayout(); 84 RefreshLayout();
86 } 85 }
87 86
88 void DockedPanelStrip::AddPanel(Panel* panel) { 87 void DockedPanelStrip::AddPanel(Panel* panel) {
89 DCHECK_EQ(this, panel->panel_strip()); 88 DCHECK_NE(this, panel->panel_strip());
89 panel->set_panel_strip(this);
90 90
91 // Always update limits, even for exiting panels, in case the maximums changed 91 // Always update limits, even on existing panels, in case the limits changed
92 // while panel was out of the strip. 92 // while panel was out of the strip.
93 int max_panel_width = GetMaxPanelWidth(); 93 int max_panel_width = GetMaxPanelWidth();
94 int max_panel_height = GetMaxPanelHeight(); 94 int max_panel_height = GetMaxPanelHeight();
95 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), 95 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight),
96 gfx::Size(max_panel_width, max_panel_height)); 96 gfx::Size(max_panel_width, max_panel_height));
97 97
98 gfx::Size restored_size = panel->restored_size(); 98 gfx::Size restored_size = panel->restored_size();
99 int height = restored_size.height(); 99 int height = restored_size.height();
100 int width = restored_size.width(); 100 int width = restored_size.width();
101 101
102 if (panel->initialized()) { 102 if (panel->initialized()) {
103 // Bump panels in the strip to make room for this panel. 103 EnsureAvailableSpace(width);
104 // Prevent layout refresh when panel is removed from this strip. 104 int x = GetRightMostAvailablePosition() - width;
105 disable_layout_refresh_ = true;
106 PanelStrip* overflow_strip = panel_manager_->overflow_strip();
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 105
114 Panel::ExpansionState expansion_state_to_restore; 106 Panel::ExpansionState expansion_state_to_restore;
115 if (panel->expansion_state() == Panel::EXPANDED) { 107 if (panel->expansion_state() == Panel::EXPANDED) {
116 expansion_state_to_restore = Panel::EXPANDED; 108 expansion_state_to_restore = Panel::EXPANDED;
117 } else { 109 } else {
118 if (are_titlebars_up_ || panel->IsDrawingAttention()) { 110 if (are_titlebars_up_ || panel->IsDrawingAttention()) {
119 expansion_state_to_restore = Panel::TITLE_ONLY; 111 expansion_state_to_restore = Panel::TITLE_ONLY;
120 height = panel->TitleOnlyHeight(); 112 height = panel->TitleOnlyHeight();
121 } else { 113 } else {
122 expansion_state_to_restore = Panel::MINIMIZED; 114 expansion_state_to_restore = Panel::MINIMIZED;
123 height = Panel::kMinimizedPanelHeight; 115 height = Panel::kMinimizedPanelHeight;
124 } 116 }
125 IncrementMinimizedPanels(); 117 IncrementMinimizedPanels();
126 } 118 }
127
128 int y = 119 int y =
129 GetBottomPositionForExpansionState(expansion_state_to_restore) - height; 120 GetBottomPositionForExpansionState(expansion_state_to_restore) - height;
130 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); 121 panel->SetPanelBounds(gfx::Rect(x, y, width, height));
131 122
132 // Update the minimized state to reflect current titlebar mode. 123 // Update the minimized state to reflect current titlebar mode.
133 // Do this AFTER setting panel bounds to avoid an extra bounds change. 124 // Do this AFTER setting panel bounds to avoid an extra bounds change.
134 if (panel->expansion_state() != Panel::EXPANDED) 125 if (panel->expansion_state() != Panel::EXPANDED)
135 panel->SetExpansionState(expansion_state_to_restore); 126 panel->SetExpansionState(expansion_state_to_restore);
136 127
137 } else { 128 } else {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 187
197 int DockedPanelStrip::StartingRightPosition() const { 188 int DockedPanelStrip::StartingRightPosition() const {
198 return display_area_.right(); 189 return display_area_.right();
199 } 190 }
200 191
201 int DockedPanelStrip::GetRightMostAvailablePosition() const { 192 int DockedPanelStrip::GetRightMostAvailablePosition() const {
202 return panels_.empty() ? StartingRightPosition() : 193 return panels_.empty() ? StartingRightPosition() :
203 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); 194 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing);
204 } 195 }
205 196
206 bool DockedPanelStrip::RemovePanel(Panel* panel) { 197 void DockedPanelStrip::RemovePanel(Panel* panel) {
198 DCHECK_EQ(this, panel->panel_strip());
199 panel->set_panel_strip(NULL);
200
207 if (panel->has_temporary_layout()) { 201 if (panel->has_temporary_layout()) {
208 panels_in_temporary_layout_.erase(panel); 202 panels_in_temporary_layout_.erase(panel);
209 return true; 203 return;
210 } 204 }
211 205
212 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); 206 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
213 if (iter == panels_.end()) 207 DCHECK(iter != panels_.end());
214 return false;
215 208
216 if (panel->expansion_state() != Panel::EXPANDED) 209 if (panel->expansion_state() != Panel::EXPANDED)
217 DecrementMinimizedPanels(); 210 DecrementMinimizedPanels();
218 211
219 // Removing an element from the list will invalidate the iterator that refers 212 // 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. 213 // to it. So we need to update the iterator in that case.
221 bool update_original_dragging_iterator_after_erase = false; 214 DCHECK(dragging_panel_current_iterator_ != iter);
222 if (dragging_panel_original_iterator_ != panels_.end()) { 215 bool update_iterator_after_erase =
223 if (dragging_panel_current_iterator_ == iter) { 216 (dragging_panel_original_iterator_ == iter);
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 217
236 iter = panels_.erase(iter); 218 iter = panels_.erase(iter);
237 219
238 if (update_original_dragging_iterator_after_erase) 220 if (update_iterator_after_erase)
239 dragging_panel_original_iterator_ = iter; 221 dragging_panel_original_iterator_ = iter;
240 222
241 if (!disable_layout_refresh_) 223 if (!disable_layout_refresh_)
242 RefreshLayout(); 224 RefreshLayout();
243
244 return true;
245 } 225 }
246 226
247 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { 227 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const {
248 // Panels with temporary layout cannot be shown as active. 228 // Panels with temporary layout cannot be shown as active.
249 return !panel->has_temporary_layout(); 229 return !panel->has_temporary_layout();
250 } 230 }
251 231
252 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { 232 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const {
253 // Only the panels having temporary layout can't be dragged. 233 // Only the panels having temporary layout can't be dragged.
254 return !panel->has_temporary_layout(); 234 return !panel->has_temporary_layout();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 416
437 panel->SetExpansionState(panel->IsDrawingAttention() ? 417 panel->SetExpansionState(panel->IsDrawingAttention() ?
438 Panel::TITLE_ONLY : Panel::MINIMIZED); 418 Panel::TITLE_ONLY : Panel::MINIMIZED);
439 } 419 }
440 420
441 void DockedPanelStrip::RestorePanel(Panel* panel) { 421 void DockedPanelStrip::RestorePanel(Panel* panel) {
442 DCHECK_EQ(this, panel->panel_strip()); 422 DCHECK_EQ(this, panel->panel_strip());
443 panel->SetExpansionState(Panel::EXPANDED); 423 panel->SetExpansionState(Panel::EXPANDED);
444 } 424 }
445 425
426 bool DockedPanelStrip::IsPanelMinimized(const Panel* panel) const {
427 return panel->expansion_state() != Panel::EXPANDED;
428 }
429
446 void DockedPanelStrip::IncrementMinimizedPanels() { 430 void DockedPanelStrip::IncrementMinimizedPanels() {
447 minimized_panel_count_++; 431 minimized_panel_count_++;
448 if (minimized_panel_count_ == 1) 432 if (minimized_panel_count_ == 1)
449 panel_manager_->mouse_watcher()->AddObserver(this); 433 panel_manager_->mouse_watcher()->AddObserver(this);
450 DCHECK_LE(minimized_panel_count_, num_panels()); 434 DCHECK_LE(minimized_panel_count_, num_panels());
451 } 435 }
452 436
453 void DockedPanelStrip::DecrementMinimizedPanels() { 437 void DockedPanelStrip::DecrementMinimizedPanels() {
454 minimized_panel_count_--; 438 minimized_panel_count_--;
455 DCHECK_GE(minimized_panel_count_, 0); 439 DCHECK_GE(minimized_panel_count_, 0);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 delayed_titlebar_action_ = NO_ACTION; 656 delayed_titlebar_action_ = NO_ACTION;
673 } 657 }
674 658
675 void DockedPanelStrip::OnFullScreenModeChanged(bool is_full_screen) { 659 void DockedPanelStrip::OnFullScreenModeChanged(bool is_full_screen) {
676 for (Panels::const_iterator iter = panels_.begin(); 660 for (Panels::const_iterator iter = panels_.begin();
677 iter != panels_.end(); ++iter) { 661 iter != panels_.end(); ++iter) {
678 (*iter)->FullScreenModeChanged(is_full_screen); 662 (*iter)->FullScreenModeChanged(is_full_screen);
679 } 663 }
680 } 664 }
681 665
666 bool DockedPanelStrip::CanFitPanel(Panel* panel) {
667 int width = panel->GetRestoredBounds().width();
668 return GetRightMostAvailablePosition() - width >= display_area_.x();
669 }
670
682 void DockedPanelStrip::RefreshLayout() { 671 void DockedPanelStrip::RefreshLayout() {
683 int rightmost_position = StartingRightPosition(); 672 int rightmost_position = StartingRightPosition();
684 673
685 Panels::const_iterator panel_iter = panels_.begin(); 674 Panels::const_iterator panel_iter = panels_.begin();
686 for (; panel_iter != panels_.end(); ++panel_iter) { 675 for (; panel_iter != panels_.end(); ++panel_iter) {
687 Panel* panel = *panel_iter; 676 Panel* panel = *panel_iter;
688 gfx::Rect new_bounds(panel->GetBounds()); 677 gfx::Rect new_bounds(panel->GetBounds());
689 int x = rightmost_position - new_bounds.width(); 678 int x = rightmost_position - new_bounds.width();
690 679
691 if (x < display_area_.x()) 680 if (x < display_area_.x())
692 break; 681 break;
693 682
694 // Don't update the docked panel that is currently dragged. 683 // Don't update the docked panel that is currently dragged.
695 if (panel != dragging_panel()) { 684 if (panel != dragging_panel()) {
696 new_bounds.set_x(x); 685 new_bounds.set_x(x);
697 new_bounds.set_y( 686 new_bounds.set_y(
698 GetBottomPositionForExpansionState(panel->expansion_state()) - 687 GetBottomPositionForExpansionState(panel->expansion_state()) -
699 new_bounds.height()); 688 new_bounds.height());
700 panel->SetPanelBounds(new_bounds); 689 panel->SetPanelBounds(new_bounds);
701 } 690 }
702 691
703 rightmost_position = x - kPanelsHorizontalSpacing; 692 rightmost_position = x - kPanelsHorizontalSpacing;
704 } 693 }
705 694
706 // Add/remove panels from/to overflow. A change in work area or the 695 // Add/remove panels from/to overflow. A change in work area or the
707 // resize/removal of a panel may affect how many panels fit in the strip. 696 // resize/removal of a panel may affect how many panels fit in the strip.
708 OverflowPanelStrip* overflow_strip = panel_manager_->overflow_strip(); 697 if (panel_iter != panels_.end())
709 if (panel_iter != panels_.end()) { 698 MovePanelsToOverflow(*panel_iter);
710 // Prevent layout refresh when panel is removed from this strip. 699 else
711 disable_layout_refresh_ = true; 700 panel_manager_->MovePanelsOutOfOverflowIfCanFit();
jianli 2012/03/02 00:11:41 MovePanelsToOverflow and panel_manager_->MovePanel
jennb 2012/03/02 01:26:32 Moved the former to PanelManager as well. Adding p
701 }
712 702
713 // Keep track of panels to move to overflow in a separate storage since 703 void DockedPanelStrip::MovePanelsToOverflow(Panel* overflow_point) {
714 // removing it from the list will invalidate the iterator. 704 // Prevent layout refresh when panels are bumped from the strip as
715 std::vector<Panel*> panels_to_move_to_overflow; 705 // remaining panels in the strip are not affected.
716 for (; panel_iter != panels_.end(); ++panel_iter) 706 // Move panels to overflow in reverse to maintain their order.
717 panels_to_move_to_overflow.push_back(*panel_iter); 707 disable_layout_refresh_ = true;
708 Panel* bumped_panel;
709 while (!panels_.empty()) {
710 bumped_panel = panels_.back();
711 panel_manager_->ChangePanelLayout(panels_.back(), PanelStrip::IN_OVERFLOW);
712 if (bumped_panel == overflow_point)
713 break;
714 }
715 DCHECK(!panels_.empty());
716 disable_layout_refresh_ = false;
717 }
718 718
719 // Move panels to overflow in reverse to maintain their order. 719 void DockedPanelStrip::EnsureAvailableSpace(int width) {
jianli 2012/03/02 00:11:41 This seems to be quite similar to MovePanelsToOver
jennb 2012/03/02 01:26:32 Not easily. In this one, the stopping point is not
720 for (std::vector<Panel*>::reverse_iterator iter = 720 // Bump panels out of strip to create the requested space.
721 panels_to_move_to_overflow.rbegin(); 721 // Prevent layout refresh wile bumping panels from end of strip as
722 iter != panels_to_move_to_overflow.rend(); ++iter) { 722 // remaining panels in the strip are not affected.
723 (*iter)->MoveToStrip(overflow_strip); 723 disable_layout_refresh_ = true;
724 } 724 while (GetRightMostAvailablePosition() - width < display_area_.x()) {
725 725 DCHECK(!panels_.empty());
726 disable_layout_refresh_ = false; 726 panel_manager_->ChangePanelLayout(panels_.back(), PanelStrip::IN_OVERFLOW);
727 } else {
728 // Attempt to add more panels from overflow to the strip.
729 Panel* overflow_panel;
730 while ((overflow_panel = overflow_strip->first_panel()) &&
731 GetRightMostAvailablePosition() >=
732 display_area_.x() + overflow_panel->restored_size().width()) {
733 overflow_panel->MoveToStrip(this);
734 }
735 } 727 }
728 disable_layout_refresh_ = false;
736 } 729 }
737 730
738 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { 731 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) {
739 if (panels_in_temporary_layout_.erase(panel)) { 732 if (panels_in_temporary_layout_.erase(panel)) {
740 DCHECK(panel->has_temporary_layout()); 733 DCHECK(panel->has_temporary_layout());
741 panel->MoveToStrip(panel_manager_->overflow_strip()); 734 panel_manager_->ChangePanelLayout(panel, PanelStrip::IN_OVERFLOW);
742 } 735 }
743 } 736 }
744 737
745 void DockedPanelStrip::CloseAll() { 738 void DockedPanelStrip::CloseAll() {
746 // This should only be called at the end of tests to clean up. 739 // This should only be called at the end of tests to clean up.
747 DCHECK(panels_in_temporary_layout_.empty()); 740 DCHECK(panels_in_temporary_layout_.empty());
748 741
749 // Make a copy of the iterator as closing panels can modify the vector. 742 // Make a copy of the iterator as closing panels can modify the vector.
750 Panels panels_copy = panels_; 743 Panels panels_copy = panels_;
751 744
752 // Start from the bottom to avoid reshuffling. 745 // Start from the bottom to avoid reshuffling.
753 for (Panels::reverse_iterator iter = panels_copy.rbegin(); 746 for (Panels::reverse_iterator iter = panels_copy.rbegin();
754 iter != panels_copy.rend(); ++iter) 747 iter != panels_copy.rend(); ++iter)
755 (*iter)->Close(); 748 (*iter)->Close();
756 } 749 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698