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

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

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

Powered by Google App Engine
This is Rietveld 408576698