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/shelf/shelf_view.h" | 5 #include "ash/shelf/shelf_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "ash/ash_constants.h" | 10 #include "ash/ash_constants.h" |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 } | 721 } |
722 | 722 |
723 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { | 723 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { |
724 // The overflow button is not shown in overflow mode. | 724 // The overflow button is not shown in overflow mode. |
725 overflow_button_->SetVisible(false); | 725 overflow_button_->SetVisible(false); |
726 DCHECK_LT(last_visible_index_, view_model_->view_size()); | 726 DCHECK_LT(last_visible_index_, view_model_->view_size()); |
727 for (int i = 0; i < view_model_->view_size(); ++i) { | 727 for (int i = 0; i < view_model_->view_size(); ++i) { |
728 bool visible = i >= first_visible_index_ && i <= last_visible_index_; | 728 bool visible = i >= first_visible_index_ && i <= last_visible_index_; |
729 // To track the dragging of |drag_view_| continuously, its visibility | 729 // To track the dragging of |drag_view_| continuously, its visibility |
730 // should be always true regardless of its position. | 730 // should be always true regardless of its position. |
731 if (dragged_off_from_overflow_to_shelf_ && | 731 if (dragged_to_another_shelf_ && view_model_->view_at(i) == drag_view_) |
732 view_model_->view_at(i) == drag_view_) | |
733 view_model_->view_at(i)->SetVisible(true); | 732 view_model_->view_at(i)->SetVisible(true); |
734 else | 733 else |
735 view_model_->view_at(i)->SetVisible(visible); | 734 view_model_->view_at(i)->SetVisible(visible); |
736 } | 735 } |
737 } | 736 } |
738 | 737 |
739 void ShelfView::CalculateIdealBounds(gfx::Rect* overflow_bounds) const { | 738 void ShelfView::CalculateIdealBounds(gfx::Rect* overflow_bounds) const { |
740 DCHECK(model_->item_count() == view_model_->view_size()); | 739 DCHECK(model_->item_count() == view_model_->view_size()); |
741 | 740 |
742 int available_size = wm_shelf_->PrimaryAxisValue(width(), height()); | 741 int available_size = wm_shelf_->PrimaryAxisValue(width(), height()); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 | 1026 |
1028 if (target_index == current_index) | 1027 if (target_index == current_index) |
1029 return; | 1028 return; |
1030 | 1029 |
1031 // Change the model, the ShelfItemMoved() callback will handle the | 1030 // Change the model, the ShelfItemMoved() callback will handle the |
1032 // |view_model_| update. | 1031 // |view_model_| update. |
1033 model_->Move(current_index, target_index); | 1032 model_->Move(current_index, target_index); |
1034 bounds_animator_->StopAnimatingView(drag_view_); | 1033 bounds_animator_->StopAnimatingView(drag_view_); |
1035 } | 1034 } |
1036 | 1035 |
| 1036 void ShelfView::EndDragOnOtherShelf(bool cancel) { |
| 1037 if (is_overflow_mode()) { |
| 1038 main_shelf_->EndDrag(cancel); |
| 1039 } else { |
| 1040 DCHECK(overflow_bubble_->IsShowing()); |
| 1041 overflow_bubble_->shelf_view()->EndDrag(cancel); |
| 1042 } |
| 1043 } |
| 1044 |
1037 bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) { | 1045 bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) { |
1038 int current_index = view_model_->GetIndexOfView(drag_view_); | 1046 int current_index = view_model_->GetIndexOfView(drag_view_); |
1039 DCHECK_NE(-1, current_index); | 1047 DCHECK_NE(-1, current_index); |
1040 std::string dragged_app_id = | 1048 std::string dragged_app_id = |
1041 model_->GetAppIDForShelfID(model_->items()[current_index].id); | 1049 model_->GetAppIDForShelfID(model_->items()[current_index].id); |
1042 | 1050 |
1043 gfx::Point screen_location = | 1051 gfx::Point screen_location = |
1044 WmWindow::Get(GetWidget()->GetNativeWindow()) | 1052 WmWindow::Get(GetWidget()->GetNativeWindow()) |
1045 ->GetRootWindow() | 1053 ->GetRootWindow() |
1046 ->ConvertPointToScreen(event.root_location()); | 1054 ->ConvertPointToScreen(event.root_location()); |
1047 | 1055 |
1048 // To avoid ugly forwards and backwards flipping we use different constants | 1056 // To avoid ugly forwards and backwards flipping we use different constants |
1049 // for ripping off / re-inserting the items. | 1057 // for ripping off / re-inserting the items. |
1050 if (dragged_off_shelf_) { | 1058 if (dragged_off_shelf_) { |
1051 // If the shelf/overflow bubble bounds contains |screen_location| we insert | 1059 // If the shelf/overflow bubble bounds contains |screen_location| we insert |
1052 // the item back into the shelf. | 1060 // the item back into the shelf. |
1053 if (GetBoundsForDragInsertInScreen().Contains(screen_location)) { | 1061 if (GetBoundsForDragInsertInScreen().Contains(screen_location)) { |
1054 if (dragged_off_from_overflow_to_shelf_) { | 1062 if (dragged_to_another_shelf_) { |
1055 // During the dragging an item from Shelf to Overflow, it can enter here | 1063 // During the dragging an item from Shelf to Overflow, it can enter here |
1056 // directly because both are located very closly. | 1064 // directly because both are located very closely. |
1057 main_shelf_->EndDrag(true); | 1065 EndDragOnOtherShelf(true /* cancel */); |
| 1066 |
1058 // Stops the animation of |drag_view_| and sets its bounds explicitly | 1067 // Stops the animation of |drag_view_| and sets its bounds explicitly |
1059 // becase ContinueDrag() stops its animation. Without this, unexpected | 1068 // because ContinueDrag() stops its animation. Without this, unexpected |
1060 // bounds will be set. | 1069 // bounds will be set. |
1061 bounds_animator_->StopAnimatingView(drag_view_); | 1070 bounds_animator_->StopAnimatingView(drag_view_); |
1062 int drag_view_index = view_model_->GetIndexOfView(drag_view_); | 1071 int drag_view_index = view_model_->GetIndexOfView(drag_view_); |
1063 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); | 1072 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); |
1064 dragged_off_from_overflow_to_shelf_ = false; | 1073 dragged_to_another_shelf_ = false; |
1065 } | 1074 } |
1066 // Destroy our proxy view item. | 1075 // Destroy our proxy view item. |
1067 DestroyDragIconProxy(); | 1076 DestroyDragIconProxy(); |
1068 // Re-insert the item and return simply false since the caller will handle | 1077 // Re-insert the item and return simply false since the caller will handle |
1069 // the move as in any normal case. | 1078 // the move as in any normal case. |
1070 dragged_off_shelf_ = false; | 1079 dragged_off_shelf_ = false; |
1071 drag_view_->layer()->SetOpacity(1.0f); | 1080 drag_view_->layer()->SetOpacity(1.0f); |
1072 // The size of Overflow bubble should be updated immediately when an item | 1081 // The size of Overflow bubble should be updated immediately when an item |
1073 // is re-inserted. | 1082 // is re-inserted. |
1074 if (is_overflow_mode()) | 1083 if (is_overflow_mode()) |
1075 PreferredSizeChanged(); | 1084 PreferredSizeChanged(); |
1076 return false; | 1085 return false; |
1077 } else if (is_overflow_mode() && | 1086 } else if (is_overflow_mode() && |
1078 main_shelf_->GetBoundsForDragInsertInScreen().Contains( | 1087 main_shelf_->GetBoundsForDragInsertInScreen().Contains( |
1079 screen_location)) { | 1088 screen_location)) { |
1080 if (!dragged_off_from_overflow_to_shelf_) { | 1089 // The item was dragged from the overflow shelf to the main shelf. |
1081 dragged_off_from_overflow_to_shelf_ = true; | 1090 if (!dragged_to_another_shelf_) { |
| 1091 dragged_to_another_shelf_ = true; |
1082 drag_image_->SetOpacity(1.0f); | 1092 drag_image_->SetOpacity(1.0f); |
1083 main_shelf_->StartDrag(dragged_app_id, screen_location); | 1093 main_shelf_->StartDrag(dragged_app_id, screen_location); |
1084 } else { | 1094 } else { |
1085 main_shelf_->Drag(screen_location); | 1095 main_shelf_->Drag(screen_location); |
1086 } | 1096 } |
1087 } else if (dragged_off_from_overflow_to_shelf_) { | 1097 } else if (!is_overflow_mode() && overflow_bubble_ && |
| 1098 overflow_bubble_->IsShowing() && |
| 1099 overflow_bubble_->shelf_view() |
| 1100 ->GetBoundsForDragInsertInScreen() |
| 1101 .Contains(screen_location)) { |
| 1102 // The item was dragged from the main shelf to the overflow shelf. |
| 1103 if (!dragged_to_another_shelf_) { |
| 1104 dragged_to_another_shelf_ = true; |
| 1105 drag_image_->SetOpacity(1.0f); |
| 1106 overflow_bubble_->shelf_view()->StartDrag(dragged_app_id, |
| 1107 screen_location); |
| 1108 } else { |
| 1109 overflow_bubble_->shelf_view()->Drag(screen_location); |
| 1110 } |
| 1111 } else if (dragged_to_another_shelf_) { |
1088 // Makes the |drag_image_| partially disappear again. | 1112 // Makes the |drag_image_| partially disappear again. |
1089 dragged_off_from_overflow_to_shelf_ = false; | 1113 dragged_to_another_shelf_ = false; |
1090 drag_image_->SetOpacity(kDraggedImageOpacity); | 1114 drag_image_->SetOpacity(kDraggedImageOpacity); |
1091 main_shelf_->EndDrag(true); | 1115 |
| 1116 EndDragOnOtherShelf(true /* cancel */); |
| 1117 if (!is_overflow_mode()) { |
| 1118 // During dragging, the position of the dragged item is moved to the |
| 1119 // back. If the overflow bubble is showing, a copy of the dragged item |
| 1120 // will appear at the end of the overflow shelf. Decrement the last |
| 1121 // visible index of the overflow shelf to hide this copy. |
| 1122 overflow_bubble_->shelf_view()->last_visible_index_--; |
| 1123 } |
| 1124 |
1092 bounds_animator_->StopAnimatingView(drag_view_); | 1125 bounds_animator_->StopAnimatingView(drag_view_); |
1093 int drag_view_index = view_model_->GetIndexOfView(drag_view_); | 1126 int drag_view_index = view_model_->GetIndexOfView(drag_view_); |
1094 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); | 1127 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); |
1095 } | 1128 } |
1096 // Move our proxy view item. | 1129 // Move our proxy view item. |
1097 UpdateDragIconProxy(screen_location); | 1130 UpdateDragIconProxy(screen_location); |
1098 return true; | 1131 return true; |
1099 } | 1132 } |
1100 // Check if we are too far away from the shelf to enter the ripped off state. | 1133 // Check if we are too far away from the shelf to enter the ripped off state. |
1101 // Determine the distance to the shelf. | 1134 // Determine the distance to the shelf. |
1102 int delta = CalculateShelfDistance(screen_location); | 1135 int delta = CalculateShelfDistance(screen_location); |
1103 if (delta > kRipOffDistance) { | 1136 if (delta > kRipOffDistance) { |
1104 // Create a proxy view item which can be moved anywhere. | 1137 // Create a proxy view item which can be moved anywhere. |
1105 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(), | 1138 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(), |
1106 drag_view_, gfx::Vector2d(0, 0), | 1139 drag_view_, gfx::Vector2d(0, 0), |
1107 kDragAndDropProxyScale); | 1140 kDragAndDropProxyScale); |
1108 drag_view_->layer()->SetOpacity(0.0f); | 1141 drag_view_->layer()->SetOpacity(0.0f); |
1109 dragged_off_shelf_ = true; | 1142 dragged_off_shelf_ = true; |
1110 if (RemovableByRipOff(current_index) == REMOVABLE) { | 1143 if (RemovableByRipOff(current_index) == REMOVABLE) { |
1111 // Move the item to the front of the first panel item and hide it. | 1144 // Move the item to the front of the first panel item and hide it. |
1112 // ShelfItemMoved() callback will handle the |view_model_| update and | 1145 // ShelfItemMoved() callback will handle the |view_model_| update and |
1113 // call AnimateToIdealBounds(). | 1146 // call AnimateToIdealBounds(). |
1114 if (current_index != model_->FirstPanelIndex() - 1) { | 1147 if (current_index != model_->FirstPanelIndex() - 1) { |
1115 model_->Move(current_index, model_->FirstPanelIndex() - 1); | 1148 model_->Move(current_index, model_->FirstPanelIndex() - 1); |
1116 StartFadeInLastVisibleItem(); | 1149 StartFadeInLastVisibleItem(); |
| 1150 |
| 1151 // During dragging, the position of the dragged item is moved to the |
| 1152 // back. If the overflow bubble is showing, a copy of the dragged item |
| 1153 // will appear at the end of the overflow shelf. Decrement the last |
| 1154 // visible index of the overflow shelf to hide this copy. |
| 1155 if (overflow_bubble_ && overflow_bubble_->IsShowing()) |
| 1156 overflow_bubble_->shelf_view()->last_visible_index_--; |
1117 } else if (is_overflow_mode()) { | 1157 } else if (is_overflow_mode()) { |
1118 // Overflow bubble should be shrunk when an item is ripped off. | 1158 // Overflow bubble should be shrunk when an item is ripped off. |
1119 PreferredSizeChanged(); | 1159 PreferredSizeChanged(); |
1120 } | 1160 } |
1121 // Make the item partially disappear to show that it will get removed if | 1161 // Make the item partially disappear to show that it will get removed if |
1122 // dropped. | 1162 // dropped. |
1123 drag_image_->SetOpacity(kDraggedImageOpacity); | 1163 drag_image_->SetOpacity(kDraggedImageOpacity); |
1124 } | 1164 } |
1125 return true; | 1165 return true; |
1126 } | 1166 } |
(...skipping 14 matching lines...) Expand all Loading... |
1141 // and only delete the proxy image. | 1181 // and only delete the proxy image. |
1142 if (current_index == -1) { | 1182 if (current_index == -1) { |
1143 DestroyDragIconProxy(); | 1183 DestroyDragIconProxy(); |
1144 return; | 1184 return; |
1145 } | 1185 } |
1146 | 1186 |
1147 // Set to true when the animation should snap back to where it was before. | 1187 // Set to true when the animation should snap back to where it was before. |
1148 bool snap_back = false; | 1188 bool snap_back = false; |
1149 // Items which cannot be dragged off will be handled as a cancel. | 1189 // Items which cannot be dragged off will be handled as a cancel. |
1150 if (!cancel) { | 1190 if (!cancel) { |
1151 if (dragged_off_from_overflow_to_shelf_) { | 1191 if (dragged_to_another_shelf_) { |
1152 dragged_off_from_overflow_to_shelf_ = false; | 1192 dragged_to_another_shelf_ = false; |
1153 main_shelf_->EndDrag(false); | 1193 EndDragOnOtherShelf(false /* cancel */); |
1154 drag_view_->layer()->SetOpacity(1.0f); | 1194 drag_view_->layer()->SetOpacity(1.0f); |
1155 } else if (RemovableByRipOff(current_index) != REMOVABLE) { | 1195 } else if (RemovableByRipOff(current_index) != REMOVABLE) { |
1156 // Make sure we do not try to remove un-removable items like items which | 1196 // Make sure we do not try to remove un-removable items like items which |
1157 // were not pinned or have to be always there. | 1197 // were not pinned or have to be always there. |
1158 cancel = true; | 1198 cancel = true; |
1159 snap_back = true; | 1199 snap_back = true; |
1160 } else { | 1200 } else { |
1161 // Make sure the item stays invisible upon removal. | 1201 // Make sure the item stays invisible upon removal. |
1162 drag_view_->SetVisible(false); | 1202 drag_view_->SetVisible(false); |
1163 std::string app_id = | 1203 std::string app_id = |
1164 model_->GetAppIDForShelfID(model_->items()[current_index].id); | 1204 model_->GetAppIDForShelfID(model_->items()[current_index].id); |
1165 model_->UnpinAppWithID(app_id); | 1205 model_->UnpinAppWithID(app_id); |
1166 } | 1206 } |
1167 } | 1207 } |
1168 if (cancel || snap_back) { | 1208 if (cancel || snap_back) { |
1169 if (dragged_off_from_overflow_to_shelf_) { | 1209 if (dragged_to_another_shelf_) { |
1170 dragged_off_from_overflow_to_shelf_ = false; | 1210 dragged_to_another_shelf_ = false; |
1171 // Main shelf handles revert of dragged item. | 1211 // Other shelf handles revert of dragged item. |
1172 main_shelf_->EndDrag(true); | 1212 EndDragOnOtherShelf(false /* true */); |
1173 drag_view_->layer()->SetOpacity(1.0f); | 1213 drag_view_->layer()->SetOpacity(1.0f); |
1174 } else if (!cancelling_drag_model_changed_) { | 1214 } else if (!cancelling_drag_model_changed_) { |
1175 // Only do something if the change did not come through a model change. | 1215 // Only do something if the change did not come through a model change. |
1176 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); | 1216 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); |
1177 gfx::Point relative_to = GetBoundsInScreen().origin(); | 1217 gfx::Point relative_to = GetBoundsInScreen().origin(); |
1178 gfx::Rect target( | 1218 gfx::Rect target( |
1179 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to), | 1219 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to), |
1180 drag_bounds.size()); | 1220 drag_bounds.size()); |
1181 drag_view_->SetBoundsRect(target); | 1221 drag_view_->SetBoundsRect(target); |
1182 // Hide the status from the active item since we snap it back now. Upon | 1222 // Hide the status from the active item since we snap it back now. Upon |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 if (!is_overflow_mode()) { | 1411 if (!is_overflow_mode()) { |
1372 if (last_hidden_index_ < view_model_->view_size() - 1) | 1412 if (last_hidden_index_ < view_model_->view_size() - 1) |
1373 last_button_index = view_model_->view_size() - 1; | 1413 last_button_index = view_model_->view_size() - 1; |
1374 else if (overflow_button_ && overflow_button_->visible()) | 1414 else if (overflow_button_ && overflow_button_->visible()) |
1375 last_button_index++; | 1415 last_button_index++; |
1376 } | 1416 } |
1377 | 1417 |
1378 // When an item is dragged off from the overflow bubble, it is moved to last | 1418 // When an item is dragged off from the overflow bubble, it is moved to last |
1379 // position and and changed to invisible. Overflow bubble size should be | 1419 // position and and changed to invisible. Overflow bubble size should be |
1380 // shrunk to fit only for visible items. | 1420 // shrunk to fit only for visible items. |
1381 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible | 1421 // If |dragged_to_another_shelf_| is set, there will be no |
1382 // items in the shelf. | 1422 // invisible items in the shelf. |
1383 if (is_overflow_mode() && dragged_off_shelf_ && | 1423 if (is_overflow_mode() && dragged_off_shelf_ && !dragged_to_another_shelf_ && |
1384 !dragged_off_from_overflow_to_shelf_ && | |
1385 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) | 1424 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) |
1386 last_button_index--; | 1425 last_button_index--; |
1387 | 1426 |
1388 const gfx::Rect last_button_bounds = | 1427 const gfx::Rect last_button_bounds = |
1389 last_button_index >= first_visible_index_ | 1428 last_button_index >= first_visible_index_ |
1390 ? view_model_->ideal_bounds(last_button_index) | 1429 ? view_model_->ideal_bounds(last_button_index) |
1391 : gfx::Rect(gfx::Size(kShelfSize, kShelfSize)); | 1430 : gfx::Rect(gfx::Size(kShelfSize, kShelfSize)); |
1392 | 1431 |
1393 if (wm_shelf_->IsHorizontalAlignment()) | 1432 if (wm_shelf_->IsHorizontalAlignment()) |
1394 return gfx::Size(last_button_bounds.right(), kShelfSize); | 1433 return gfx::Size(last_button_bounds.right(), kShelfSize); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 if (pointer == TOUCH && | 1800 if (pointer == TOUCH && |
1762 (base::TimeTicks::Now() - touch_press_time_) < | 1801 (base::TimeTicks::Now() - touch_press_time_) < |
1763 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { | 1802 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { |
1764 return false; | 1803 return false; |
1765 } | 1804 } |
1766 | 1805 |
1767 return true; | 1806 return true; |
1768 } | 1807 } |
1769 | 1808 |
1770 } // namespace ash | 1809 } // namespace ash |
OLD | NEW |