Chromium Code Reviews| 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_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" |
| 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/panels/panel_manager.h" | 13 #include "chrome/browser/ui/panels/panel_manager.h" |
| 14 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" | 14 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" |
| 15 #include "chrome/browser/ui/panels/panel_overflow_strip.h" | |
| 15 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
| 17 #include "content/public/browser/notification_source.h" | 18 #include "content/public/browser/notification_source.h" |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 // Invalid panel index. | 21 // Invalid panel index. |
| 21 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); | 22 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); |
| 22 | 23 |
| 23 // Width to height ratio is used to compute the default width or height | 24 // Width to height ratio is used to compute the default width or height |
| 24 // when only one value is provided. | 25 // when only one value is provided. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 else if (height > max_panel_height) | 125 else if (height > max_panel_height) |
| 125 height = max_panel_height; | 126 height = max_panel_height; |
| 126 panel->set_restored_size(gfx::Size(width, height)); | 127 panel->set_restored_size(gfx::Size(width, height)); |
| 127 | 128 |
| 128 // Layout the new panel. | 129 // Layout the new panel. |
| 129 int y = display_area_.bottom() - height; | 130 int y = display_area_.bottom() - height; |
| 130 int x = GetRightMostAvailablePosition() - width; | 131 int x = GetRightMostAvailablePosition() - width; |
| 131 | 132 |
| 132 // Keep panel visible in the strip even if overlap would occur. | 133 // Keep panel visible in the strip even if overlap would occur. |
| 133 // Panel is moved to overflow from the strip after a delay. | 134 // Panel is moved to overflow from the strip after a delay. |
| 135 // TODO(jianli): Enable overflow area support for other platforms. | |
|
jennb
2011/12/02 19:15:00
Could you file a bug and put bug # here so we don'
jianli
2011/12/02 23:23:46
Done.
| |
| 136 #if defined(OS_WIN) | |
| 134 if (x < display_area_.x()) { | 137 if (x < display_area_.x()) { |
| 135 x = display_area_.x(); | 138 x = display_area_.x(); |
| 136 MessageLoop::current()->PostDelayedTask( | 139 MessageLoop::current()->PostDelayedTask( |
| 137 FROM_HERE, | 140 FROM_HERE, |
| 138 base::Bind(&PanelStrip::MovePanelToOverflow, | 141 base::Bind(&PanelStrip::MovePanelToOverflow, |
| 139 overflow_action_factory_.GetWeakPtr(), | 142 overflow_action_factory_.GetWeakPtr(), |
| 140 panel, | 143 panel, |
| 141 true), // new panel | 144 true), // new panel |
| 142 kMoveNewPanelToOverflowDelayMilliseconds); | 145 remove_delays_for_testing_ ? |
| 146 0 : kMoveNewPanelToOverflowDelayMilliseconds); | |
| 143 } | 147 } |
| 148 #endif | |
| 144 panel->Initialize(gfx::Rect(x, y, width, height)); | 149 panel->Initialize(gfx::Rect(x, y, width, height)); |
| 145 } | 150 } |
| 146 | 151 |
| 147 void PanelStrip::AddExistingPanel(Panel* panel) { | 152 void PanelStrip::AddExistingPanel(Panel* panel) { |
| 153 DCHECK(panel->expansion_state() == Panel::IN_OVERFLOW); | |
| 154 | |
| 148 gfx::Size restored_size = panel->restored_size(); | 155 gfx::Size restored_size = panel->restored_size(); |
| 149 int height = restored_size.height(); | 156 int height = restored_size.height(); |
| 150 int width = restored_size.width(); | 157 int width = restored_size.width(); |
| 151 int x; | 158 int x; |
| 152 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { | 159 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { |
| 153 DCHECK(!panels_.empty()); | 160 DCHECK(!panels_.empty()); |
| 154 MovePanelToOverflow(panels_.back(), false); | 161 MovePanelToOverflow(panels_.back(), false); |
| 155 } | 162 } |
| 156 int y = display_area_.bottom() - height; | 163 int y = display_area_.bottom() - height; |
| 157 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | 164 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
| 165 panel->SetExpansionState(Panel::EXPANDED); | |
| 158 } | 166 } |
| 159 | 167 |
| 160 int PanelStrip::GetMaxPanelWidth() const { | 168 int PanelStrip::GetMaxPanelWidth() const { |
| 161 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); | 169 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
| 162 } | 170 } |
| 163 | 171 |
| 164 int PanelStrip::GetMaxPanelHeight() const { | 172 int PanelStrip::GetMaxPanelHeight() const { |
| 165 return display_area_.height(); | 173 return display_area_.height(); |
| 166 } | 174 } |
| 167 | 175 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 198 | 206 |
| 199 bool PanelStrip::DoRemove(Panel* panel) { | 207 bool PanelStrip::DoRemove(Panel* panel) { |
| 200 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 208 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| 201 if (iter == panels_.end()) | 209 if (iter == panels_.end()) |
| 202 return false; | 210 return false; |
| 203 | 211 |
| 204 if (panel->expansion_state() != Panel::EXPANDED) | 212 if (panel->expansion_state() != Panel::EXPANDED) |
| 205 DecrementMinimizedPanels(); | 213 DecrementMinimizedPanels(); |
| 206 | 214 |
| 207 panels_.erase(iter); | 215 panels_.erase(iter); |
| 216 panel_manager_->OnPanelRemoved(panel); | |
| 208 return true; | 217 return true; |
| 209 } | 218 } |
| 210 | 219 |
| 211 void PanelStrip::StartDragging(Panel* panel) { | 220 void PanelStrip::StartDragging(Panel* panel) { |
| 212 for (size_t i = 0; i < panels_.size(); ++i) { | 221 for (size_t i = 0; i < panels_.size(); ++i) { |
| 213 if (panels_[i] == panel) { | 222 if (panels_[i] == panel) { |
| 214 dragging_panel_index_ = i; | 223 dragging_panel_index_ = i; |
| 215 dragging_panel_bounds_ = panel->GetBounds(); | 224 dragging_panel_bounds_ = panel->GetBounds(); |
| 216 dragging_panel_original_x_ = dragging_panel_bounds_.x(); | 225 dragging_panel_original_x_ = dragging_panel_bounds_.x(); |
| 217 break; | 226 break; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 panels_[dragging_panel_index_]->SetPanelBounds( | 342 panels_[dragging_panel_index_]->SetPanelBounds( |
| 334 dragging_panel_bounds_); | 343 dragging_panel_bounds_); |
| 335 } | 344 } |
| 336 | 345 |
| 337 dragging_panel_index_ = kInvalidPanelIndex; | 346 dragging_panel_index_ = kInvalidPanelIndex; |
| 338 | 347 |
| 339 DelayedRemove(); | 348 DelayedRemove(); |
| 340 } | 349 } |
| 341 | 350 |
| 342 void PanelStrip::OnPanelExpansionStateChanged( | 351 void PanelStrip::OnPanelExpansionStateChanged( |
| 343 Panel::ExpansionState old_state, Panel::ExpansionState new_state) { | 352 Panel* panel, Panel::ExpansionState old_state) { |
| 344 DCHECK_NE(new_state, old_state); | 353 DCHECK(panel->expansion_state() != Panel::IN_OVERFLOW); |
| 345 switch (new_state) { | 354 |
| 355 gfx::Size size = panel->restored_size(); | |
|
jennb
2011/12/02 19:15:00
Should only have to modify height. Panels coming f
jianli
2011/12/02 23:23:46
I rather update both width and height since this t
| |
| 356 switch (panel->expansion_state()) { | |
| 346 case Panel::EXPANDED: | 357 case Panel::EXPANDED: |
| 347 DecrementMinimizedPanels(); | 358 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) |
| 359 DecrementMinimizedPanels(); | |
| 360 break; | |
| 361 case Panel::TITLE_ONLY: | |
| 362 size.set_height(panel->TitleOnlyHeight()); | |
| 363 if (old_state == Panel::EXPANDED) | |
| 364 IncrementMinimizedPanels(); | |
| 348 break; | 365 break; |
| 349 case Panel::MINIMIZED: | 366 case Panel::MINIMIZED: |
| 350 case Panel::TITLE_ONLY: | 367 size.set_height(Panel::kMinimizedPanelHeight); |
| 351 if (old_state == Panel::EXPANDED) | 368 if (old_state == Panel::EXPANDED) |
| 352 IncrementMinimizedPanels(); | 369 IncrementMinimizedPanels(); |
| 353 break; | 370 break; |
| 354 default: | 371 default: |
| 372 NOTREACHED(); | |
|
jennb
2011/12/02 19:15:00
nit: Don't need DCHECK up above when we have this
jianli
2011/12/02 23:23:46
Done.
| |
| 355 break; | 373 break; |
| 356 } | 374 } |
| 375 | |
| 376 int bottom = GetBottomPositionForExpansionState(panel->expansion_state()); | |
|
jennb
2011/12/02 19:15:00
nit: Use a local var for panel->expansion_state()
jianli
2011/12/02 23:23:46
Done.
| |
| 377 gfx::Rect bounds = panel->GetBounds(); | |
| 378 panel->SetPanelBounds( | |
| 379 gfx::Rect(bounds.right() - size.width(), | |
| 380 bottom - size.height(), | |
| 381 size.width(), | |
| 382 size.height())); | |
| 357 } | 383 } |
| 358 | 384 |
| 359 void PanelStrip::IncrementMinimizedPanels() { | 385 void PanelStrip::IncrementMinimizedPanels() { |
| 360 minimized_panel_count_++; | 386 minimized_panel_count_++; |
| 361 if (minimized_panel_count_ == 1) | 387 if (minimized_panel_count_ == 1) |
| 362 panel_manager_->mouse_watcher()->AddObserver(this); | 388 panel_manager_->mouse_watcher()->AddObserver(this); |
| 363 DCHECK_LE(minimized_panel_count_, num_panels()); | 389 DCHECK_LE(minimized_panel_count_, num_panels()); |
| 364 } | 390 } |
| 365 | 391 |
| 366 void PanelStrip::DecrementMinimizedPanels() { | 392 void PanelStrip::DecrementMinimizedPanels() { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 AutoHidingDesktopBar::Visibility expected_visibility = | 584 AutoHidingDesktopBar::Visibility expected_visibility = |
| 559 delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE | 585 delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE |
| 560 : AutoHidingDesktopBar::HIDDEN; | 586 : AutoHidingDesktopBar::HIDDEN; |
| 561 if (visibility != expected_visibility) | 587 if (visibility != expected_visibility) |
| 562 return; | 588 return; |
| 563 | 589 |
| 564 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); | 590 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); |
| 565 delayed_titlebar_action_ = NO_ACTION; | 591 delayed_titlebar_action_ = NO_ACTION; |
| 566 } | 592 } |
| 567 | 593 |
| 568 void PanelStrip::Rearrange() { | 594 void PanelStrip::Rearrange() { |
|
jennb
2011/12/02 21:16:58
Need to #if windows the overflow logic here too to
jianli
2011/12/02 23:23:46
Done.
| |
| 569 int rightmost_position = StartingRightPosition(); | 595 int rightmost_position = StartingRightPosition(); |
| 570 | 596 |
| 571 size_t panel_index = 0; | 597 size_t panel_index = 0; |
| 572 for (; panel_index < panels_.size(); ++panel_index) { | 598 for (; panel_index < panels_.size(); ++panel_index) { |
| 573 Panel* panel = panels_[panel_index]; | 599 Panel* panel = panels_[panel_index]; |
| 574 gfx::Rect new_bounds(panel->GetBounds()); | 600 gfx::Rect new_bounds(panel->GetBounds()); |
| 575 int x = rightmost_position - new_bounds.width(); | 601 int x = rightmost_position - new_bounds.width(); |
| 576 | 602 |
| 577 if (x < display_area_.x()) { | 603 if (x < display_area_.x()) { |
| 578 MovePanelsToOverflow(panel_index); | 604 MovePanelsToOverflow(panel_index); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 596 DCHECK(overflow_point >= 0); | 622 DCHECK(overflow_point >= 0); |
| 597 // Move panels in reverse to maintain their order. | 623 // Move panels in reverse to maintain their order. |
| 598 for (size_t i = panels_.size() - 1; i >= overflow_point; --i) | 624 for (size_t i = panels_.size() - 1; i >= overflow_point; --i) |
| 599 MovePanelToOverflow(panels_[i], false); | 625 MovePanelToOverflow(panels_[i], false); |
| 600 } | 626 } |
| 601 | 627 |
| 602 void PanelStrip::MovePanelToOverflow(Panel* panel, bool is_new) { | 628 void PanelStrip::MovePanelToOverflow(Panel* panel, bool is_new) { |
| 603 if (!DoRemove(panel)) | 629 if (!DoRemove(panel)) |
| 604 return; | 630 return; |
| 605 | 631 |
| 606 // TODO(jianli): Replace with the real code using overflow strip. | 632 panel_manager_->panel_overflow_strip()->AddPanel(panel, is_new); |
| 607 // panel_manager_->panel_overflow_strip()->AddPanel(panel, is_new); | |
| 608 } | 633 } |
| 609 | 634 |
| 610 void PanelStrip::MovePanelsFromOverflowIfNeeded() { | 635 void PanelStrip::MovePanelsFromOverflowIfNeeded() { |
| 611 // TODO(jianli): Replace with the real code using overflow strip. | 636 PanelOverflowStrip* overflow_strip = panel_manager_->panel_overflow_strip(); |
| 612 // PanelOverflowStrip* overflow = panel_manager_->panel_overflow_strip(); | 637 Panel* overflow_panel; |
| 613 // Panel* candidate; | 638 while ((overflow_panel = overflow_strip->first_panel()) && |
| 614 // while (candidate = overflow->FirstPanel() && | 639 GetRightMostAvailablePosition() - |
| 615 // GetRightMostAvailablePosition - | 640 overflow_panel->restored_size().width() >= display_area_.x()) { |
| 616 // candidate->GetRestoredSize().width() >= display_area_.x()) { | 641 overflow_strip->Remove(overflow_panel); |
| 617 // overflow->Remove(candidate); | 642 AddPanel(overflow_panel); |
| 618 // AddPanel(candidate); | 643 } |
| 619 // } | |
| 620 } | 644 } |
| 621 | 645 |
| 622 void PanelStrip::RemoveAll() { | 646 void PanelStrip::RemoveAll() { |
| 623 // This should not be called when we're in the process of dragging. | 647 // This should not be called when we're in the process of dragging. |
| 624 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 648 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
| 625 | 649 |
| 626 // Make a copy of the iterator as closing panels can modify the vector. | 650 // Make a copy of the iterator as closing panels can modify the vector. |
| 627 Panels panels_copy = panels_; | 651 Panels panels_copy = panels_; |
| 628 | 652 |
| 629 // Start from the bottom to avoid reshuffling. | 653 // Start from the bottom to avoid reshuffling. |
| 630 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 654 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
| 631 iter != panels_copy.rend(); ++iter) | 655 iter != panels_copy.rend(); ++iter) |
| 632 (*iter)->Close(); | 656 (*iter)->Close(); |
| 633 } | 657 } |
| 634 | 658 |
| 635 bool PanelStrip::is_dragging_panel() const { | 659 bool PanelStrip::is_dragging_panel() const { |
| 636 return dragging_panel_index_ != kInvalidPanelIndex; | 660 return dragging_panel_index_ != kInvalidPanelIndex; |
| 637 } | 661 } |
| OLD | NEW |