OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_manager.h" | 5 #include "chrome/browser/ui/panels/panel_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/window_sizer.h" | 13 #include "chrome/browser/ui/window_sizer.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 // Invalid panel index. | 16 // Invalid panel index. |
17 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); | 17 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); |
18 | 18 |
19 // Minimum width and height of a panel. | 19 // Minimum width and height of a panel. |
20 const int kPanelMinWidthPixels = 64; | 20 // Note: The minimum size of a widget (see widget.cc) is fixed to 100x100. |
21 const int kPanelMinHeightPixels = 24; | 21 // TODO(jianli): Need to fix this to support smaller panel. |
| 22 const int kPanelMinWidthPixels = 100; |
| 23 const int kPanelMinHeightPixels = 100; |
22 | 24 |
23 // Default width and height of a panel. | 25 // Default width and height of a panel. |
24 const int kPanelDefaultWidthPixels = 240; | 26 const int kPanelDefaultWidthPixels = 240; |
25 const int kPanelDefaultHeightPixels = 290; | 27 const int kPanelDefaultHeightPixels = 290; |
26 | 28 |
27 // Maxmium width and height of a panel based on the factor of the working | 29 // Maxmium width and height of a panel based on the factor of the working |
28 // area. | 30 // area. |
29 const double kPanelMaxWidthFactor = 1.0; | 31 const double kPanelMaxWidthFactor = 1.0; |
30 const double kPanelMaxHeightFactor = 0.5; | 32 const double kPanelMaxHeightFactor = 0.5; |
31 | 33 |
(...skipping 11 matching lines...) Expand all Loading... |
43 PanelManager* PanelManager::GetInstance() { | 45 PanelManager* PanelManager::GetInstance() { |
44 if (!panel_instance.get()) | 46 if (!panel_instance.get()) |
45 panel_instance = new PanelManager(); | 47 panel_instance = new PanelManager(); |
46 return panel_instance.get(); | 48 return panel_instance.get(); |
47 } | 49 } |
48 | 50 |
49 PanelManager::PanelManager() | 51 PanelManager::PanelManager() |
50 : dragging_panel_index_(kInvalidPanelIndex), | 52 : dragging_panel_index_(kInvalidPanelIndex), |
51 dragging_panel_original_x_(0), | 53 dragging_panel_original_x_(0), |
52 delayed_titlebar_action_(NO_ACTION), | 54 delayed_titlebar_action_(NO_ACTION), |
53 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 55 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 56 auto_sizing_enabled_(true) { |
54 auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); | 57 auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); |
55 OnDisplayChanged(); | 58 OnDisplayChanged(); |
56 } | 59 } |
57 | 60 |
58 PanelManager::~PanelManager() { | 61 PanelManager::~PanelManager() { |
59 DCHECK(panels_.empty()); | 62 DCHECK(panels_.empty()); |
60 DCHECK(panels_pending_to_remove_.empty()); | 63 DCHECK(panels_pending_to_remove_.empty()); |
61 } | 64 } |
62 | 65 |
63 void PanelManager::OnDisplayChanged() { | 66 void PanelManager::OnDisplayChanged() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 Panel* PanelManager::CreatePanel(Browser* browser) { | 103 Panel* PanelManager::CreatePanel(Browser* browser) { |
101 // Adjust the width and height to fit into our constraint. | 104 // Adjust the width and height to fit into our constraint. |
102 int width = browser->override_bounds().width(); | 105 int width = browser->override_bounds().width(); |
103 int height = browser->override_bounds().height(); | 106 int height = browser->override_bounds().height(); |
104 | 107 |
105 if (width == 0 && height == 0) { | 108 if (width == 0 && height == 0) { |
106 width = kPanelDefaultWidthPixels; | 109 width = kPanelDefaultWidthPixels; |
107 height = kPanelDefaultHeightPixels; | 110 height = kPanelDefaultHeightPixels; |
108 } | 111 } |
109 | 112 |
110 int max_panel_width = | 113 int max_panel_width = GetMaxPanelWidth(); |
111 static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor); | 114 int max_panel_height = GetMaxPanelHeight(); |
112 int max_panel_height = | |
113 static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor); | |
114 | 115 |
115 if (width < kPanelMinWidthPixels) | 116 if (width < kPanelMinWidthPixels) |
116 width = kPanelMinWidthPixels; | 117 width = kPanelMinWidthPixels; |
117 else if (width > max_panel_width) | 118 else if (width > max_panel_width) |
118 width = max_panel_width; | 119 width = max_panel_width; |
119 | 120 |
120 if (height < kPanelMinHeightPixels) | 121 if (height < kPanelMinHeightPixels) |
121 height = kPanelMinHeightPixels; | 122 height = kPanelMinHeightPixels; |
122 else if (height > max_panel_height) | 123 else if (height > max_panel_height) |
123 height = max_panel_height; | 124 height = max_panel_height; |
124 | 125 |
125 // Compute the origin. Ensure that it falls within the adjusted work area by | 126 // Compute the origin. Ensure that it falls within the adjusted work area by |
126 // closing other panels if needed. | 127 // closing other panels if needed. |
127 int y = adjusted_work_area_.bottom() - height; | 128 int y = adjusted_work_area_.bottom() - height; |
128 | 129 |
129 const Extension* extension = NULL; | 130 const Extension* extension = NULL; |
130 int x; | 131 int x; |
131 while ((x = GetRightMostAvaialblePosition() - width) < | 132 while ((x = GetRightMostAvaialblePosition() - width) < |
132 adjusted_work_area_.x() ) { | 133 adjusted_work_area_.x() ) { |
133 if (!extension) | 134 if (!extension) |
134 extension = Panel::GetExtension(browser); | 135 extension = Panel::GetExtension(browser); |
135 FindAndClosePanelOnOverflow(extension); | 136 FindAndClosePanelOnOverflow(extension); |
136 } | 137 } |
137 | 138 |
138 // Now create the panel with the computed bounds. | 139 // Now create the panel with the computed bounds. |
139 Panel* panel = new Panel(browser, gfx::Rect(x, y, width, height)); | 140 Panel* panel = new Panel(browser, gfx::Rect(x, y, width, height)); |
140 panels_.push_back(panel); | 141 panels_.push_back(panel); |
141 | 142 |
| 143 UpdateMaxSizeForAllPanels(); |
| 144 |
142 return panel; | 145 return panel; |
143 } | 146 } |
144 | 147 |
| 148 int PanelManager::GetMaxPanelWidth() const { |
| 149 return static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor); |
| 150 } |
| 151 |
| 152 int PanelManager::GetMaxPanelHeight() const { |
| 153 return static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor); |
| 154 } |
| 155 |
145 int PanelManager::GetRightMostAvaialblePosition() const { | 156 int PanelManager::GetRightMostAvaialblePosition() const { |
146 return panels_.empty() ? adjusted_work_area_.right() : | 157 return panels_.empty() ? adjusted_work_area_.right() : |
147 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); | 158 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); |
148 } | 159 } |
149 | 160 |
150 void PanelManager::Remove(Panel* panel) { | 161 void PanelManager::Remove(Panel* panel) { |
151 // If we're in the process of dragging, delay the removal. | 162 // If we're in the process of dragging, delay the removal. |
152 if (dragging_panel_index_ != kInvalidPanelIndex) { | 163 if (dragging_panel_index_ != kInvalidPanelIndex) { |
153 panels_pending_to_remove_.push_back(panel); | 164 panels_pending_to_remove_.push_back(panel); |
154 return; | 165 return; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 } else { | 307 } else { |
297 panels_[dragging_panel_index_]->SetPanelBounds( | 308 panels_[dragging_panel_index_]->SetPanelBounds( |
298 dragging_panel_bounds_); | 309 dragging_panel_bounds_); |
299 } | 310 } |
300 | 311 |
301 dragging_panel_index_ = kInvalidPanelIndex; | 312 dragging_panel_index_ = kInvalidPanelIndex; |
302 | 313 |
303 DelayedRemove(); | 314 DelayedRemove(); |
304 } | 315 } |
305 | 316 |
| 317 void PanelManager::OnPreferredWindowSizeChanged( |
| 318 Panel* panel, const gfx::Size& preferred_window_size) { |
| 319 if (!auto_sizing_enabled_) |
| 320 return; |
| 321 |
| 322 gfx::Rect bounds = panel->GetBounds(); |
| 323 int restored_height = panel->GetRestoredHeight(); |
| 324 |
| 325 // The panel width: |
| 326 // * cannot grow or shrink to go beyond [min_width, max_width] |
| 327 // * cannot grow to take more than the available space and go beyond the left |
| 328 // of the work area. |
| 329 int new_width = preferred_window_size.width(); |
| 330 if (new_width > panel->max_size().width()) |
| 331 new_width = panel->max_size().width(); |
| 332 if (new_width < panel->min_size().width()) |
| 333 new_width = panel->min_size().width(); |
| 334 |
| 335 int right_most_available_position = GetRightMostAvaialblePosition(); |
| 336 if (new_width - bounds.width() > right_most_available_position) |
| 337 new_width = bounds.width() + right_most_available_position; |
| 338 |
| 339 if (new_width != bounds.width()) { |
| 340 int delta = bounds.width() - new_width; |
| 341 bounds.set_x(bounds.x() + delta); |
| 342 bounds.set_width(new_width); |
| 343 |
| 344 // Reposition all the panels on the left. |
| 345 int panel_index = -1; |
| 346 for (int i = 0; i < static_cast<int>(panels_.size()); ++i) { |
| 347 if (panels_[i] == panel) { |
| 348 panel_index = i; |
| 349 break; |
| 350 } |
| 351 } |
| 352 DCHECK(panel_index >= 0); |
| 353 for (int i = static_cast<int>(panels_.size()) -1; i > panel_index; |
| 354 --i) { |
| 355 gfx::Rect this_bounds = panels_[i]->GetBounds(); |
| 356 this_bounds.set_x(this_bounds.x() + delta); |
| 357 panels_[i]->SetPanelBounds(this_bounds); |
| 358 } |
| 359 } |
| 360 |
| 361 // The panel height: |
| 362 // * cannot grow or shrink to go beyond [min_height, max_height] |
| 363 int new_height = preferred_window_size.height(); |
| 364 if (new_height > panel->max_size().height()) |
| 365 new_height = panel->max_size().height(); |
| 366 if (new_height < panel->min_size().height()) |
| 367 new_height = panel->min_size().height(); |
| 368 |
| 369 if (new_height != restored_height) { |
| 370 // If the panel is not expanded, we only need to save the new restored |
| 371 // height. |
| 372 if (panel->expansion_state() == Panel::EXPANDED) { |
| 373 bounds.set_y(bounds.y() - new_height + bounds.height()); |
| 374 bounds.set_height(new_height); |
| 375 } else { |
| 376 panel->SetRestoredHeight(new_height); |
| 377 } |
| 378 } |
| 379 |
| 380 panel->SetPanelBounds(bounds); |
| 381 |
| 382 UpdateMaxSizeForAllPanels(); |
| 383 } |
| 384 |
306 bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { | 385 bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
307 // We should always bring up the titlebar if the mouse is over the | 386 // We should always bring up the titlebar if the mouse is over the |
308 // visible auto-hiding bottom bar. | 387 // visible auto-hiding bottom bar. |
309 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && | 388 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && |
310 auto_hiding_desktop_bar_->GetVisibility( | 389 auto_hiding_desktop_bar_->GetVisibility( |
311 AutoHidingDesktopBar::ALIGN_BOTTOM) == | 390 AutoHidingDesktopBar::ALIGN_BOTTOM) == |
312 AutoHidingDesktopBar::VISIBLE && | 391 AutoHidingDesktopBar::VISIBLE && |
313 mouse_y >= adjusted_work_area_.bottom()) | 392 mouse_y >= adjusted_work_area_.bottom()) |
314 return true; | 393 return true; |
315 | 394 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 int PanelManager::GetBottomPositionForExpansionState( | 482 int PanelManager::GetBottomPositionForExpansionState( |
404 Panel::ExpansionState expansion_state) const { | 483 Panel::ExpansionState expansion_state) const { |
405 // If there is an auto-hiding desktop bar aligned to the bottom edge, we need | 484 // If there is an auto-hiding desktop bar aligned to the bottom edge, we need |
406 // to move the minimize panel down to the bottom edge. | 485 // to move the minimize panel down to the bottom edge. |
407 int bottom = adjusted_work_area_.bottom(); | 486 int bottom = adjusted_work_area_.bottom(); |
408 if (expansion_state == Panel::MINIMIZED && | 487 if (expansion_state == Panel::MINIMIZED && |
409 auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { | 488 auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
410 bottom += auto_hiding_desktop_bar_->GetThickness( | 489 bottom += auto_hiding_desktop_bar_->GetThickness( |
411 AutoHidingDesktopBar::ALIGN_BOTTOM); | 490 AutoHidingDesktopBar::ALIGN_BOTTOM); |
412 } | 491 } |
| 492 |
413 return bottom; | 493 return bottom; |
414 } | 494 } |
415 | 495 |
416 void PanelManager::OnAutoHidingDesktopBarThicknessChanged() { | 496 void PanelManager::OnAutoHidingDesktopBarThicknessChanged() { |
417 AdjustWorkAreaForAutoHidingDesktopBars(); | 497 AdjustWorkAreaForAutoHidingDesktopBars(); |
418 Rearrange(panels_.begin(), adjusted_work_area_.right()); | 498 Rearrange(panels_.begin(), adjusted_work_area_.right()); |
419 } | 499 } |
420 | 500 |
421 void PanelManager::OnAutoHidingDesktopBarVisibilityChanged( | 501 void PanelManager::OnAutoHidingDesktopBarVisibilityChanged( |
422 AutoHidingDesktopBar::Alignment alignment, | 502 AutoHidingDesktopBar::Alignment alignment, |
(...skipping 20 matching lines...) Expand all Loading... |
443 Panel* panel = *iter; | 523 Panel* panel = *iter; |
444 | 524 |
445 gfx::Rect new_bounds(panel->GetBounds()); | 525 gfx::Rect new_bounds(panel->GetBounds()); |
446 new_bounds.set_x(rightmost_position - new_bounds.width()); | 526 new_bounds.set_x(rightmost_position - new_bounds.width()); |
447 new_bounds.set_y(adjusted_work_area_.bottom() - new_bounds.height()); | 527 new_bounds.set_y(adjusted_work_area_.bottom() - new_bounds.height()); |
448 if (new_bounds != panel->GetBounds()) | 528 if (new_bounds != panel->GetBounds()) |
449 panel->SetPanelBounds(new_bounds); | 529 panel->SetPanelBounds(new_bounds); |
450 | 530 |
451 rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; | 531 rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; |
452 } | 532 } |
| 533 |
| 534 UpdateMaxSizeForAllPanels(); |
453 } | 535 } |
454 | 536 |
455 void PanelManager::RemoveAll() { | 537 void PanelManager::RemoveAll() { |
456 // This should not be called when we're in the process of dragging. | 538 // This should not be called when we're in the process of dragging. |
457 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 539 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
458 | 540 |
459 // Make a copy of the iterator as closing panels can modify the vector. | 541 // Make a copy of the iterator as closing panels can modify the vector. |
460 Panels panels_copy = panels_; | 542 Panels panels_copy = panels_; |
461 | 543 |
462 // Start from the bottom to avoid reshuffling. | 544 // Start from the bottom to avoid reshuffling. |
463 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 545 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
464 iter != panels_copy.rend(); ++iter) | 546 iter != panels_copy.rend(); ++iter) |
465 (*iter)->Close(); | 547 (*iter)->Close(); |
466 } | 548 } |
467 | 549 |
468 bool PanelManager::is_dragging_panel() const { | 550 bool PanelManager::is_dragging_panel() const { |
469 return dragging_panel_index_ != kInvalidPanelIndex; | 551 return dragging_panel_index_ != kInvalidPanelIndex; |
470 } | 552 } |
| 553 |
| 554 void PanelManager::UpdateMaxSizeForAllPanels() { |
| 555 if (!auto_sizing_enabled_) |
| 556 return; |
| 557 |
| 558 for (Panels::const_iterator iter = panels_.begin(); |
| 559 iter != panels_.end(); ++iter) { |
| 560 Panel* panel = *iter; |
| 561 // A panel can at most grow to take over all the avaialble space that is |
| 562 // returned by GetRightMostAvaialblePosition. |
| 563 int width_can_grow_to = |
| 564 panel->GetBounds().width() + GetRightMostAvaialblePosition(); |
| 565 panel->SetMaxSize(gfx::Size( |
| 566 std::min(width_can_grow_to, GetMaxPanelWidth()), |
| 567 GetMaxPanelHeight())); |
| 568 } |
| 569 } |
OLD | NEW |