| 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 "ash/wm/panels/panel_layout_manager.h" | 5 #include "ash/wm/common/panels/panel_layout_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "ash/shell.h" | |
| 12 #include "ash/wm/common/shelf/wm_shelf.h" | 11 #include "ash/wm/common/shelf/wm_shelf.h" |
| 13 #include "ash/wm/common/shelf/wm_shelf_util.h" | 12 #include "ash/wm/common/shelf/wm_shelf_util.h" |
| 14 #include "ash/wm/common/window_animation_types.h" | 13 #include "ash/wm/common/window_animation_types.h" |
| 15 #include "ash/wm/common/window_parenting_utils.h" | 14 #include "ash/wm/common/window_parenting_utils.h" |
| 16 #include "ash/wm/common/window_state.h" | 15 #include "ash/wm/common/window_state.h" |
| 17 #include "ash/wm/common/wm_globals.h" | 16 #include "ash/wm/common/wm_globals.h" |
| 18 #include "ash/wm/common/wm_root_window_controller.h" | 17 #include "ash/wm/common/wm_root_window_controller.h" |
| 19 #include "ash/wm/common/wm_shell_window_ids.h" | 18 #include "ash/wm/common/wm_shell_window_ids.h" |
| 20 #include "ash/wm/common/wm_window.h" | 19 #include "ash/wm/common/wm_window.h" |
| 21 #include "ash/wm/common/wm_window_property.h" | 20 #include "ash/wm/common/wm_window_property.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 111 |
| 113 bool CompareWindowMajor(const VisiblePanelPositionInfo& win1, | 112 bool CompareWindowMajor(const VisiblePanelPositionInfo& win1, |
| 114 const VisiblePanelPositionInfo& win2) { | 113 const VisiblePanelPositionInfo& win2) { |
| 115 return win1.major_pos < win2.major_pos; | 114 return win1.major_pos < win2.major_pos; |
| 116 } | 115 } |
| 117 | 116 |
| 118 void FanOutPanels(std::vector<VisiblePanelPositionInfo>::iterator first, | 117 void FanOutPanels(std::vector<VisiblePanelPositionInfo>::iterator first, |
| 119 std::vector<VisiblePanelPositionInfo>::iterator last) { | 118 std::vector<VisiblePanelPositionInfo>::iterator last) { |
| 120 int num_panels = last - first; | 119 int num_panels = last - first; |
| 121 if (num_panels == 1) { | 120 if (num_panels == 1) { |
| 122 (*first).major_pos = std::max((*first).min_major, std::min( | 121 (*first).major_pos = std::max( |
| 123 (*first).max_major, (*first).major_pos)); | 122 (*first).min_major, std::min((*first).max_major, (*first).major_pos)); |
| 124 } | 123 } |
| 125 if (num_panels <= 1) | 124 if (num_panels <= 1) |
| 126 return; | 125 return; |
| 127 | 126 |
| 128 if (num_panels == 2) { | 127 if (num_panels == 2) { |
| 129 // If there are two adjacent overlapping windows, separate them by the | 128 // If there are two adjacent overlapping windows, separate them by the |
| 130 // minimum major_length necessary. | 129 // minimum major_length necessary. |
| 131 std::vector<VisiblePanelPositionInfo>::iterator second = first + 1; | 130 std::vector<VisiblePanelPositionInfo>::iterator second = first + 1; |
| 132 int separation = (*first).major_length / 2 + (*second).major_length / 2 + | 131 int separation = (*first).major_length / 2 + (*second).major_length / 2 + |
| 133 kPanelIdealSpacing; | 132 kPanelIdealSpacing; |
| 134 int overlap = (*first).major_pos + separation - (*second).major_pos; | 133 int overlap = (*first).major_pos + separation - (*second).major_pos; |
| 135 (*first).major_pos = std::max((*first).min_major, | 134 (*first).major_pos = |
| 136 (*first).major_pos - overlap / 2); | 135 std::max((*first).min_major, (*first).major_pos - overlap / 2); |
| 137 (*second).major_pos = std::min((*second).max_major, | 136 (*second).major_pos = |
| 138 (*first).major_pos + separation); | 137 std::min((*second).max_major, (*first).major_pos + separation); |
| 139 // Recalculate the first panel position in case the second one was | 138 // Recalculate the first panel position in case the second one was |
| 140 // constrained on the right. | 139 // constrained on the right. |
| 141 (*first).major_pos = std::max((*first).min_major, | 140 (*first).major_pos = |
| 142 (*second).major_pos - separation); | 141 std::max((*first).min_major, (*second).major_pos - separation); |
| 143 return; | 142 return; |
| 144 } | 143 } |
| 145 | 144 |
| 146 // If there are more than two overlapping windows, fan them out from minimum | 145 // If there are more than two overlapping windows, fan them out from minimum |
| 147 // position to maximum position equally spaced. | 146 // position to maximum position equally spaced. |
| 148 int delta = ((*(last - 1)).max_major - (*first).min_major) / (num_panels - 1); | 147 int delta = ((*(last - 1)).max_major - (*first).min_major) / (num_panels - 1); |
| 149 int major_pos = (*first).min_major; | 148 int major_pos = (*first).min_major; |
| 150 for (std::vector<VisiblePanelPositionInfo>::iterator iter = first; | 149 for (std::vector<VisiblePanelPositionInfo>::iterator iter = first; |
| 151 iter != last; ++iter) { | 150 iter != last; ++iter) { |
| 152 (*iter).major_pos = std::max((*iter).min_major, | 151 (*iter).major_pos = |
| 153 std::min((*iter).max_major, major_pos)); | 152 std::max((*iter).min_major, std::min((*iter).max_major, major_pos)); |
| 154 major_pos += delta; | 153 major_pos += delta; |
| 155 } | 154 } |
| 156 } | 155 } |
| 157 | 156 |
| 158 bool BoundsAdjacent(const gfx::Rect& bounds1, const gfx::Rect& bounds2) { | 157 bool BoundsAdjacent(const gfx::Rect& bounds1, const gfx::Rect& bounds2) { |
| 159 return bounds1.x() == bounds2.right() || | 158 return bounds1.x() == bounds2.right() || bounds1.y() == bounds2.bottom() || |
| 160 bounds1.y() == bounds2.bottom() || | 159 bounds1.right() == bounds2.x() || bounds1.bottom() == bounds2.y(); |
| 161 bounds1.right() == bounds2.x() || | |
| 162 bounds1.bottom() == bounds2.y(); | |
| 163 } | 160 } |
| 164 | 161 |
| 165 gfx::Vector2d GetSlideInAnimationOffset(wm::ShelfAlignment alignment) { | 162 gfx::Vector2d GetSlideInAnimationOffset(wm::ShelfAlignment alignment) { |
| 166 gfx::Vector2d offset; | 163 gfx::Vector2d offset; |
| 167 if (alignment == wm::SHELF_ALIGNMENT_LEFT) | 164 if (alignment == wm::SHELF_ALIGNMENT_LEFT) |
| 168 offset.set_x(-kPanelSlideInOffset); | 165 offset.set_x(-kPanelSlideInOffset); |
| 169 else if (alignment == wm::SHELF_ALIGNMENT_RIGHT) | 166 else if (alignment == wm::SHELF_ALIGNMENT_RIGHT) |
| 170 offset.set_x(kPanelSlideInOffset); | 167 offset.set_x(kPanelSlideInOffset); |
| 171 else | 168 else |
| 172 offset.set_y(kPanelSlideInOffset); | 169 offset.set_y(kPanelSlideInOffset); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 const int max_width = max_bounds.width() * kMaxWidthFactor; | 399 const int max_width = max_bounds.width() * kMaxWidthFactor; |
| 403 const int max_height = max_bounds.height() * kMaxHeightFactor; | 400 const int max_height = max_bounds.height() * kMaxHeightFactor; |
| 404 if (bounds.width() > max_width) | 401 if (bounds.width() > max_width) |
| 405 bounds.set_width(max_width); | 402 bounds.set_width(max_width); |
| 406 if (bounds.height() > max_height) | 403 if (bounds.height() > max_height) |
| 407 bounds.set_height(max_height); | 404 bounds.set_height(max_height); |
| 408 | 405 |
| 409 // Reposition dragged panel in the panel order. | 406 // Reposition dragged panel in the panel order. |
| 410 if (dragged_panel_ == child) { | 407 if (dragged_panel_ == child) { |
| 411 PanelList::iterator dragged_panel_iter = | 408 PanelList::iterator dragged_panel_iter = |
| 412 std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_); | 409 std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_); |
| 413 DCHECK(dragged_panel_iter != panel_windows_.end()); | 410 DCHECK(dragged_panel_iter != panel_windows_.end()); |
| 414 PanelList::iterator new_position; | 411 PanelList::iterator new_position; |
| 415 for (new_position = panel_windows_.begin(); | 412 for (new_position = panel_windows_.begin(); |
| 416 new_position != panel_windows_.end(); | 413 new_position != panel_windows_.end(); ++new_position) { |
| 417 ++new_position) { | |
| 418 const gfx::Rect& bounds = (*new_position).window->GetBounds(); | 414 const gfx::Rect& bounds = (*new_position).window->GetBounds(); |
| 419 if (bounds.x() + bounds.width() / 2 <= requested_bounds.x()) | 415 if (bounds.x() + bounds.width() / 2 <= requested_bounds.x()) |
| 420 break; | 416 break; |
| 421 } | 417 } |
| 422 if (new_position != dragged_panel_iter) { | 418 if (new_position != dragged_panel_iter) { |
| 423 PanelInfo dragged_panel_info = *dragged_panel_iter; | 419 PanelInfo dragged_panel_info = *dragged_panel_iter; |
| 424 panel_windows_.erase(dragged_panel_iter); | 420 panel_windows_.erase(dragged_panel_iter); |
| 425 panel_windows_.insert(new_position, dragged_panel_info); | 421 panel_windows_.insert(new_position, dragged_panel_info); |
| 426 } | 422 } |
| 427 } | 423 } |
| 428 // Respect the minimum size of the window. | 424 // Respect the minimum size of the window. |
| 429 if (child->HasNonClientArea()) { | 425 if (child->HasNonClientArea()) { |
| 430 const gfx::Size min_size = child->GetMinimumSize(); | 426 const gfx::Size min_size = child->GetMinimumSize(); |
| 431 bounds.set_width(std::max(min_size.width(), bounds.width())); | 427 bounds.set_width(std::max(min_size.width(), bounds.width())); |
| 432 bounds.set_height(std::max(min_size.height(), bounds.height())); | 428 bounds.set_height(std::max(min_size.height(), bounds.height())); |
| 433 } | 429 } |
| 434 | 430 |
| 435 child->SetBoundsDirect(bounds); | 431 child->SetBoundsDirect(bounds); |
| 436 Relayout(); | 432 Relayout(); |
| 437 } | 433 } |
| 438 | 434 |
| 439 //////////////////////////////////////////////////////////////////////////////// | 435 //////////////////////////////////////////////////////////////////////////////// |
| 440 // PanelLayoutManager, ash::ShellObserver implementation: | 436 // PanelLayoutManager, wm::WmShellObserver implementation: |
| 441 | 437 |
| 442 void PanelLayoutManager::OnOverviewModeEnded() { | 438 void PanelLayoutManager::OnOverviewModeEnded() { |
| 443 Relayout(); | 439 Relayout(); |
| 444 } | 440 } |
| 445 | 441 |
| 446 void PanelLayoutManager::OnShelfAlignmentChanged() { | 442 void PanelLayoutManager::OnShelfAlignmentChanged() { |
| 447 Relayout(); | 443 Relayout(); |
| 448 } | 444 } |
| 449 | 445 |
| 450 ///////////////////////////////////////////////////////////////////////////// | 446 ///////////////////////////////////////////////////////////////////////////// |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 | 633 |
| 638 if (panel->IsFocused() || | 634 if (panel->IsFocused() || |
| 639 panel->Contains(panel->GetGlobals()->GetFocusedWindow())) { | 635 panel->Contains(panel->GetGlobals()->GetFocusedWindow())) { |
| 640 DCHECK(!active_panel); | 636 DCHECK(!active_panel); |
| 641 active_panel = panel; | 637 active_panel = panel; |
| 642 } | 638 } |
| 643 icon_bounds = panel_container_->ConvertRectFromScreen(icon_bounds); | 639 icon_bounds = panel_container_->ConvertRectFromScreen(icon_bounds); |
| 644 gfx::Point icon_origin = icon_bounds.origin(); | 640 gfx::Point icon_origin = icon_bounds.origin(); |
| 645 VisiblePanelPositionInfo position_info; | 641 VisiblePanelPositionInfo position_info; |
| 646 int icon_start = horizontal ? icon_origin.x() : icon_origin.y(); | 642 int icon_start = horizontal ? icon_origin.x() : icon_origin.y(); |
| 647 int icon_end = icon_start + (horizontal ? icon_bounds.width() : | 643 int icon_end = |
| 648 icon_bounds.height()); | 644 icon_start + (horizontal ? icon_bounds.width() : icon_bounds.height()); |
| 649 position_info.major_length = | 645 position_info.major_length = |
| 650 horizontal ? panel->GetBounds().width() : panel->GetBounds().height(); | 646 horizontal ? panel->GetBounds().width() : panel->GetBounds().height(); |
| 651 position_info.min_major = std::max( | 647 position_info.min_major = |
| 652 panel_start_bounds + position_info.major_length / 2, | 648 std::max(panel_start_bounds + position_info.major_length / 2, |
| 653 icon_end - position_info.major_length / 2); | 649 icon_end - position_info.major_length / 2); |
| 654 position_info.max_major = std::min( | 650 position_info.max_major = |
| 655 icon_start + position_info.major_length / 2, | 651 std::min(icon_start + position_info.major_length / 2, |
| 656 panel_end_bounds - position_info.major_length / 2); | 652 panel_end_bounds - position_info.major_length / 2); |
| 657 position_info.major_pos = (icon_start + icon_end) / 2; | 653 position_info.major_pos = (icon_start + icon_end) / 2; |
| 658 position_info.window = panel; | 654 position_info.window = panel; |
| 659 position_info.slide_in = iter->slide_in; | 655 position_info.slide_in = iter->slide_in; |
| 660 iter->slide_in = false; | 656 iter->slide_in = false; |
| 661 visible_panels.push_back(position_info); | 657 visible_panels.push_back(position_info); |
| 662 } | 658 } |
| 663 | 659 |
| 664 // Sort panels by their X positions and fan out groups of overlapping panels. | 660 // Sort panels by their X positions and fan out groups of overlapping panels. |
| 665 // The fan out method may result in new overlapping panels however given that | 661 // The fan out method may result in new overlapping panels however given that |
| 666 // the panels start at least a full panel width apart this overlap will | 662 // the panels start at least a full panel width apart this overlap will |
| 667 // never completely obscure a panel. | 663 // never completely obscure a panel. |
| 668 // TODO(flackr): Rearrange panels if new overlaps are introduced. | 664 // TODO(flackr): Rearrange panels if new overlaps are introduced. |
| 669 std::sort(visible_panels.begin(), visible_panels.end(), CompareWindowMajor); | 665 std::sort(visible_panels.begin(), visible_panels.end(), CompareWindowMajor); |
| 670 size_t first_overlapping_panel = 0; | 666 size_t first_overlapping_panel = 0; |
| 671 for (size_t i = 1; i < visible_panels.size(); ++i) { | 667 for (size_t i = 1; i < visible_panels.size(); ++i) { |
| 672 if (visible_panels[i - 1].major_pos + | 668 if (visible_panels[i - 1].major_pos + |
| 673 visible_panels[i - 1].major_length / 2 < visible_panels[i].major_pos - | 669 visible_panels[i - 1].major_length / 2 < |
| 674 visible_panels[i].major_length / 2) { | 670 visible_panels[i].major_pos - visible_panels[i].major_length / 2) { |
| 675 FanOutPanels(visible_panels.begin() + first_overlapping_panel, | 671 FanOutPanels(visible_panels.begin() + first_overlapping_panel, |
| 676 visible_panels.begin() + i); | 672 visible_panels.begin() + i); |
| 677 first_overlapping_panel = i; | 673 first_overlapping_panel = i; |
| 678 } | 674 } |
| 679 } | 675 } |
| 680 FanOutPanels(visible_panels.begin() + first_overlapping_panel, | 676 FanOutPanels(visible_panels.begin() + first_overlapping_panel, |
| 681 visible_panels.end()); | 677 visible_panels.end()); |
| 682 | 678 |
| 683 for (size_t i = 0; i < visible_panels.size(); ++i) { | 679 for (size_t i = 0; i < visible_panels.size(); ++i) { |
| 684 if (visible_panels[i].window == dragged_panel_) | 680 if (visible_panels[i].window == dragged_panel_) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 // | 745 // |
| 750 // We use the middle of each panel to figure out how to stack the panels. This | 746 // We use the middle of each panel to figure out how to stack the panels. This |
| 751 // allows us to update the stacking when a panel is being dragged around by | 747 // allows us to update the stacking when a panel is being dragged around by |
| 752 // the titlebar--even though it doesn't update the shelf icon positions, we | 748 // the titlebar--even though it doesn't update the shelf icon positions, we |
| 753 // still want the visual effect. | 749 // still want the visual effect. |
| 754 std::map<int, wm::WmWindow*> window_ordering; | 750 std::map<int, wm::WmWindow*> window_ordering; |
| 755 const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment()); | 751 const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment()); |
| 756 for (PanelList::const_iterator it = panel_windows_.begin(); | 752 for (PanelList::const_iterator it = panel_windows_.begin(); |
| 757 it != panel_windows_.end(); ++it) { | 753 it != panel_windows_.end(); ++it) { |
| 758 gfx::Rect bounds = it->window->GetBounds(); | 754 gfx::Rect bounds = it->window->GetBounds(); |
| 759 window_ordering.insert(std::make_pair(horizontal ? | 755 window_ordering.insert( |
| 760 bounds.x() + bounds.width() / 2 : | 756 std::make_pair(horizontal ? bounds.x() + bounds.width() / 2 |
| 761 bounds.y() + bounds.height() / 2, | 757 : bounds.y() + bounds.height() / 2, |
| 762 it->window)); | 758 it->window)); |
| 763 } | 759 } |
| 764 | 760 |
| 765 wm::WmWindow* previous_panel = nullptr; | 761 wm::WmWindow* previous_panel = nullptr; |
| 766 for (std::map<int, wm::WmWindow*>::const_iterator it = | 762 for (std::map<int, wm::WmWindow*>::const_iterator it = |
| 767 window_ordering.begin(); | 763 window_ordering.begin(); |
| 768 it != window_ordering.end() && it->second != active_panel; ++it) { | 764 it != window_ordering.end() && it->second != active_panel; ++it) { |
| 769 if (previous_panel) | 765 if (previous_panel) |
| 770 panel_container_->StackChildAbove(it->second, previous_panel); | 766 panel_container_->StackChildAbove(it->second, previous_panel); |
| 771 previous_panel = it->second; | 767 previous_panel = it->second; |
| 772 } | 768 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 803 callout_widget->Hide(); | 799 callout_widget->Hide(); |
| 804 callout_widget_window->GetLayer()->SetOpacity(0); | 800 callout_widget_window->GetLayer()->SetOpacity(0); |
| 805 continue; | 801 continue; |
| 806 } | 802 } |
| 807 | 803 |
| 808 gfx::Rect callout_bounds = callout_widget->GetWindowBoundsInScreen(); | 804 gfx::Rect callout_bounds = callout_widget->GetWindowBoundsInScreen(); |
| 809 gfx::Vector2d slide_vector = bounds.origin() - current_bounds.origin(); | 805 gfx::Vector2d slide_vector = bounds.origin() - current_bounds.origin(); |
| 810 int slide_distance = horizontal ? slide_vector.x() : slide_vector.y(); | 806 int slide_distance = horizontal ? slide_vector.x() : slide_vector.y(); |
| 811 int distance_until_over_panel = 0; | 807 int distance_until_over_panel = 0; |
| 812 if (horizontal) { | 808 if (horizontal) { |
| 813 callout_bounds.set_x( | 809 callout_bounds.set_x(icon_bounds.x() + |
| 814 icon_bounds.x() + (icon_bounds.width() - callout_bounds.width()) / 2); | 810 (icon_bounds.width() - callout_bounds.width()) / 2); |
| 815 distance_until_over_panel = std::max( | 811 distance_until_over_panel = |
| 816 current_bounds.x() - callout_bounds.x(), | 812 std::max(current_bounds.x() - callout_bounds.x(), |
| 817 callout_bounds.right() - current_bounds.right()); | 813 callout_bounds.right() - current_bounds.right()); |
| 818 } else { | 814 } else { |
| 819 callout_bounds.set_y( | 815 callout_bounds.set_y(icon_bounds.y() + |
| 820 icon_bounds.y() + (icon_bounds.height() - | 816 (icon_bounds.height() - callout_bounds.height()) / |
| 821 callout_bounds.height()) / 2); | 817 2); |
| 822 distance_until_over_panel = std::max( | 818 distance_until_over_panel = |
| 823 current_bounds.y() - callout_bounds.y(), | 819 std::max(current_bounds.y() - callout_bounds.y(), |
| 824 callout_bounds.bottom() - current_bounds.bottom()); | 820 callout_bounds.bottom() - current_bounds.bottom()); |
| 825 } | 821 } |
| 826 if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_LEFT) | 822 if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_LEFT) |
| 827 callout_bounds.set_x(bounds.x() - callout_bounds.width()); | 823 callout_bounds.set_x(bounds.x() - callout_bounds.width()); |
| 828 else if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_RIGHT) | 824 else if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_RIGHT) |
| 829 callout_bounds.set_x(bounds.right()); | 825 callout_bounds.set_x(bounds.right()); |
| 830 else | 826 else |
| 831 callout_bounds.set_y(bounds.bottom()); | 827 callout_bounds.set_y(bounds.bottom()); |
| 832 callout_bounds = callout_widget_window->GetParent()->ConvertRectFromScreen( | 828 callout_bounds = callout_widget_window->GetParent()->ConvertRectFromScreen( |
| 833 callout_bounds); | 829 callout_bounds); |
| 834 | 830 |
| 835 callout_widget_window->SetBoundsDirect(callout_bounds); | 831 callout_widget_window->SetBoundsDirect(callout_bounds); |
| 836 panel_container_->StackChildAbove(callout_widget_window, panel); | 832 panel_container_->StackChildAbove(callout_widget_window, panel); |
| 837 | 833 |
| 838 ui::Layer* layer = callout_widget_window->GetLayer(); | 834 ui::Layer* layer = callout_widget_window->GetLayer(); |
| 839 // If the panel is not over the callout position or has just become visible | 835 // If the panel is not over the callout position or has just become visible |
| 840 // then fade in the callout. | 836 // then fade in the callout. |
| 841 if ((distance_until_over_panel > 0 || layer->GetTargetOpacity() < 1)) { | 837 if ((distance_until_over_panel > 0 || layer->GetTargetOpacity() < 1)) { |
| 842 if (distance_until_over_panel > 0 && | 838 if (distance_until_over_panel > 0 && |
| 843 slide_distance >= distance_until_over_panel) { | 839 slide_distance >= distance_until_over_panel) { |
| 844 // If the panel is not yet over the callout, then delay fading in | 840 // If the panel is not yet over the callout, then delay fading in |
| 845 // the callout until after the panel should be over it. | 841 // the callout until after the panel should be over it. |
| 846 int delay = kPanelSlideDurationMilliseconds * | 842 int delay = kPanelSlideDurationMilliseconds * |
| 847 distance_until_over_panel / slide_distance; | 843 distance_until_over_panel / slide_distance; |
| 848 layer->SetOpacity(0); | 844 layer->SetOpacity(0); |
| 849 layer->GetAnimator()->StopAnimating(); | 845 layer->GetAnimator()->StopAnimating(); |
| 850 layer->GetAnimator()->SchedulePauseForProperties( | 846 layer->GetAnimator()->SchedulePauseForProperties( |
| 851 base::TimeDelta::FromMilliseconds(delay), | 847 base::TimeDelta::FromMilliseconds(delay), |
| 852 ui::LayerAnimationElement::OPACITY); | 848 ui::LayerAnimationElement::OPACITY); |
| 853 } | 849 } |
| 854 ui::ScopedLayerAnimationSettings callout_settings(layer->GetAnimator()); | 850 ui::ScopedLayerAnimationSettings callout_settings(layer->GetAnimator()); |
| 855 callout_settings.SetPreemptionStrategy( | 851 callout_settings.SetPreemptionStrategy( |
| 856 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); | 852 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); |
| 857 callout_settings.SetTransitionDuration( | 853 callout_settings.SetTransitionDuration( |
| 858 base::TimeDelta::FromMilliseconds( | 854 base::TimeDelta::FromMilliseconds(kCalloutFadeDurationMilliseconds)); |
| 859 kCalloutFadeDurationMilliseconds)); | |
| 860 layer->SetOpacity(1); | 855 layer->SetOpacity(1); |
| 861 } | 856 } |
| 862 | 857 |
| 863 // Show after changing the opacity animation. This way we don't have a | 858 // Show after changing the opacity animation. This way we don't have a |
| 864 // state where the widget is visible but the opacity is 0. | 859 // state where the widget is visible but the opacity is 0. |
| 865 callout_widget->Show(); | 860 callout_widget->Show(); |
| 866 } | 861 } |
| 867 } | 862 } |
| 868 | 863 |
| 869 //////////////////////////////////////////////////////////////////////////////// | 864 //////////////////////////////////////////////////////////////////////////////// |
| 870 // keyboard::KeyboardControllerObserver implementation: | 865 // keyboard::KeyboardControllerObserver implementation: |
| 871 | 866 |
| 872 void PanelLayoutManager::OnKeyboardBoundsChanging( | 867 void PanelLayoutManager::OnKeyboardBoundsChanging( |
| 873 const gfx::Rect& keyboard_bounds) { | 868 const gfx::Rect& keyboard_bounds) { |
| 874 gfx::Rect parent_bounds = panel_container_->GetBounds(); | 869 gfx::Rect parent_bounds = panel_container_->GetBounds(); |
| 875 int available_space = parent_bounds.height() - keyboard_bounds.height(); | 870 int available_space = parent_bounds.height() - keyboard_bounds.height(); |
| 876 for (PanelList::iterator iter = panel_windows_.begin(); | 871 for (PanelList::iterator iter = panel_windows_.begin(); |
| 877 iter != panel_windows_.end(); | 872 iter != panel_windows_.end(); ++iter) { |
| 878 ++iter) { | |
| 879 wm::WmWindow* panel = iter->window; | 873 wm::WmWindow* panel = iter->window; |
| 880 wm::WindowState* panel_state = panel->GetWindowState(); | 874 wm::WindowState* panel_state = panel->GetWindowState(); |
| 881 if (keyboard_bounds.height() > 0) { | 875 if (keyboard_bounds.height() > 0) { |
| 882 // Save existing bounds, so that we can restore them when the keyboard | 876 // Save existing bounds, so that we can restore them when the keyboard |
| 883 // hides. | 877 // hides. |
| 884 panel_state->SaveCurrentBoundsForRestore(); | 878 panel_state->SaveCurrentBoundsForRestore(); |
| 885 | 879 |
| 886 gfx::Rect panel_bounds = | 880 gfx::Rect panel_bounds = |
| 887 panel->GetParent()->ConvertRectToScreen(panel->GetTargetBounds()); | 881 panel->GetParent()->ConvertRectToScreen(panel->GetTargetBounds()); |
| 888 int delta = panel_bounds.height() - available_space; | 882 int delta = panel_bounds.height() - available_space; |
| 889 // Ensure panels are not pushed above the parent boundaries, shrink any | 883 // Ensure panels are not pushed above the parent boundaries, shrink any |
| 890 // panels that violate this constraint. | 884 // panels that violate this constraint. |
| 891 if (delta > 0) { | 885 if (delta > 0) { |
| 892 panel->SetBoundsDirect( | 886 panel->SetBoundsDirect( |
| 893 gfx::Rect(panel_bounds.x(), panel_bounds.y() + delta, | 887 gfx::Rect(panel_bounds.x(), panel_bounds.y() + delta, |
| 894 panel_bounds.width(), panel_bounds.height() - delta)); | 888 panel_bounds.width(), panel_bounds.height() - delta)); |
| 895 } | 889 } |
| 896 } else if (panel_state->HasRestoreBounds()) { | 890 } else if (panel_state->HasRestoreBounds()) { |
| 897 // Keyboard hidden, restore original bounds if they exist. | 891 // Keyboard hidden, restore original bounds if they exist. |
| 898 panel->SetBoundsDirect(panel_state->GetRestoreBoundsInScreen()); | 892 panel->SetBoundsDirect(panel_state->GetRestoreBoundsInScreen()); |
| 899 } | 893 } |
| 900 } | 894 } |
| 901 // This bounds change will have caused a change to the Shelf which does not | 895 // This bounds change will have caused a change to the Shelf which does not |
| 902 // propogate automatically to this class, so manually recalculate bounds. | 896 // propogate automatically to this class, so manually recalculate bounds. |
| 903 OnWindowResized(); | 897 OnWindowResized(); |
| 904 } | 898 } |
| 905 | 899 |
| 906 } // namespace ash | 900 } // namespace ash |
| OLD | NEW |