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

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

Issue 2820693004: shelf: Allow dragging items from main shelf to overflow shelf. (Closed)
Patch Set: Fixed patch set 1 errors. Created 3 years, 8 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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 drag_view_(nullptr), 256 drag_view_(nullptr),
257 start_drag_index_(-1), 257 start_drag_index_(-1),
258 context_menu_id_(0), 258 context_menu_id_(0),
259 cancelling_drag_model_changed_(false), 259 cancelling_drag_model_changed_(false),
260 last_hidden_index_(0), 260 last_hidden_index_(0),
261 closing_event_time_(base::TimeTicks()), 261 closing_event_time_(base::TimeTicks()),
262 drag_and_drop_item_pinned_(false), 262 drag_and_drop_item_pinned_(false),
263 drag_and_drop_shelf_id_(0), 263 drag_and_drop_shelf_id_(0),
264 drag_replaced_view_(nullptr), 264 drag_replaced_view_(nullptr),
265 dragged_off_shelf_(false), 265 dragged_off_shelf_(false),
266 dragged_to_another_shelf_(false),
266 snap_back_from_rip_off_view_(nullptr), 267 snap_back_from_rip_off_view_(nullptr),
267 overflow_mode_(false), 268 overflow_mode_(false),
268 main_shelf_(nullptr), 269 main_shelf_(nullptr),
269 dragged_off_from_overflow_to_shelf_(false),
270 is_repost_event_on_same_item_(false), 270 is_repost_event_on_same_item_(false),
271 last_pressed_index_(-1), 271 last_pressed_index_(-1),
272 weak_factory_(this) { 272 weak_factory_(this) {
273 DCHECK(model_); 273 DCHECK(model_);
274 DCHECK(delegate_); 274 DCHECK(delegate_);
275 DCHECK(wm_shelf_); 275 DCHECK(wm_shelf_);
276 DCHECK(shelf_widget_); 276 DCHECK(shelf_widget_);
277 bounds_animator_.reset(new views::BoundsAnimator(this)); 277 bounds_animator_.reset(new views::BoundsAnimator(this));
278 bounds_animator_->AddObserver(this); 278 bounds_animator_->AddObserver(this);
279 set_context_menu_controller(this); 279 set_context_menu_controller(this);
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 } 747 }
748 748
749 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { 749 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() {
750 // The overflow button is not shown in overflow mode. 750 // The overflow button is not shown in overflow mode.
751 overflow_button_->SetVisible(false); 751 overflow_button_->SetVisible(false);
752 DCHECK_LT(last_visible_index_, view_model_->view_size()); 752 DCHECK_LT(last_visible_index_, view_model_->view_size());
753 for (int i = 0; i < view_model_->view_size(); ++i) { 753 for (int i = 0; i < view_model_->view_size(); ++i) {
754 bool visible = i >= first_visible_index_ && i <= last_visible_index_; 754 bool visible = i >= first_visible_index_ && i <= last_visible_index_;
755 // To track the dragging of |drag_view_| continuously, its visibility 755 // To track the dragging of |drag_view_| continuously, its visibility
756 // should be always true regardless of its position. 756 // should be always true regardless of its position.
757 if (dragged_off_from_overflow_to_shelf_ && 757 if (dragged_to_another_shelf_ && view_model_->view_at(i) == drag_view_)
758 view_model_->view_at(i) == drag_view_)
759 view_model_->view_at(i)->SetVisible(true); 758 view_model_->view_at(i)->SetVisible(true);
760 else 759 else
761 view_model_->view_at(i)->SetVisible(visible); 760 view_model_->view_at(i)->SetVisible(visible);
762 } 761 }
763 } 762 }
764 763
765 void ShelfView::CalculateIdealBounds(gfx::Rect* overflow_bounds) const { 764 void ShelfView::CalculateIdealBounds(gfx::Rect* overflow_bounds) const {
766 DCHECK(model_->item_count() == view_model_->view_size()); 765 DCHECK(model_->item_count() == view_model_->view_size());
767 766
768 int available_size = wm_shelf_->PrimaryAxisValue(width(), height()); 767 int available_size = wm_shelf_->PrimaryAxisValue(width(), height());
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 WmWindow::Get(GetWidget()->GetNativeWindow()) 1069 WmWindow::Get(GetWidget()->GetNativeWindow())
1071 ->GetRootWindow() 1070 ->GetRootWindow()
1072 ->ConvertPointToScreen(event.root_location()); 1071 ->ConvertPointToScreen(event.root_location());
1073 1072
1074 // To avoid ugly forwards and backwards flipping we use different constants 1073 // To avoid ugly forwards and backwards flipping we use different constants
1075 // for ripping off / re-inserting the items. 1074 // for ripping off / re-inserting the items.
1076 if (dragged_off_shelf_) { 1075 if (dragged_off_shelf_) {
1077 // If the shelf/overflow bubble bounds contains |screen_location| we insert 1076 // If the shelf/overflow bubble bounds contains |screen_location| we insert
1078 // the item back into the shelf. 1077 // the item back into the shelf.
1079 if (GetBoundsForDragInsertInScreen().Contains(screen_location)) { 1078 if (GetBoundsForDragInsertInScreen().Contains(screen_location)) {
1080 if (dragged_off_from_overflow_to_shelf_) { 1079 if (dragged_to_another_shelf_) {
1081 // During the dragging an item from Shelf to Overflow, it can enter here 1080 // During the dragging an item from Shelf to Overflow, it can enter here
1082 // directly because both are located very closly. 1081 // directly because both are located very closely.
1083 main_shelf_->EndDrag(true); 1082 if (is_overflow_mode()) {
1083 main_shelf_->EndDrag(true);
1084 } else {
1085 DCHECK(overflow_bubble_ && overflow_bubble_->IsShowing());
msw 2017/04/18 00:11:04 nit: just DCHECK(overflow_bubble_->IsShowing()); t
sammiequon 2017/04/18 18:57:45 Done.
1086 overflow_bubble_->shelf_view()->EndDrag(true);
1087 }
1088
1084 // Stops the animation of |drag_view_| and sets its bounds explicitly 1089 // Stops the animation of |drag_view_| and sets its bounds explicitly
1085 // becase ContinueDrag() stops its animation. Without this, unexpected 1090 // because ContinueDrag() stops its animation. Without this, unexpected
1086 // bounds will be set. 1091 // bounds will be set.
1087 bounds_animator_->StopAnimatingView(drag_view_); 1092 bounds_animator_->StopAnimatingView(drag_view_);
1088 int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1093 int drag_view_index = view_model_->GetIndexOfView(drag_view_);
1089 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1094 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index));
1090 dragged_off_from_overflow_to_shelf_ = false; 1095 dragged_to_another_shelf_ = false;
1091 } 1096 }
1092 // Destroy our proxy view item. 1097 // Destroy our proxy view item.
1093 DestroyDragIconProxy(); 1098 DestroyDragIconProxy();
1094 // Re-insert the item and return simply false since the caller will handle 1099 // Re-insert the item and return simply false since the caller will handle
1095 // the move as in any normal case. 1100 // the move as in any normal case.
1096 dragged_off_shelf_ = false; 1101 dragged_off_shelf_ = false;
1097 drag_view_->layer()->SetOpacity(1.0f); 1102 drag_view_->layer()->SetOpacity(1.0f);
1098 // The size of Overflow bubble should be updated immediately when an item 1103 // The size of Overflow bubble should be updated immediately when an item
1099 // is re-inserted. 1104 // is re-inserted.
1100 if (is_overflow_mode()) 1105 if (is_overflow_mode())
1101 PreferredSizeChanged(); 1106 PreferredSizeChanged();
1102 return false; 1107 return false;
1103 } else if (is_overflow_mode() && 1108 } else if (is_overflow_mode() &&
1104 main_shelf_->GetBoundsForDragInsertInScreen().Contains( 1109 main_shelf_->GetBoundsForDragInsertInScreen().Contains(
1105 screen_location)) { 1110 screen_location)) {
1106 if (!dragged_off_from_overflow_to_shelf_) { 1111 // The item was dragged from the overflow shelf to the main shelf.
1107 dragged_off_from_overflow_to_shelf_ = true; 1112 if (!dragged_to_another_shelf_) {
1113 dragged_to_another_shelf_ = true;
1108 drag_image_->SetOpacity(1.0f); 1114 drag_image_->SetOpacity(1.0f);
1109 main_shelf_->StartDrag(dragged_app_id, screen_location); 1115 main_shelf_->StartDrag(dragged_app_id, screen_location);
1110 } else { 1116 } else {
1111 main_shelf_->Drag(screen_location); 1117 main_shelf_->Drag(screen_location);
1112 } 1118 }
1113 } else if (dragged_off_from_overflow_to_shelf_) { 1119 } else if (!is_overflow_mode() && overflow_bubble_ &&
1120 overflow_bubble_->IsShowing() &&
1121 overflow_bubble_->shelf_view()
1122 ->GetBoundsForDragInsertInScreen()
1123 .Contains(screen_location)) {
1124 // The item was dragged from the main shelf to the overflow shelf.
1125 if (!dragged_to_another_shelf_) {
1126 dragged_to_another_shelf_ = true;
1127 drag_image_->SetOpacity(1.0f);
1128 overflow_bubble_->shelf_view()->StartDrag(dragged_app_id,
1129 screen_location);
1130 } else {
1131 overflow_bubble_->shelf_view()->Drag(screen_location);
1132 }
1133 } else if (dragged_to_another_shelf_) {
1114 // Makes the |drag_image_| partially disappear again. 1134 // Makes the |drag_image_| partially disappear again.
1115 dragged_off_from_overflow_to_shelf_ = false; 1135 dragged_to_another_shelf_ = false;
1116 drag_image_->SetOpacity(kDraggedImageOpacity); 1136 drag_image_->SetOpacity(kDraggedImageOpacity);
1117 main_shelf_->EndDrag(true); 1137
1138 if (is_overflow_mode()) {
1139 main_shelf_->EndDrag(true);
1140 } else {
1141 DCHECK(overflow_bubble_ && overflow_bubble_->IsShowing());
1142 overflow_bubble_->shelf_view()->EndDrag(true);
1143 // After entering the overflow shelf the last item becomes visible
1144 // again. Hide the last item when we exit the overflow shelf, otherwise
1145 // a copy of the item we are dragging will appear on the overflow shelf.
1146 overflow_bubble_->shelf_view()->last_visible_index_--;
1147 }
1148
1118 bounds_animator_->StopAnimatingView(drag_view_); 1149 bounds_animator_->StopAnimatingView(drag_view_);
1119 int drag_view_index = view_model_->GetIndexOfView(drag_view_); 1150 int drag_view_index = view_model_->GetIndexOfView(drag_view_);
1120 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); 1151 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index));
1121 } 1152 }
1122 // Move our proxy view item. 1153 // Move our proxy view item.
1123 UpdateDragIconProxy(screen_location); 1154 UpdateDragIconProxy(screen_location);
1124 return true; 1155 return true;
1125 } 1156 }
1126 // Check if we are too far away from the shelf to enter the ripped off state. 1157 // Check if we are too far away from the shelf to enter the ripped off state.
1127 // Determine the distance to the shelf. 1158 // Determine the distance to the shelf.
1128 int delta = CalculateShelfDistance(screen_location); 1159 int delta = CalculateShelfDistance(screen_location);
1129 if (delta > kRipOffDistance) { 1160 if (delta > kRipOffDistance) {
1130 // Create a proxy view item which can be moved anywhere. 1161 // Create a proxy view item which can be moved anywhere.
1131 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(), 1162 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(),
1132 drag_view_, gfx::Vector2d(0, 0), 1163 drag_view_, gfx::Vector2d(0, 0),
1133 kDragAndDropProxyScale); 1164 kDragAndDropProxyScale);
1134 drag_view_->layer()->SetOpacity(0.0f); 1165 drag_view_->layer()->SetOpacity(0.0f);
1135 dragged_off_shelf_ = true; 1166 dragged_off_shelf_ = true;
1136 if (RemovableByRipOff(current_index) == REMOVABLE) { 1167 if (RemovableByRipOff(current_index) == REMOVABLE) {
1137 // Move the item to the front of the first panel item and hide it. 1168 // Move the item to the front of the first panel item and hide it.
1138 // ShelfItemMoved() callback will handle the |view_model_| update and 1169 // ShelfItemMoved() callback will handle the |view_model_| update and
1139 // call AnimateToIdealBounds(). 1170 // call AnimateToIdealBounds().
1140 if (current_index != model_->FirstPanelIndex() - 1) { 1171 if (current_index != model_->FirstPanelIndex() - 1) {
1141 model_->Move(current_index, model_->FirstPanelIndex() - 1); 1172 model_->Move(current_index, model_->FirstPanelIndex() - 1);
1142 StartFadeInLastVisibleItem(); 1173 StartFadeInLastVisibleItem();
1174
1175 // If the overflow bubble is showing, the current item will swap to the
1176 // back of the overflow shelf as well, so we tell the overflow shelf to
1177 // not show their last item, which would be the current item.
1178 if (overflow_bubble_ && overflow_bubble_->IsShowing())
1179 overflow_bubble_->shelf_view()->last_visible_index_--;
1143 } else if (is_overflow_mode()) { 1180 } else if (is_overflow_mode()) {
1144 // Overflow bubble should be shrunk when an item is ripped off. 1181 // Overflow bubble should be shrunk when an item is ripped off.
1145 PreferredSizeChanged(); 1182 PreferredSizeChanged();
1146 } 1183 }
1147 // Make the item partially disappear to show that it will get removed if 1184 // Make the item partially disappear to show that it will get removed if
1148 // dropped. 1185 // dropped.
1149 drag_image_->SetOpacity(kDraggedImageOpacity); 1186 drag_image_->SetOpacity(kDraggedImageOpacity);
1150 } 1187 }
1151 return true; 1188 return true;
1152 } 1189 }
(...skipping 14 matching lines...) Expand all
1167 // and only delete the proxy image. 1204 // and only delete the proxy image.
1168 if (current_index == -1) { 1205 if (current_index == -1) {
1169 DestroyDragIconProxy(); 1206 DestroyDragIconProxy();
1170 return; 1207 return;
1171 } 1208 }
1172 1209
1173 // Set to true when the animation should snap back to where it was before. 1210 // Set to true when the animation should snap back to where it was before.
1174 bool snap_back = false; 1211 bool snap_back = false;
1175 // Items which cannot be dragged off will be handled as a cancel. 1212 // Items which cannot be dragged off will be handled as a cancel.
1176 if (!cancel) { 1213 if (!cancel) {
1177 if (dragged_off_from_overflow_to_shelf_) { 1214 if (dragged_to_another_shelf_) {
1178 dragged_off_from_overflow_to_shelf_ = false; 1215 dragged_to_another_shelf_ = false;
1179 main_shelf_->EndDrag(false); 1216 if (is_overflow_mode()) {
1217 main_shelf_->EndDrag(false);
1218 } else {
1219 DCHECK(overflow_bubble_ && overflow_bubble_->IsShowing());
1220 overflow_bubble_->shelf_view()->EndDrag(false);
1221 }
1180 drag_view_->layer()->SetOpacity(1.0f); 1222 drag_view_->layer()->SetOpacity(1.0f);
1181 } else if (RemovableByRipOff(current_index) != REMOVABLE) { 1223 } else if (RemovableByRipOff(current_index) != REMOVABLE) {
1182 // Make sure we do not try to remove un-removable items like items which 1224 // Make sure we do not try to remove un-removable items like items which
1183 // were not pinned or have to be always there. 1225 // were not pinned or have to be always there.
1184 cancel = true; 1226 cancel = true;
1185 snap_back = true; 1227 snap_back = true;
1186 } else { 1228 } else {
1187 // Make sure the item stays invisible upon removal. 1229 // Make sure the item stays invisible upon removal.
1188 drag_view_->SetVisible(false); 1230 drag_view_->SetVisible(false);
1189 std::string app_id = 1231 std::string app_id =
1190 delegate_->GetAppIDForShelfID(model_->items()[current_index].id); 1232 delegate_->GetAppIDForShelfID(model_->items()[current_index].id);
1191 delegate_->UnpinAppWithID(app_id); 1233 delegate_->UnpinAppWithID(app_id);
1192 } 1234 }
1193 } 1235 }
1194 if (cancel || snap_back) { 1236 if (cancel || snap_back) {
1195 if (dragged_off_from_overflow_to_shelf_) { 1237 if (dragged_to_another_shelf_) {
1196 dragged_off_from_overflow_to_shelf_ = false; 1238 dragged_to_another_shelf_ = false;
1197 // Main shelf handles revert of dragged item. 1239 // Other shelf handles revert of dragged item.
1198 main_shelf_->EndDrag(true); 1240 if (is_overflow_mode()) {
1241 main_shelf_->EndDrag(true);
1242 } else {
1243 DCHECK(overflow_bubble_ && overflow_bubble_->IsShowing());
1244 overflow_bubble_->shelf_view()->EndDrag(true);
1245 }
1199 drag_view_->layer()->SetOpacity(1.0f); 1246 drag_view_->layer()->SetOpacity(1.0f);
1200 } else if (!cancelling_drag_model_changed_) { 1247 } else if (!cancelling_drag_model_changed_) {
1201 // Only do something if the change did not come through a model change. 1248 // Only do something if the change did not come through a model change.
1202 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); 1249 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen();
1203 gfx::Point relative_to = GetBoundsInScreen().origin(); 1250 gfx::Point relative_to = GetBoundsInScreen().origin();
1204 gfx::Rect target( 1251 gfx::Rect target(
1205 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to), 1252 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to),
1206 drag_bounds.size()); 1253 drag_bounds.size());
1207 drag_view_->SetBoundsRect(target); 1254 drag_view_->SetBoundsRect(target);
1208 // Hide the status from the active item since we snap it back now. Upon 1255 // Hide the status from the active item since we snap it back now. Upon
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 if (!is_overflow_mode()) { 1449 if (!is_overflow_mode()) {
1403 if (last_hidden_index_ < view_model_->view_size() - 1) 1450 if (last_hidden_index_ < view_model_->view_size() - 1)
1404 last_button_index = view_model_->view_size() - 1; 1451 last_button_index = view_model_->view_size() - 1;
1405 else if (overflow_button_ && overflow_button_->visible()) 1452 else if (overflow_button_ && overflow_button_->visible())
1406 last_button_index++; 1453 last_button_index++;
1407 } 1454 }
1408 1455
1409 // When an item is dragged off from the overflow bubble, it is moved to last 1456 // When an item is dragged off from the overflow bubble, it is moved to last
1410 // position and and changed to invisible. Overflow bubble size should be 1457 // position and and changed to invisible. Overflow bubble size should be
1411 // shrunk to fit only for visible items. 1458 // shrunk to fit only for visible items.
1412 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible 1459 // If |dragged_to_another_shelf_| is set, there will be no
1413 // items in the shelf. 1460 // invisible items in the shelf.
1414 if (is_overflow_mode() && dragged_off_shelf_ && 1461 if (is_overflow_mode() && dragged_off_shelf_ && !dragged_to_another_shelf_ &&
1415 !dragged_off_from_overflow_to_shelf_ &&
1416 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) 1462 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE)
1417 last_button_index--; 1463 last_button_index--;
1418 1464
1419 const gfx::Rect last_button_bounds = 1465 const gfx::Rect last_button_bounds =
1420 last_button_index >= first_visible_index_ 1466 last_button_index >= first_visible_index_
1421 ? view_model_->ideal_bounds(last_button_index) 1467 ? view_model_->ideal_bounds(last_button_index)
1422 : gfx::Rect(gfx::Size(shelf_size, shelf_size)); 1468 : gfx::Rect(gfx::Size(shelf_size, shelf_size));
1423 1469
1424 if (wm_shelf_->IsHorizontalAlignment()) 1470 if (wm_shelf_->IsHorizontalAlignment())
1425 return gfx::Size(last_button_bounds.right(), shelf_size); 1471 return gfx::Size(last_button_bounds.right(), shelf_size);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 1808
1763 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { 1809 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const {
1764 const gfx::Rect bounds = GetBoundsInScreen(); 1810 const gfx::Rect bounds = GetBoundsInScreen();
1765 int distance = wm_shelf_->SelectValueForShelfAlignment( 1811 int distance = wm_shelf_->SelectValueForShelfAlignment(
1766 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(), 1812 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(),
1767 bounds.x() - coordinate.x()); 1813 bounds.x() - coordinate.x());
1768 return distance > 0 ? distance : 0; 1814 return distance > 0 ? distance : 0;
1769 } 1815 }
1770 1816
1771 } // namespace ash 1817 } // 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