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 "ui/app_list/views/apps_grid_view.h" | 5 #include "ui/app_list/views/apps_grid_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 const int kTopPadding = 1; | 64 const int kTopPadding = 1; |
65 const int kBottomPadding = 24; | 65 const int kBottomPadding = 24; |
66 | 66 |
67 // Padding space in pixels between pages. | 67 // Padding space in pixels between pages. |
68 const int kPagePadding = 40; | 68 const int kPagePadding = 40; |
69 | 69 |
70 // Preferred tile size when showing in fixed layout. | 70 // Preferred tile size when showing in fixed layout. |
71 const int kPreferredTileWidth = 88; | 71 const int kPreferredTileWidth = 88; |
72 const int kPreferredTileHeight = 98; | 72 const int kPreferredTileHeight = 98; |
73 | 73 |
74 const int kExperimentalTileWidth = 90; | |
Matt Giuca
2014/09/16 07:37:57
Can this be kExperimentalPreferredTileWidth?
calamity
2014/09/17 01:48:49
Done.
| |
75 const int kExperimentalTileHeight = 90; | |
76 | |
77 // Padding on each side of a tile. | |
78 const int kTileLeftRightPadding = 15; | |
Matt Giuca
2014/09/16 07:37:57
kExperimental...
calamity
2014/09/17 01:48:49
Done.
| |
79 const int kTileTopBottomPadding = 11; | |
80 | |
74 // Width in pixels of the area on the sides that triggers a page flip. | 81 // Width in pixels of the area on the sides that triggers a page flip. |
75 const int kPageFlipZoneSize = 40; | 82 const int kPageFlipZoneSize = 40; |
76 | 83 |
77 // Delay in milliseconds to do the page flip. | 84 // Delay in milliseconds to do the page flip. |
78 const int kPageFlipDelayInMs = 1000; | 85 const int kPageFlipDelayInMs = 1000; |
79 | 86 |
80 // How many pages on either side of the selected one we prerender. | 87 // How many pages on either side of the selected one we prerender. |
81 const int kPrerenderPages = 1; | 88 const int kPrerenderPages = 1; |
82 | 89 |
83 // The drag and drop proxy should get scaled by this factor. | 90 // The drag and drop proxy should get scaled by this factor. |
84 const float kDragAndDropProxyScale = 1.5f; | 91 const float kDragAndDropProxyScale = 1.5f; |
85 | 92 |
86 // Delays in milliseconds to show folder dropping preview circle. | 93 // Delays in milliseconds to show folder dropping preview circle. |
87 const int kFolderDroppingDelay = 150; | 94 const int kFolderDroppingDelay = 150; |
88 | 95 |
89 // Delays in milliseconds to show re-order preview. | 96 // Delays in milliseconds to show re-order preview. |
90 const int kReorderDelay = 120; | 97 const int kReorderDelay = 120; |
91 | 98 |
92 // Delays in milliseconds to show folder item reparent UI. | 99 // Delays in milliseconds to show folder item reparent UI. |
93 const int kFolderItemReparentDelay = 50; | 100 const int kFolderItemReparentDelay = 50; |
94 | 101 |
95 // Radius of the circle, in which if entered, show folder dropping preview | 102 // Radius of the circle, in which if entered, show folder dropping preview |
96 // UI. | 103 // UI. |
97 const int kFolderDroppingCircleRadius = 39; | 104 const int kFolderDroppingCircleRadius = 39; |
98 | 105 |
106 gfx::Size GetTileViewSize() { | |
Matt Giuca
2014/09/16 07:37:57
Comments.
calamity
2014/09/17 01:48:49
Done.
| |
107 return switches::IsExperimentalAppListEnabled() | |
108 ? gfx::Size(kExperimentalTileWidth, kExperimentalTileHeight) | |
109 : gfx::Size(kPreferredTileWidth, kPreferredTileHeight); | |
110 } | |
111 | |
112 gfx::Size GetTotalTileSize() { | |
113 gfx::Size size = GetTileViewSize(); | |
114 if (switches::IsExperimentalAppListEnabled()) | |
115 size.Enlarge(2 * kTileLeftRightPadding, 2 * kTileTopBottomPadding); | |
116 return size; | |
117 } | |
118 | |
99 // RowMoveAnimationDelegate is used when moving an item into a different row. | 119 // RowMoveAnimationDelegate is used when moving an item into a different row. |
100 // Before running the animation, the item's layer is re-created and kept in | 120 // Before running the animation, the item's layer is re-created and kept in |
101 // the original position, then the item is moved to just before its target | 121 // the original position, then the item is moved to just before its target |
102 // position and opacity set to 0. When the animation runs, this delegate moves | 122 // position and opacity set to 0. When the animation runs, this delegate moves |
103 // the layer and fades it out while fading in the item at the same time. | 123 // the layer and fades it out while fading in the item at the same time. |
104 class RowMoveAnimationDelegate : public gfx::AnimationDelegate { | 124 class RowMoveAnimationDelegate : public gfx::AnimationDelegate { |
105 public: | 125 public: |
106 RowMoveAnimationDelegate(views::View* view, | 126 RowMoveAnimationDelegate(views::View* view, |
107 ui::Layer* layer, | 127 ui::Layer* layer, |
108 const gfx::Rect& layer_target) | 128 const gfx::Rect& layer_target) |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1033 if (pulsing_blocks_model_.view_size() == desired) | 1053 if (pulsing_blocks_model_.view_size() == desired) |
1034 return; | 1054 return; |
1035 | 1055 |
1036 while (pulsing_blocks_model_.view_size() > desired) { | 1056 while (pulsing_blocks_model_.view_size() > desired) { |
1037 views::View* view = pulsing_blocks_model_.view_at(0); | 1057 views::View* view = pulsing_blocks_model_.view_at(0); |
1038 pulsing_blocks_model_.Remove(0); | 1058 pulsing_blocks_model_.Remove(0); |
1039 delete view; | 1059 delete view; |
1040 } | 1060 } |
1041 | 1061 |
1042 while (pulsing_blocks_model_.view_size() < desired) { | 1062 while (pulsing_blocks_model_.view_size() < desired) { |
1043 views::View* view = new PulsingBlockView( | 1063 views::View* view = new PulsingBlockView(GetTotalTileSize(), true); |
1044 gfx::Size(kPreferredTileWidth, kPreferredTileHeight), true); | |
1045 pulsing_blocks_model_.Add(view, 0); | 1064 pulsing_blocks_model_.Add(view, 0); |
1046 AddChildView(view); | 1065 AddChildView(view); |
1047 } | 1066 } |
1048 } | 1067 } |
1049 | 1068 |
1050 views::View* AppsGridView::CreateViewForItemAtIndex(size_t index) { | 1069 views::View* AppsGridView::CreateViewForItemAtIndex(size_t index) { |
1051 // The drag_view_ might be pending for deletion, therefore view_model_ | 1070 // The drag_view_ might be pending for deletion, therefore view_model_ |
1052 // may have one more item than item_list_. | 1071 // may have one more item than item_list_. |
1053 DCHECK_LE(index, item_list_->item_count()); | 1072 DCHECK_LE(index, item_list_->item_count()); |
1054 AppListItemView* view = new AppListItemView(this, | 1073 AppListItemView* view = new AppListItemView(this, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1246 const gfx::Rect& target = view_model_.ideal_bounds(i); | 1265 const gfx::Rect& target = view_model_.ideal_bounds(i); |
1247 if (bounds_animator_.GetTargetBounds(view) == target) | 1266 if (bounds_animator_.GetTargetBounds(view) == target) |
1248 continue; | 1267 continue; |
1249 | 1268 |
1250 const gfx::Rect& current = view->bounds(); | 1269 const gfx::Rect& current = view->bounds(); |
1251 const bool current_visible = visible_bounds.Intersects(current); | 1270 const bool current_visible = visible_bounds.Intersects(current); |
1252 const bool target_visible = visible_bounds.Intersects(target); | 1271 const bool target_visible = visible_bounds.Intersects(target); |
1253 const bool visible = current_visible || target_visible; | 1272 const bool visible = current_visible || target_visible; |
1254 | 1273 |
1255 const int y_diff = target.y() - current.y(); | 1274 const int y_diff = target.y() - current.y(); |
1256 if (visible && y_diff && y_diff % kPreferredTileHeight == 0) { | 1275 if (visible && y_diff && y_diff % GetTotalTileSize().height() == 0) { |
1257 AnimationBetweenRows(view, | 1276 AnimationBetweenRows(view, |
1258 current_visible, | 1277 current_visible, |
1259 current, | 1278 current, |
1260 target_visible, | 1279 target_visible, |
1261 target); | 1280 target); |
1262 } else if (visible || bounds_animator_.IsAnimating(view)) { | 1281 } else if (visible || bounds_animator_.IsAnimating(view)) { |
1263 bounds_animator_.AnimateViewTo(view, target); | 1282 bounds_animator_.AnimateViewTo(view, target); |
1264 bounds_animator_.SetAnimationDelegate( | 1283 bounds_animator_.SetAnimationDelegate( |
1265 view, | 1284 view, |
1266 scoped_ptr<gfx::AnimationDelegate>( | 1285 scoped_ptr<gfx::AnimationDelegate>( |
(...skipping 21 matching lines...) Expand all Loading... | |
1288 | 1307 |
1289 scoped_ptr<ui::Layer> layer; | 1308 scoped_ptr<ui::Layer> layer; |
1290 if (animate_current) { | 1309 if (animate_current) { |
1291 layer = view->RecreateLayer(); | 1310 layer = view->RecreateLayer(); |
1292 layer->SuppressPaint(); | 1311 layer->SuppressPaint(); |
1293 | 1312 |
1294 view->SetFillsBoundsOpaquely(false); | 1313 view->SetFillsBoundsOpaquely(false); |
1295 view->layer()->SetOpacity(0.f); | 1314 view->layer()->SetOpacity(0.f); |
1296 } | 1315 } |
1297 | 1316 |
1317 gfx::Size total_tile_size = GetTotalTileSize(); | |
1298 gfx::Rect current_out(current); | 1318 gfx::Rect current_out(current); |
1299 current_out.Offset(dir * kPreferredTileWidth, 0); | 1319 current_out.Offset(dir * total_tile_size.width(), 0); |
1300 | 1320 |
1301 gfx::Rect target_in(target); | 1321 gfx::Rect target_in(target); |
1302 if (animate_target) | 1322 if (animate_target) |
1303 target_in.Offset(-dir * kPreferredTileWidth, 0); | 1323 target_in.Offset(-dir * total_tile_size.width(), 0); |
1304 view->SetBoundsRect(target_in); | 1324 view->SetBoundsRect(target_in); |
1305 bounds_animator_.AnimateViewTo(view, target); | 1325 bounds_animator_.AnimateViewTo(view, target); |
1306 | 1326 |
1307 bounds_animator_.SetAnimationDelegate( | 1327 bounds_animator_.SetAnimationDelegate( |
1308 view, | 1328 view, |
1309 scoped_ptr<gfx::AnimationDelegate>( | 1329 scoped_ptr<gfx::AnimationDelegate>( |
1310 new RowMoveAnimationDelegate(view, layer.release(), current_out))); | 1330 new RowMoveAnimationDelegate(view, layer.release(), current_out))); |
1311 } | 1331 } |
1312 | 1332 |
1313 void AppsGridView::ExtractDragLocation(const ui::LocatedEvent& event, | 1333 void AppsGridView::ExtractDragLocation(const ui::LocatedEvent& event, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1388 gfx::Point reorder_placeholder_center = | 1408 gfx::Point reorder_placeholder_center = |
1389 GetExpectedTileBounds(reorder_placeholder_.slot).CenterPoint(); | 1409 GetExpectedTileBounds(reorder_placeholder_.slot).CenterPoint(); |
1390 | 1410 |
1391 int x_offset_direction = 0; | 1411 int x_offset_direction = 0; |
1392 if (grid_index == reorder_placeholder_) { | 1412 if (grid_index == reorder_placeholder_) { |
1393 x_offset_direction = reorder_placeholder_center.x() < point.x() ? -1 : 1; | 1413 x_offset_direction = reorder_placeholder_center.x() < point.x() ? -1 : 1; |
1394 } else { | 1414 } else { |
1395 x_offset_direction = reorder_placeholder_ < grid_index ? -1 : 1; | 1415 x_offset_direction = reorder_placeholder_ < grid_index ? -1 : 1; |
1396 } | 1416 } |
1397 | 1417 |
1418 gfx::Size total_tile_size = GetTotalTileSize(); | |
1398 int row = grid_index.slot / cols_; | 1419 int row = grid_index.slot / cols_; |
1399 | 1420 |
1400 // Offset the target column based on the direction of the target. This will | 1421 // Offset the target column based on the direction of the target. This will |
1401 // result in earlier targets getting their reorder zone shifted backwards | 1422 // result in earlier targets getting their reorder zone shifted backwards |
1402 // and later targets getting their reorder zones shifted forwards. | 1423 // and later targets getting their reorder zones shifted forwards. |
1403 // | 1424 // |
1404 // This makes eordering feel like the user is slotting items into the spaces | 1425 // This makes eordering feel like the user is slotting items into the spaces |
1405 // between apps. | 1426 // between apps. |
1406 int x_offset = x_offset_direction * | 1427 int x_offset = x_offset_direction * |
1407 (kPreferredTileWidth - kFolderDroppingCircleRadius) / 2; | 1428 (total_tile_size.width() - kFolderDroppingCircleRadius) / 2; |
1408 int col = (point.x() - bounds.x() + x_offset) / kPreferredTileWidth; | 1429 int col = (point.x() - bounds.x() + x_offset) / total_tile_size.width(); |
1409 col = ClampToRange(col, 0, cols_ - 1); | 1430 col = ClampToRange(col, 0, cols_ - 1); |
1410 *drop_target = | 1431 *drop_target = |
1411 std::min(Index(pagination_model_.selected_page(), row * cols_ + col), | 1432 std::min(Index(pagination_model_.selected_page(), row * cols_ + col), |
1412 GetLastViewIndex()); | 1433 GetLastViewIndex()); |
1413 } | 1434 } |
1414 | 1435 |
1415 void AppsGridView::OnReorderTimer() { | 1436 void AppsGridView::OnReorderTimer() { |
1416 if (drop_attempt_ == DROP_FOR_REORDER) { | 1437 if (drop_attempt_ == DROP_FOR_REORDER) { |
1417 reorder_placeholder_ = reorder_drop_target_; | 1438 reorder_placeholder_ = reorder_drop_target_; |
1418 AnimateToIdealBounds(); | 1439 AnimateToIdealBounds(); |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2060 // Items can be dropped into non-folders (which have no children) or folders | 2081 // Items can be dropped into non-folders (which have no children) or folders |
2061 // that have fewer than the max allowed items. | 2082 // that have fewer than the max allowed items. |
2062 // OEM folder does not allow to drag/drop other items in it. | 2083 // OEM folder does not allow to drag/drop other items in it. |
2063 return target_item->ChildItemCount() < kMaxFolderItems && | 2084 return target_item->ChildItemCount() < kMaxFolderItems && |
2064 !IsOEMFolderItem(target_item); | 2085 !IsOEMFolderItem(target_item); |
2065 } | 2086 } |
2066 | 2087 |
2067 AppsGridView::Index AppsGridView::GetNearestTileIndexForPoint( | 2088 AppsGridView::Index AppsGridView::GetNearestTileIndexForPoint( |
2068 const gfx::Point& point) const { | 2089 const gfx::Point& point) const { |
2069 gfx::Rect bounds = GetContentsBounds(); | 2090 gfx::Rect bounds = GetContentsBounds(); |
2070 int col = | 2091 gfx::Size total_tile_size = GetTotalTileSize(); |
2071 ClampToRange((point.x() - bounds.x()) / kPreferredTileWidth, 0, cols_); | 2092 int col = ClampToRange( |
2093 (point.x() - bounds.x()) / total_tile_size.width(), 0, cols_); | |
2072 int row = ClampToRange( | 2094 int row = ClampToRange( |
2073 (point.y() - bounds.y()) / kPreferredTileHeight, 0, rows_per_page_); | 2095 (point.y() - bounds.y()) / total_tile_size.height(), 0, rows_per_page_); |
2074 return Index(pagination_model_.selected_page(), row * cols_ + col); | 2096 return Index(pagination_model_.selected_page(), row * cols_ + col); |
2075 } | 2097 } |
2076 | 2098 |
2077 gfx::Size AppsGridView::GetTileGridSize() const { | 2099 gfx::Size AppsGridView::GetTileGridSize() const { |
2078 gfx::Rect bounds = GetExpectedTileBounds(0, 0); | 2100 gfx::Rect bounds = GetExpectedTileBounds(0, 0); |
2079 bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1)); | 2101 bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1)); |
2102 if (switches::IsExperimentalAppListEnabled()) | |
2103 bounds.Inset(-kTileLeftRightPadding, -kTileTopBottomPadding); | |
2080 return bounds.size(); | 2104 return bounds.size(); |
2081 } | 2105 } |
2082 | 2106 |
2083 gfx::Rect AppsGridView::GetExpectedTileBounds(int slot) const { | 2107 gfx::Rect AppsGridView::GetExpectedTileBounds(int slot) const { |
2084 return GetExpectedTileBounds(slot / cols_, slot % cols_); | 2108 return GetExpectedTileBounds(slot / cols_, slot % cols_); |
2085 } | 2109 } |
2086 | 2110 |
2087 gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const { | 2111 gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const { |
2088 gfx::Rect bounds(GetContentsBounds()); | 2112 gfx::Rect bounds(GetContentsBounds()); |
2089 gfx::Size tile_size(kPreferredTileWidth, kPreferredTileHeight); | 2113 gfx::Size total_tile_size = GetTotalTileSize(); |
2090 return gfx::Rect(gfx::Point(bounds.x() + col * tile_size.width(), | 2114 gfx::Rect tile_bounds(gfx::Point(bounds.x() + col * total_tile_size.width(), |
2091 bounds.y() + row * tile_size.height()), | 2115 bounds.y() + row * total_tile_size.height()), |
2092 tile_size); | 2116 total_tile_size); |
2117 tile_bounds.ClampToCenteredSize(GetTileViewSize()); | |
2118 return tile_bounds; | |
2093 } | 2119 } |
2094 | 2120 |
2095 views::View* AppsGridView::GetViewAtSlotOnCurrentPage(int slot) { | 2121 views::View* AppsGridView::GetViewAtSlotOnCurrentPage(int slot) { |
2096 if (slot < 0) | 2122 if (slot < 0) |
2097 return NULL; | 2123 return NULL; |
2098 | 2124 |
2099 // Calculate the original bound of the tile at |index|. | 2125 // Calculate the original bound of the tile at |index|. |
2100 int row = slot / cols_; | 2126 int row = slot / cols_; |
2101 int col = slot % cols_; | 2127 int col = slot % cols_; |
2102 gfx::Rect tile_rect = GetExpectedTileBounds(row, col); | 2128 gfx::Rect tile_rect = GetExpectedTileBounds(row, col); |
2103 | 2129 |
2104 for (int i = 0; i < view_model_.view_size(); ++i) { | 2130 for (int i = 0; i < view_model_.view_size(); ++i) { |
2105 views::View* view = view_model_.view_at(i); | 2131 views::View* view = view_model_.view_at(i); |
2106 if (view->bounds() == tile_rect && view != drag_view_) | 2132 if (view->bounds() == tile_rect && view != drag_view_) |
2107 return view; | 2133 return view; |
2108 } | 2134 } |
2109 return NULL; | 2135 return NULL; |
2110 } | 2136 } |
2111 | 2137 |
2112 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, | 2138 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, |
2113 bool is_target_folder) { | 2139 bool is_target_folder) { |
2114 AppListItemView* target_view = | 2140 AppListItemView* target_view = |
2115 static_cast<AppListItemView*>( | 2141 static_cast<AppListItemView*>( |
2116 GetViewAtSlotOnCurrentPage(target_index.slot)); | 2142 GetViewAtSlotOnCurrentPage(target_index.slot)); |
2117 if (target_view) | 2143 if (target_view) |
2118 target_view->SetAsAttemptedFolderTarget(is_target_folder); | 2144 target_view->SetAsAttemptedFolderTarget(is_target_folder); |
2119 } | 2145 } |
2120 | 2146 |
2121 } // namespace app_list | 2147 } // namespace app_list |
OLD | NEW |