OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/dock/docked_window_layout_manager.h" | 5 #include "ash/wm/dock/docked_window_layout_manager.h" |
6 | 6 |
7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/screen_ash.h" | 8 #include "ash/screen_ash.h" |
9 #include "ash/shelf/shelf.h" | 9 #include "ash/shelf/shelf.h" |
10 #include "ash/shelf/shelf_constants.h" | 10 #include "ash/shelf/shelf_constants.h" |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 (!wm::GetWindowState(window)->CanResize() || | 543 (!wm::GetWindowState(window)->CanResize() || |
544 (window->delegate() && | 544 (window->delegate() && |
545 window->delegate()->GetMinimumSize().width() != 0 && | 545 window->delegate()->GetMinimumSize().width() != 0 && |
546 window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { | 546 window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { |
547 return false; | 547 return false; |
548 } | 548 } |
549 // If a window is tall and cannot be resized down to maximum height allowed | 549 // If a window is tall and cannot be resized down to maximum height allowed |
550 // then it cannot be docked. | 550 // then it cannot be docked. |
551 const gfx::Rect work_area = | 551 const gfx::Rect work_area = |
552 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); | 552 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
553 if (GetWindowHeightCloseTo(window, work_area.height() - 2 * kMinDockGap) > | 553 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) |
554 work_area.height() - 2 * kMinDockGap) { | |
555 return false; | 554 return false; |
556 } | |
557 // Cannot dock on the other size from an existing dock. | 555 // Cannot dock on the other size from an existing dock. |
558 const DockedAlignment alignment = CalculateAlignment(); | 556 const DockedAlignment alignment = CalculateAlignment(); |
559 if ((edge == SNAP_LEFT && alignment == DOCKED_ALIGNMENT_RIGHT) || | 557 if ((edge == SNAP_LEFT && alignment == DOCKED_ALIGNMENT_RIGHT) || |
560 (edge == SNAP_RIGHT && alignment == DOCKED_ALIGNMENT_LEFT)) { | 558 (edge == SNAP_RIGHT && alignment == DOCKED_ALIGNMENT_LEFT)) { |
561 return false; | 559 return false; |
562 } | 560 } |
563 // Do not allow docking on the same side as shelf. | 561 // Do not allow docking on the same side as shelf. |
564 ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; | 562 ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; |
565 if (shelf_) | 563 if (shelf_) |
566 shelf_alignment = shelf_->alignment(); | 564 shelf_alignment = shelf_->alignment(); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 } | 809 } |
812 | 810 |
813 //////////////////////////////////////////////////////////////////////////////// | 811 //////////////////////////////////////////////////////////////////////////////// |
814 // DockedWindowLayoutManager private implementation: | 812 // DockedWindowLayoutManager private implementation: |
815 | 813 |
816 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( | 814 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( |
817 aura::Window* child) { | 815 aura::Window* child) { |
818 // Minimize any windows that don't fit without overlap. | 816 // Minimize any windows that don't fit without overlap. |
819 const gfx::Rect work_area = | 817 const gfx::Rect work_area = |
820 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); | 818 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
821 int available_room = work_area.height() - kMinDockGap; | 819 int available_room = work_area.height(); |
| 820 bool gap_needed = !!child; |
822 if (child) | 821 if (child) |
823 available_room -= (GetWindowHeightCloseTo(child, 0) + kMinDockGap); | 822 available_room -= GetWindowHeightCloseTo(child, 0); |
824 // Use a copy of children array because a call to Minimize can change order. | 823 // Use a copy of children array because a call to Minimize can change order. |
825 aura::Window::Windows children(dock_container_->children()); | 824 aura::Window::Windows children(dock_container_->children()); |
826 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); | 825 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); |
827 while (iter != children.rend()) { | 826 while (iter != children.rend()) { |
828 aura::Window* window(*iter++); | 827 aura::Window* window(*iter++); |
829 if (window == child || !IsUsedByLayout(window)) | 828 if (window == child || !IsUsedByLayout(window)) |
830 continue; | 829 continue; |
831 int room_needed = GetWindowHeightCloseTo(window, 0) + kMinDockGap; | 830 int room_needed = GetWindowHeightCloseTo(window, 0) + |
| 831 (gap_needed ? kMinDockGap : 0); |
| 832 gap_needed = true; |
832 if (available_room > room_needed) { | 833 if (available_room > room_needed) { |
833 available_room -= room_needed; | 834 available_room -= room_needed; |
834 } else { | 835 } else { |
835 // Slow down minimizing animations. Lock duration so that it is not | 836 // Slow down minimizing animations. Lock duration so that it is not |
836 // overridden by other ScopedLayerAnimationSettings down the stack. | 837 // overridden by other ScopedLayerAnimationSettings down the stack. |
837 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 838 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
838 settings.SetTransitionDuration( | 839 settings.SetTransitionDuration( |
839 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); | 840 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); |
840 settings.LockTransitionDuration(); | 841 settings.LockTransitionDuration(); |
841 wm::GetWindowState(window)->Minimize(); | 842 wm::GetWindowState(window)->Minimize(); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 | 1002 |
1002 // After the first Relayout allow the windows to change their order easier | 1003 // After the first Relayout allow the windows to change their order easier |
1003 // since we know they are docked. | 1004 // since we know they are docked. |
1004 is_dragged_from_dock_ = true; | 1005 is_dragged_from_dock_ = true; |
1005 UpdateStacking(active_window); | 1006 UpdateStacking(active_window); |
1006 } | 1007 } |
1007 | 1008 |
1008 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( | 1009 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( |
1009 const gfx::Rect work_area, | 1010 const gfx::Rect work_area, |
1010 std::vector<WindowWithHeight>* visible_windows) { | 1011 std::vector<WindowWithHeight>* visible_windows) { |
1011 int available_room = work_area.height() - kMinDockGap; | 1012 int available_room = work_area.height(); |
1012 int remaining_windows = visible_windows->size(); | 1013 int remaining_windows = visible_windows->size(); |
| 1014 int gap_height = remaining_windows > 1 ? kMinDockGap : 0; |
1013 | 1015 |
1014 // Sort windows by their minimum heights and calculate target heights. | 1016 // Sort windows by their minimum heights and calculate target heights. |
1015 std::sort(visible_windows->begin(), visible_windows->end(), | 1017 std::sort(visible_windows->begin(), visible_windows->end(), |
1016 CompareMinimumHeight()); | 1018 CompareMinimumHeight()); |
1017 // Distribute the free space among the docked windows. Since the windows are | 1019 // Distribute the free space among the docked windows. Since the windows are |
1018 // sorted (tall windows first) we can now assume that any window which | 1020 // sorted (tall windows first) we can now assume that any window which |
1019 // required more space than the current window will have already been | 1021 // required more space than the current window will have already been |
1020 // accounted for previously in this loop, so we can safely give that window | 1022 // accounted for previously in this loop, so we can safely give that window |
1021 // its proportional share of the remaining space. | 1023 // its proportional share of the remaining space. |
1022 for (std::vector<WindowWithHeight>::reverse_iterator iter = | 1024 for (std::vector<WindowWithHeight>::reverse_iterator iter = |
1023 visible_windows->rbegin(); | 1025 visible_windows->rbegin(); |
1024 iter != visible_windows->rend(); ++iter) { | 1026 iter != visible_windows->rend(); ++iter) { |
1025 iter->height_ = GetWindowHeightCloseTo( | 1027 iter->height_ = GetWindowHeightCloseTo( |
1026 iter->window(), available_room / remaining_windows - kMinDockGap); | 1028 iter->window(), |
1027 available_room -= (iter->height_ + kMinDockGap); | 1029 (available_room + gap_height) / remaining_windows - gap_height); |
| 1030 available_room -= (iter->height_ + gap_height); |
1028 remaining_windows--; | 1031 remaining_windows--; |
1029 } | 1032 } |
1030 return available_room; | 1033 return available_room + gap_height; |
1031 } | 1034 } |
1032 | 1035 |
1033 int DockedWindowLayoutManager::CalculateIdealWidth( | 1036 int DockedWindowLayoutManager::CalculateIdealWidth( |
1034 const std::vector<WindowWithHeight>& visible_windows) { | 1037 const std::vector<WindowWithHeight>& visible_windows) { |
1035 int smallest_max_width = kMaxDockWidth; | 1038 int smallest_max_width = kMaxDockWidth; |
1036 int largest_min_width = kMinDockWidth; | 1039 int largest_min_width = kMinDockWidth; |
1037 // Ideal width of the docked area is as close to kIdealWidth as possible | 1040 // Ideal width of the docked area is as close to kIdealWidth as possible |
1038 // while still respecting the minimum and maximum width restrictions on the | 1041 // while still respecting the minimum and maximum width restrictions on the |
1039 // individual docked windows as well as the width that was possibly set by a | 1042 // individual docked windows as well as the width that was possibly set by a |
1040 // user (which needs to be preserved when dragging and rearranging windows). | 1043 // user (which needs to be preserved when dragging and rearranging windows). |
(...skipping 19 matching lines...) Expand all Loading... |
1060 | 1063 |
1061 void DockedWindowLayoutManager::FanOutChildren( | 1064 void DockedWindowLayoutManager::FanOutChildren( |
1062 const gfx::Rect& work_area, | 1065 const gfx::Rect& work_area, |
1063 int ideal_docked_width, | 1066 int ideal_docked_width, |
1064 int available_room, | 1067 int available_room, |
1065 std::vector<WindowWithHeight>* visible_windows) { | 1068 std::vector<WindowWithHeight>* visible_windows) { |
1066 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); | 1069 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); |
1067 | 1070 |
1068 // Calculate initial vertical offset and the gap or overlap between windows. | 1071 // Calculate initial vertical offset and the gap or overlap between windows. |
1069 const int num_windows = visible_windows->size(); | 1072 const int num_windows = visible_windows->size(); |
1070 const float delta = kMinDockGap + (float)available_room / | 1073 const float delta = static_cast<float>(available_room) / |
1071 ((available_room > 0 || num_windows <= 1) ? | 1074 ((available_room > 0 || num_windows <= 1) ? |
1072 num_windows + 1 : num_windows - 1); | 1075 num_windows + 1 : num_windows - 1); |
1073 float y_pos = work_area.y() + ((delta > 0) ? delta : kMinDockGap); | 1076 float y_pos = work_area.y() + ((delta > 0) ? delta : 0); |
1074 | 1077 |
1075 // Docked area is shown only if there is at least one non-dragged visible | 1078 // Docked area is shown only if there is at least one non-dragged visible |
1076 // docked window. | 1079 // docked window. |
1077 int new_width = ideal_docked_width; | 1080 int new_width = ideal_docked_width; |
1078 if (visible_windows->empty() || | 1081 if (visible_windows->empty() || |
1079 (visible_windows->size() == 1 && | 1082 (visible_windows->size() == 1 && |
1080 (*visible_windows)[0].window() == dragged_window_)) { | 1083 (*visible_windows)[0].window() == dragged_window_)) { |
1081 new_width = 0; | 1084 new_width = 0; |
1082 } | 1085 } |
1083 UpdateDockedWidth(new_width); | 1086 UpdateDockedWidth(new_width); |
(...skipping 22 matching lines...) Expand all Loading... |
1106 alignment = GetAlignmentOfWindow(window); | 1109 alignment = GetAlignmentOfWindow(window); |
1107 if (alignment == DOCKED_ALIGNMENT_NONE) | 1110 if (alignment == DOCKED_ALIGNMENT_NONE) |
1108 bounds.set_size(gfx::Size()); | 1111 bounds.set_size(gfx::Size()); |
1109 } | 1112 } |
1110 | 1113 |
1111 // Fan out windows evenly distributing the overlap or remaining free space. | 1114 // Fan out windows evenly distributing the overlap or remaining free space. |
1112 bounds.set_height(iter->height_); | 1115 bounds.set_height(iter->height_); |
1113 bounds.set_y(std::max(work_area.y(), | 1116 bounds.set_y(std::max(work_area.y(), |
1114 std::min(work_area.bottom() - bounds.height(), | 1117 std::min(work_area.bottom() - bounds.height(), |
1115 static_cast<int>(y_pos + 0.5)))); | 1118 static_cast<int>(y_pos + 0.5)))); |
1116 y_pos += bounds.height() + delta; | 1119 y_pos += bounds.height() + delta + kMinDockGap; |
1117 | 1120 |
1118 // All docked windows other than the one currently dragged remain stuck | 1121 // All docked windows other than the one currently dragged remain stuck |
1119 // to the screen edge (flush with the edge or centered in the dock area). | 1122 // to the screen edge (flush with the edge or centered in the dock area). |
1120 switch (alignment) { | 1123 switch (alignment) { |
1121 case DOCKED_ALIGNMENT_LEFT: | 1124 case DOCKED_ALIGNMENT_LEFT: |
1122 bounds.set_x(dock_bounds.x() + | 1125 bounds.set_x(dock_bounds.x() + |
1123 (ideal_docked_width - bounds.width()) / 2); | 1126 (ideal_docked_width - bounds.width()) / 2); |
1124 break; | 1127 break; |
1125 case DOCKED_ALIGNMENT_RIGHT: | 1128 case DOCKED_ALIGNMENT_RIGHT: |
1126 bounds.set_x(dock_bounds.right() - | 1129 bounds.set_x(dock_bounds.right() - |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1242 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
1240 const gfx::Rect& keyboard_bounds) { | 1243 const gfx::Rect& keyboard_bounds) { |
1241 // This bounds change will have caused a change to the Shelf which does not | 1244 // This bounds change will have caused a change to the Shelf which does not |
1242 // propagate automatically to this class, so manually recalculate bounds. | 1245 // propagate automatically to this class, so manually recalculate bounds. |
1243 Relayout(); | 1246 Relayout(); |
1244 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1247 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
1245 } | 1248 } |
1246 | 1249 |
1247 } // namespace internal | 1250 } // namespace internal |
1248 } // namespace ash | 1251 } // namespace ash |
OLD | NEW |