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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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); | |
skuhne
2017/05/03 00:56:18
could you please add here true /* cancel */ ?
sammiequon
2017/05/03 16:19:19
Done.
| |
1084 } else { | |
1085 DCHECK(overflow_bubble_->IsShowing()); | |
1086 overflow_bubble_->shelf_view()->EndDrag(true); | |
skuhne
2017/05/03 00:56:18
same here (and in the other places)
sammiequon
2017/05/03 16:19:19
Done.
| |
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_->IsShowing()); | |
1142 overflow_bubble_->shelf_view()->EndDrag(true); | |
1143 | |
1144 // During dragging, the position of the dragged item is moved to the | |
1145 // back. If the overflow bubble is showing, a copy of the dragged item | |
1146 // will appear at the end of the overflow shelf. Decrement the last | |
1147 // visible index of the overflow shelf to hide this copy. | |
1148 overflow_bubble_->shelf_view()->last_visible_index_--; | |
1149 } | |
1150 | |
1118 bounds_animator_->StopAnimatingView(drag_view_); | 1151 bounds_animator_->StopAnimatingView(drag_view_); |
1119 int drag_view_index = view_model_->GetIndexOfView(drag_view_); | 1152 int drag_view_index = view_model_->GetIndexOfView(drag_view_); |
1120 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); | 1153 drag_view_->SetBoundsRect(view_model_->ideal_bounds(drag_view_index)); |
1121 } | 1154 } |
1122 // Move our proxy view item. | 1155 // Move our proxy view item. |
1123 UpdateDragIconProxy(screen_location); | 1156 UpdateDragIconProxy(screen_location); |
1124 return true; | 1157 return true; |
1125 } | 1158 } |
1126 // Check if we are too far away from the shelf to enter the ripped off state. | 1159 // Check if we are too far away from the shelf to enter the ripped off state. |
1127 // Determine the distance to the shelf. | 1160 // Determine the distance to the shelf. |
1128 int delta = CalculateShelfDistance(screen_location); | 1161 int delta = CalculateShelfDistance(screen_location); |
1129 if (delta > kRipOffDistance) { | 1162 if (delta > kRipOffDistance) { |
1130 // Create a proxy view item which can be moved anywhere. | 1163 // Create a proxy view item which can be moved anywhere. |
1131 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(), | 1164 CreateDragIconProxy(event.root_location(), drag_view_->GetImage(), |
1132 drag_view_, gfx::Vector2d(0, 0), | 1165 drag_view_, gfx::Vector2d(0, 0), |
1133 kDragAndDropProxyScale); | 1166 kDragAndDropProxyScale); |
1134 drag_view_->layer()->SetOpacity(0.0f); | 1167 drag_view_->layer()->SetOpacity(0.0f); |
1135 dragged_off_shelf_ = true; | 1168 dragged_off_shelf_ = true; |
1136 if (RemovableByRipOff(current_index) == REMOVABLE) { | 1169 if (RemovableByRipOff(current_index) == REMOVABLE) { |
1137 // Move the item to the front of the first panel item and hide it. | 1170 // Move the item to the front of the first panel item and hide it. |
1138 // ShelfItemMoved() callback will handle the |view_model_| update and | 1171 // ShelfItemMoved() callback will handle the |view_model_| update and |
1139 // call AnimateToIdealBounds(). | 1172 // call AnimateToIdealBounds(). |
1140 if (current_index != model_->FirstPanelIndex() - 1) { | 1173 if (current_index != model_->FirstPanelIndex() - 1) { |
1141 model_->Move(current_index, model_->FirstPanelIndex() - 1); | 1174 model_->Move(current_index, model_->FirstPanelIndex() - 1); |
1142 StartFadeInLastVisibleItem(); | 1175 StartFadeInLastVisibleItem(); |
1176 | |
1177 // During dragging, the position of the dragged item is moved to the | |
1178 // back. If the overflow bubble is showing, a copy of the dragged item | |
1179 // will appear at the end of the overflow shelf. Decrement the last | |
1180 // visible index of the overflow shelf to hide this copy. | |
1181 if (overflow_bubble_ && overflow_bubble_->IsShowing()) | |
1182 overflow_bubble_->shelf_view()->last_visible_index_--; | |
1143 } else if (is_overflow_mode()) { | 1183 } else if (is_overflow_mode()) { |
1144 // Overflow bubble should be shrunk when an item is ripped off. | 1184 // Overflow bubble should be shrunk when an item is ripped off. |
1145 PreferredSizeChanged(); | 1185 PreferredSizeChanged(); |
1146 } | 1186 } |
1147 // Make the item partially disappear to show that it will get removed if | 1187 // Make the item partially disappear to show that it will get removed if |
1148 // dropped. | 1188 // dropped. |
1149 drag_image_->SetOpacity(kDraggedImageOpacity); | 1189 drag_image_->SetOpacity(kDraggedImageOpacity); |
1150 } | 1190 } |
1151 return true; | 1191 return true; |
1152 } | 1192 } |
(...skipping 14 matching lines...) Expand all Loading... | |
1167 // and only delete the proxy image. | 1207 // and only delete the proxy image. |
1168 if (current_index == -1) { | 1208 if (current_index == -1) { |
1169 DestroyDragIconProxy(); | 1209 DestroyDragIconProxy(); |
1170 return; | 1210 return; |
1171 } | 1211 } |
1172 | 1212 |
1173 // Set to true when the animation should snap back to where it was before. | 1213 // Set to true when the animation should snap back to where it was before. |
1174 bool snap_back = false; | 1214 bool snap_back = false; |
1175 // Items which cannot be dragged off will be handled as a cancel. | 1215 // Items which cannot be dragged off will be handled as a cancel. |
1176 if (!cancel) { | 1216 if (!cancel) { |
1177 if (dragged_off_from_overflow_to_shelf_) { | 1217 if (dragged_to_another_shelf_) { |
1178 dragged_off_from_overflow_to_shelf_ = false; | 1218 dragged_to_another_shelf_ = false; |
1179 main_shelf_->EndDrag(false); | 1219 if (is_overflow_mode()) { |
1220 main_shelf_->EndDrag(false); | |
1221 } else { | |
1222 DCHECK(overflow_bubble_->IsShowing()); | |
1223 overflow_bubble_->shelf_view()->EndDrag(false); | |
1224 } | |
1180 drag_view_->layer()->SetOpacity(1.0f); | 1225 drag_view_->layer()->SetOpacity(1.0f); |
1181 } else if (RemovableByRipOff(current_index) != REMOVABLE) { | 1226 } else if (RemovableByRipOff(current_index) != REMOVABLE) { |
1182 // Make sure we do not try to remove un-removable items like items which | 1227 // Make sure we do not try to remove un-removable items like items which |
1183 // were not pinned or have to be always there. | 1228 // were not pinned or have to be always there. |
1184 cancel = true; | 1229 cancel = true; |
1185 snap_back = true; | 1230 snap_back = true; |
1186 } else { | 1231 } else { |
1187 // Make sure the item stays invisible upon removal. | 1232 // Make sure the item stays invisible upon removal. |
1188 drag_view_->SetVisible(false); | 1233 drag_view_->SetVisible(false); |
1189 std::string app_id = | 1234 std::string app_id = |
1190 delegate_->GetAppIDForShelfID(model_->items()[current_index].id); | 1235 delegate_->GetAppIDForShelfID(model_->items()[current_index].id); |
1191 delegate_->UnpinAppWithID(app_id); | 1236 delegate_->UnpinAppWithID(app_id); |
1192 } | 1237 } |
1193 } | 1238 } |
1194 if (cancel || snap_back) { | 1239 if (cancel || snap_back) { |
1195 if (dragged_off_from_overflow_to_shelf_) { | 1240 if (dragged_to_another_shelf_) { |
1196 dragged_off_from_overflow_to_shelf_ = false; | 1241 dragged_to_another_shelf_ = false; |
1197 // Main shelf handles revert of dragged item. | 1242 // Other shelf handles revert of dragged item. |
1198 main_shelf_->EndDrag(true); | 1243 if (is_overflow_mode()) { |
1244 main_shelf_->EndDrag(true); | |
1245 } else { | |
1246 DCHECK(overflow_bubble_->IsShowing()); | |
1247 overflow_bubble_->shelf_view()->EndDrag(true); | |
1248 } | |
skuhne
2017/05/03 00:56:18
Line 1241 - 1248 appears to be quite repetitive.
(
sammiequon
2017/05/03 16:19:19
I did this but I think its better to keep this as
Mr4D (OOO till 08-26)
2017/05/03 17:30:00
Super. Thanks!
| |
1199 drag_view_->layer()->SetOpacity(1.0f); | 1249 drag_view_->layer()->SetOpacity(1.0f); |
1200 } else if (!cancelling_drag_model_changed_) { | 1250 } else if (!cancelling_drag_model_changed_) { |
1201 // Only do something if the change did not come through a model change. | 1251 // Only do something if the change did not come through a model change. |
1202 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); | 1252 gfx::Rect drag_bounds = drag_image_->GetBoundsInScreen(); |
1203 gfx::Point relative_to = GetBoundsInScreen().origin(); | 1253 gfx::Point relative_to = GetBoundsInScreen().origin(); |
1204 gfx::Rect target( | 1254 gfx::Rect target( |
1205 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to), | 1255 gfx::PointAtOffsetFromOrigin(drag_bounds.origin() - relative_to), |
1206 drag_bounds.size()); | 1256 drag_bounds.size()); |
1207 drag_view_->SetBoundsRect(target); | 1257 drag_view_->SetBoundsRect(target); |
1208 // Hide the status from the active item since we snap it back now. Upon | 1258 // 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 Loading... | |
1402 if (!is_overflow_mode()) { | 1452 if (!is_overflow_mode()) { |
1403 if (last_hidden_index_ < view_model_->view_size() - 1) | 1453 if (last_hidden_index_ < view_model_->view_size() - 1) |
1404 last_button_index = view_model_->view_size() - 1; | 1454 last_button_index = view_model_->view_size() - 1; |
1405 else if (overflow_button_ && overflow_button_->visible()) | 1455 else if (overflow_button_ && overflow_button_->visible()) |
1406 last_button_index++; | 1456 last_button_index++; |
1407 } | 1457 } |
1408 | 1458 |
1409 // When an item is dragged off from the overflow bubble, it is moved to last | 1459 // 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 | 1460 // position and and changed to invisible. Overflow bubble size should be |
1411 // shrunk to fit only for visible items. | 1461 // shrunk to fit only for visible items. |
1412 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible | 1462 // If |dragged_to_another_shelf_| is set, there will be no |
1413 // items in the shelf. | 1463 // invisible items in the shelf. |
1414 if (is_overflow_mode() && dragged_off_shelf_ && | 1464 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) | 1465 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) |
1417 last_button_index--; | 1466 last_button_index--; |
1418 | 1467 |
1419 const gfx::Rect last_button_bounds = | 1468 const gfx::Rect last_button_bounds = |
1420 last_button_index >= first_visible_index_ | 1469 last_button_index >= first_visible_index_ |
1421 ? view_model_->ideal_bounds(last_button_index) | 1470 ? view_model_->ideal_bounds(last_button_index) |
1422 : gfx::Rect(gfx::Size(shelf_size, shelf_size)); | 1471 : gfx::Rect(gfx::Size(shelf_size, shelf_size)); |
1423 | 1472 |
1424 if (wm_shelf_->IsHorizontalAlignment()) | 1473 if (wm_shelf_->IsHorizontalAlignment()) |
1425 return gfx::Size(last_button_bounds.right(), shelf_size); | 1474 return gfx::Size(last_button_bounds.right(), shelf_size); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 | 1811 |
1763 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { | 1812 int ShelfView::CalculateShelfDistance(const gfx::Point& coordinate) const { |
1764 const gfx::Rect bounds = GetBoundsInScreen(); | 1813 const gfx::Rect bounds = GetBoundsInScreen(); |
1765 int distance = wm_shelf_->SelectValueForShelfAlignment( | 1814 int distance = wm_shelf_->SelectValueForShelfAlignment( |
1766 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(), | 1815 bounds.y() - coordinate.y(), coordinate.x() - bounds.right(), |
1767 bounds.x() - coordinate.x()); | 1816 bounds.x() - coordinate.x()); |
1768 return distance > 0 ? distance : 0; | 1817 return distance > 0 ? distance : 0; |
1769 } | 1818 } |
1770 | 1819 |
1771 } // namespace ash | 1820 } // namespace ash |
OLD | NEW |