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

Side by Side Diff: ui/app_list/views/app_list_folder_view.cc

Issue 136303008: Implement ui for re-parenting an item from an app list folder to another position or folder in the … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments. Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « ui/app_list/views/app_list_folder_view.h ('k') | ui/app_list/views/app_list_item_view.h » ('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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/app_list_folder_view.h" 5 #include "ui/app_list/views/app_list_folder_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ui/app_list/app_list_constants.h" 9 #include "ui/app_list/app_list_constants.h"
10 #include "ui/app_list/app_list_folder_item.h" 10 #include "ui/app_list/app_list_folder_item.h"
11 #include "ui/app_list/app_list_model.h" 11 #include "ui/app_list/app_list_model.h"
12 #include "ui/app_list/pagination_model.h" 12 #include "ui/app_list/pagination_model.h"
13 #include "ui/app_list/views/app_list_item_view.h" 13 #include "ui/app_list/views/app_list_item_view.h"
14 #include "ui/app_list/views/app_list_main_view.h" 14 #include "ui/app_list/views/app_list_main_view.h"
15 #include "ui/app_list/views/apps_container_view.h" 15 #include "ui/app_list/views/apps_container_view.h"
16 #include "ui/app_list/views/apps_grid_view.h" 16 #include "ui/app_list/views/apps_grid_view.h"
17 #include "ui/app_list/views/contents_view.h" 17 #include "ui/app_list/views/contents_view.h"
18 #include "ui/app_list/views/folder_background_view.h"
18 #include "ui/app_list/views/folder_header_view.h" 19 #include "ui/app_list/views/folder_header_view.h"
19 #include "ui/compositor/scoped_layer_animation_settings.h" 20 #include "ui/compositor/scoped_layer_animation_settings.h"
20 #include "ui/events/event.h" 21 #include "ui/events/event.h"
22 #include "ui/gfx/rect_conversions.h"
21 #include "ui/views/view_model.h" 23 #include "ui/views/view_model.h"
22 #include "ui/views/view_model_utils.h" 24 #include "ui/views/view_model_utils.h"
23 25
24 namespace app_list { 26 namespace app_list {
25 27
26 namespace { 28 namespace {
27 29
28 // Indexes of interesting views in ViewModel of AppListFolderView. 30 // Indexes of interesting views in ViewModel of AppListFolderView.
29 const int kIndexFolderHeader = 0; 31 const int kIndexFolderHeader = 0;
30 const int kIndexChildItems = 1; 32 const int kIndexChildItems = 1;
31 33
34 // Threshold for the distance from the center of the item to the circle of the
35 // folder container ink bubble, beyond which, the item is considered dragged
36 // out of the folder boundary.
37 const int kOutOfFolderContainerBubbleDelta = 30;
38
32 } // namespace 39 } // namespace
33 40
34 AppListFolderView::AppListFolderView(AppsContainerView* container_view, 41 AppListFolderView::AppListFolderView(AppsContainerView* container_view,
35 AppListModel* model, 42 AppListModel* model,
36 AppListMainView* app_list_main_view, 43 AppListMainView* app_list_main_view,
37 content::WebContents* start_page_contents) 44 content::WebContents* start_page_contents)
38 : container_view_(container_view), 45 : container_view_(container_view),
39 folder_header_view_(new FolderHeaderView(this)), 46 folder_header_view_(new FolderHeaderView(this)),
40 view_model_(new views::ViewModel), 47 view_model_(new views::ViewModel),
41 model_(model), 48 model_(model),
42 folder_item_(NULL), 49 folder_item_(NULL),
43 pagination_model_(new PaginationModel) { 50 pagination_model_(new PaginationModel),
51 hide_for_reparent_(false) {
44 AddChildView(folder_header_view_); 52 AddChildView(folder_header_view_);
45 view_model_->Add(folder_header_view_, kIndexFolderHeader); 53 view_model_->Add(folder_header_view_, kIndexFolderHeader);
46 54
47 items_grid_view_ = new AppsGridView( 55 items_grid_view_ = new AppsGridView(
48 app_list_main_view, pagination_model_.get(), NULL); 56 app_list_main_view, pagination_model_.get(), NULL);
49 items_grid_view_->set_is_root_level(false); 57 items_grid_view_->set_is_root_level(false);
50 items_grid_view_->SetLayout(kPreferredIconDimension, 58 items_grid_view_->SetLayout(kPreferredIconDimension,
51 kPreferredCols, 59 kPreferredCols,
52 kPreferredRows); 60 kPreferredRows);
53 items_grid_view_->SetModel(model); 61 items_grid_view_->SetModel(model);
(...skipping 13 matching lines...) Expand all
67 // Make sure |items_grid_view_| is deleted before |pagination_model_|. 75 // Make sure |items_grid_view_| is deleted before |pagination_model_|.
68 RemoveAllChildViews(true); 76 RemoveAllChildViews(true);
69 } 77 }
70 78
71 void AppListFolderView::SetAppListFolderItem(AppListFolderItem* folder) { 79 void AppListFolderView::SetAppListFolderItem(AppListFolderItem* folder) {
72 folder_item_ = folder; 80 folder_item_ = folder;
73 items_grid_view_->SetItemList(folder_item_->item_list()); 81 items_grid_view_->SetItemList(folder_item_->item_list());
74 folder_header_view_->SetFolderItem(folder_item_); 82 folder_header_view_->SetFolderItem(folder_item_);
75 } 83 }
76 84
77 void AppListFolderView::ScheduleShowHideAnimation(bool show) { 85 void AppListFolderView::ScheduleShowHideAnimation(bool show,
86 bool hide_for_reparent) {
87 hide_for_reparent_ = hide_for_reparent;
88
78 // Stop any previous animation. 89 // Stop any previous animation.
79 layer()->GetAnimator()->StopAnimating(); 90 layer()->GetAnimator()->StopAnimating();
80 91
81 // Hide the top items temporarily if showing the view for opening the folder. 92 // Hide the top items temporarily if showing the view for opening the folder.
82 if (show) 93 if (show)
83 items_grid_view_->SetTopItemViewsVisible(false); 94 items_grid_view_->SetTopItemViewsVisible(false);
84 95
85 // Set initial state. 96 // Set initial state.
97 layer()->SetOpacity(show ? 0.0f : 1.0f);
86 SetVisible(true); 98 SetVisible(true);
87 layer()->SetOpacity(show ? 0.0f : 1.0f); 99 UpdateFolderNameVisibility(true);
88 100
89 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); 101 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
90 animation.SetTweenType(gfx::Tween::EASE_IN_2); 102 animation.SetTweenType(gfx::Tween::EASE_IN_2);
91 animation.AddObserver(this); 103 animation.AddObserver(this);
92 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( 104 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
93 show ? kFolderTransitionInDurationMs : kFolderTransitionOutDurationMs)); 105 show ? kFolderTransitionInDurationMs : kFolderTransitionOutDurationMs));
94 106
95 layer()->SetOpacity(show ? 1.0f : 0.0f); 107 layer()->SetOpacity(show ? 1.0f : 0.0f);
96 } 108 }
97 109
98 gfx::Size AppListFolderView::GetPreferredSize() { 110 gfx::Size AppListFolderView::GetPreferredSize() {
99 const gfx::Size header_size = folder_header_view_->GetPreferredSize(); 111 const gfx::Size header_size = folder_header_view_->GetPreferredSize();
100 const gfx::Size grid_size = items_grid_view_->GetPreferredSize(); 112 const gfx::Size grid_size = items_grid_view_->GetPreferredSize();
101 int width = std::max(header_size.width(), grid_size.width()); 113 int width = std::max(header_size.width(), grid_size.width());
102 int height = header_size.height() + grid_size.height(); 114 int height = header_size.height() + grid_size.height();
103 return gfx::Size(width, height); 115 return gfx::Size(width, height);
104 } 116 }
105 117
106 void AppListFolderView::Layout() { 118 void AppListFolderView::Layout() {
107 CalculateIdealBounds(); 119 CalculateIdealBounds();
108 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); 120 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_);
109 } 121 }
110 122
111 bool AppListFolderView::OnKeyPressed(const ui::KeyEvent& event) { 123 bool AppListFolderView::OnKeyPressed(const ui::KeyEvent& event) {
112 return items_grid_view_->OnKeyPressed(event); 124 return items_grid_view_->OnKeyPressed(event);
113 } 125 }
114 126
115 void AppListFolderView::OnListItemRemoved(size_t index, AppListItem* item) { 127 void AppListFolderView::OnListItemRemoved(size_t index, AppListItem* item) {
116 // If the folder item associated with this view is removed from the model,
117 // (e.g. the last item in the folder was deleted), reset the view and signal
118 // the container view to show the app list instead.
119 if (item == folder_item_) { 128 if (item == folder_item_) {
120 items_grid_view_->SetItemList(NULL); 129 items_grid_view_->OnFolderItemRemoved();
121 folder_header_view_->SetFolderItem(NULL); 130 folder_header_view_->OnFolderItemRemoved();
122 folder_item_ = NULL; 131 folder_item_ = NULL;
132
133 // Do not change state if it is hidden.
134 if (layer()->opacity() == 0.0f)
135 return;
136
137 // If the folder item associated with this view is removed from the model,
138 // (e.g. the last item in the folder was deleted), reset the view and signal
139 // the container view to show the app list instead.
123 // Pass NULL to ShowApps() to avoid triggering animation from the deleted 140 // Pass NULL to ShowApps() to avoid triggering animation from the deleted
124 // folder. 141 // folder.
125 container_view_->ShowApps(NULL); 142 container_view_->ShowApps(NULL);
126 } 143 }
127 } 144 }
128 145
129 void AppListFolderView::OnImplicitAnimationsCompleted() { 146 void AppListFolderView::OnImplicitAnimationsCompleted() {
130 // Show the top items when the opening folder animation is done. 147 // Show the top items when the opening folder animation is done.
131 if (layer()->opacity() == 1.0f) 148 if (layer()->opacity() == 1.0f)
132 items_grid_view_->SetTopItemViewsVisible(true); 149 items_grid_view_->SetTopItemViewsVisible(true);
133 150
134 if (layer()->opacity() == 0.0f) 151 // If the view is hidden for reparenting a folder item, it has to be visible,
152 // so that drag_view_ can keep receiving mouse events.
153 if (layer()->opacity() == 0.0f && !hide_for_reparent_)
135 SetVisible(false); 154 SetVisible(false);
155
156 // Set the view bounds to a small rect, so that it won't overlap the root
157 // level apps grid view during folder item reprenting transitional period.
158 if (hide_for_reparent_)
159 SetBoundsRect(gfx::Rect(bounds().x(), bounds().y(), 1, 1));
136 } 160 }
137 161
138 void AppListFolderView::CalculateIdealBounds() { 162 void AppListFolderView::CalculateIdealBounds() {
139 gfx::Rect rect(GetContentsBounds()); 163 gfx::Rect rect(GetContentsBounds());
140 if (rect.IsEmpty()) 164 if (rect.IsEmpty())
141 return; 165 return;
142 166
143 gfx::Rect header_frame(rect); 167 gfx::Rect header_frame(rect);
144 gfx::Size size = folder_header_view_->GetPreferredSize(); 168 gfx::Size size = folder_header_view_->GetPreferredSize();
145 header_frame.set_height(size.height()); 169 header_frame.set_height(size.height());
146 view_model_->set_ideal_bounds(kIndexFolderHeader, header_frame); 170 view_model_->set_ideal_bounds(kIndexFolderHeader, header_frame);
147 171
148 gfx::Rect grid_frame(rect); 172 gfx::Rect grid_frame(rect);
149 grid_frame.set_y(header_frame.height()); 173 grid_frame.Subtract(header_frame);
150 view_model_->set_ideal_bounds(kIndexChildItems, grid_frame); 174 view_model_->set_ideal_bounds(kIndexChildItems, grid_frame);
151 } 175 }
152 176
177 void AppListFolderView::StartSetupDragInRootLevelAppsGridView(
178 AppListItemView* original_drag_view,
179 const gfx::Point& drag_point_in_root_grid) {
180 // Converts the original_drag_view's bounds to the coordinate system of
181 // root level grid view.
182 gfx::RectF rect_f(original_drag_view->bounds());
183 views::View::ConvertRectToTarget(items_grid_view_,
184 container_view_->apps_grid_view(),
185 &rect_f);
186 gfx::Rect rect_in_root_grid_view = gfx::ToEnclosingRect(rect_f);
187
188 container_view_->apps_grid_view()->
189 InitiateDragFromReparentItemInRootLevelGridView(
190 original_drag_view, rect_in_root_grid_view, drag_point_in_root_grid);
191 }
192
153 gfx::Rect AppListFolderView::GetItemIconBoundsAt(int index) { 193 gfx::Rect AppListFolderView::GetItemIconBoundsAt(int index) {
154 AppListItemView* item_view = items_grid_view_->GetItemViewAt(index); 194 AppListItemView* item_view = items_grid_view_->GetItemViewAt(index);
155 // Icon bounds relative to AppListItemView. 195 // Icon bounds relative to AppListItemView.
156 const gfx::Rect icon_bounds = item_view->GetIconBounds(); 196 const gfx::Rect icon_bounds = item_view->GetIconBounds();
157 gfx::Rect to_apps_grid_view = item_view->ConvertRectToParent(icon_bounds); 197 gfx::Rect to_apps_grid_view = item_view->ConvertRectToParent(icon_bounds);
158 gfx::Rect to_folder = 198 gfx::Rect to_folder =
159 items_grid_view_->ConvertRectToParent(to_apps_grid_view); 199 items_grid_view_->ConvertRectToParent(to_apps_grid_view);
160 200
161 // Get the icon image's bound. 201 // Get the icon image's bound.
162 to_folder.ClampToCenteredSize( 202 to_folder.ClampToCenteredSize(
163 gfx::Size(kPreferredIconDimension, kPreferredIconDimension)); 203 gfx::Size(kPreferredIconDimension, kPreferredIconDimension));
164 204
165 return to_folder; 205 return to_folder;
166 } 206 }
167 207
208 void AppListFolderView::UpdateFolderViewBackground(bool show_bubble) {
209 if (hide_for_reparent_)
210 return;
211
212 // Before showing the folder container inking bubble, hide the folder name.
213 if (show_bubble)
214 UpdateFolderNameVisibility(false);
215
216 container_view_->folder_background_view()->UpdateFolderContainerBubble(
217 show_bubble ? FolderBackgroundView::SHOW_BUBBLE :
218 FolderBackgroundView::HIDE_BUBBLE);
219 }
220
221 void AppListFolderView::UpdateFolderNameVisibility(bool visible) {
222 folder_header_view_->UpdateFolderNameVisibility(visible);
223 }
224
225 bool AppListFolderView::IsPointOutsideOfFolderBoundray(
226 const gfx::Point& point) {
227 if (!GetLocalBounds().Contains(point))
228 return true;
229
230 gfx::Point center = GetLocalBounds().CenterPoint();
231 float delta = (point - center).Length();
232 return delta > container_view_->folder_background_view()->
233 GetFolderContainerBubbleRadius() + kOutOfFolderContainerBubbleDelta;
234 }
235
236 // When user drags a folder item out of the folder boundary ink bubble, the
237 // folder view UI will be hidden, and switch back to top level AppsGridView.
238 // The dragged item will seamlessly move on the top level AppsGridView.
239 // In order to achieve the above, we keep the folder view and its child grid
240 // view visible with opacity 0, so that the drag_view_ on the hidden grid view
241 // will keep receiving mouse event. At the same time, we initiated a new
242 // drag_view_ in the top level grid view, and keep it moving with the hidden
243 // grid view's drag_view_, so that the dragged item can be engaged in drag and
244 // drop flow in the top level grid view. During the reparenting process, the
245 // drag_view_ in hidden grid view will dispatch the drag and drop event to
246 // the top level grid view, until the drag ends.
247 void AppListFolderView::ReparentItem(
248 AppListItemView* original_drag_view,
249 const gfx::Point& drag_point_in_folder_grid) {
250 // Convert the drag point relative to the root level AppsGridView.
251 gfx::Point to_root_level_grid = drag_point_in_folder_grid;
252 ConvertPointToTarget(items_grid_view_,
253 container_view_->apps_grid_view(),
254 &to_root_level_grid);
255 StartSetupDragInRootLevelAppsGridView(original_drag_view, to_root_level_grid);
256 container_view_->ReparentFolderItemTransit(folder_item_);
257 }
258
259 void AppListFolderView::DispatchDragEventForReparent(
260 AppsGridView::Pointer pointer,
261 const ui::LocatedEvent& event) {
262 container_view_->apps_grid_view()->UpdateDragFromReparentItem(pointer, event);
263 }
264
265 void AppListFolderView::DispatchEndDragEventForReparent(
266 bool events_forwarded_to_drag_drop_host) {
267 container_view_->apps_grid_view()->
268 EndDragFromReparentItemInRootLevel(events_forwarded_to_drag_drop_host);
269 }
270
168 void AppListFolderView::NavigateBack(AppListFolderItem* item, 271 void AppListFolderView::NavigateBack(AppListFolderItem* item,
169 const ui::Event& event_flags) { 272 const ui::Event& event_flags) {
170 container_view_->ShowApps(item); 273 container_view_->ShowApps(item);
171 } 274 }
172 275
173 } // namespace app_list 276 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/views/app_list_folder_view.h ('k') | ui/app_list/views/app_list_item_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698