Chromium Code Reviews| 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)); |
|
James Cook
2014/01/06 21:06:53
nit: Don't need parens around GetWindowHeight().
varkha
2014/01/06 21:14:05
Done.
| |
| 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 = (float)available_room / |
|
James Cook
2014/01/06 21:06:53
nit: static_cast<float>
varkha
2014/01/06 21:14:05
Done.
| |
| 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 |