Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(538)

Side by Side Diff: ash/shelf/shelf_view.cc

Issue 2820693004: shelf: Allow dragging items from main shelf to overflow shelf. (Closed)
Patch Set: Rebased. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/shelf/shelf_view.h ('k') | ash/shelf/shelf_view_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ash/shelf/shelf_view.h ('k') | ash/shelf/shelf_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698