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

Side by Side Diff: ui/app_list/app_list_item_view.cc

Issue 11784034: Skeleton for app_list on OSX, and refactoring for enable_app_list=1 on OS=="mac". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase for 175876 and 175961 Created 7 years, 11 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 | « ui/app_list/app_list_item_view.h ('k') | ui/app_list/app_list_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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/app_list/app_list_item_view.h"
6
7 #include <algorithm>
8
9 #include "base/utf_string_conversions.h"
10 #include "ui/app_list/app_list_item_model.h"
11 #include "ui/app_list/apps_grid_view.h"
12 #include "ui/base/accessibility/accessible_view_state.h"
13 #include "ui/base/animation/throb_animation.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/compositor/layer.h"
16 #include "ui/compositor/scoped_layer_animation_settings.h"
17 #include "ui/gfx/canvas.h"
18 #include "ui/gfx/font.h"
19 #include "ui/gfx/image/image_skia_operations.h"
20 #include "ui/gfx/transform_util.h"
21 #include "ui/views/controls/image_view.h"
22 #include "ui/views/controls/label.h"
23 #include "ui/views/controls/menu/menu_item_view.h"
24 #include "ui/views/controls/menu/menu_model_adapter.h"
25 #include "ui/views/controls/menu/menu_runner.h"
26
27 namespace app_list {
28
29 namespace {
30
31 const int kTopBottomPadding = 10;
32 const int kTopPadding = 20;
33 const int kIconTitleSpacing = 7;
34
35 const SkColor kTitleColor = SkColorSetRGB(0x5A, 0x5A, 0x5A);
36 const SkColor kTitleHoverColor = SkColorSetRGB(0x3C, 0x3C, 0x3C);
37
38 const SkColor kHoverAndPushedColor = SkColorSetARGB(0x19, 0, 0, 0);
39 const SkColor kSelectedColor = SkColorSetARGB(0x0D, 0, 0, 0);
40 const SkColor kHighlightedColor = kHoverAndPushedColor;
41
42 const int kLeftRightPaddingChars = 1;
43
44 // Scale to transform the icon when a drag starts.
45 const float kDraggingIconScale = 1.5f;
46
47 // Delay in milliseconds of when the dragging UI should be shown for mouse drag.
48 const int kMouseDragUIDelayInMs = 100;
49
50 } // namespace
51
52 // static
53 const char AppListItemView::kViewClassName[] = "ui/app_list/AppListItemView";
54
55 AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
56 AppListItemModel* model)
57 : CustomButton(apps_grid_view),
58 model_(model),
59 apps_grid_view_(apps_grid_view),
60 icon_(new views::ImageView),
61 title_(new views::Label),
62 ui_state_(UI_STATE_NORMAL),
63 touch_dragging_(false) {
64 icon_->set_interactive(false);
65
66 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
67 title_->SetBackgroundColor(0);
68 title_->SetAutoColorReadabilityEnabled(false);
69 title_->SetEnabledColor(kTitleColor);
70 title_->SetFont(rb.GetFont(ui::ResourceBundle::SmallBoldFont));
71 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
72
73 const gfx::ShadowValue kIconShadows[] = {
74 gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0)),
75 };
76 icon_shadows_.assign(kIconShadows, kIconShadows + arraysize(kIconShadows));
77
78 AddChildView(icon_);
79 AddChildView(title_);
80
81 ItemIconChanged();
82 ItemTitleChanged();
83 model_->AddObserver(this);
84
85 set_context_menu_controller(this);
86 set_request_focus_on_press(false);
87 }
88
89 AppListItemView::~AppListItemView() {
90 model_->RemoveObserver(this);
91 }
92
93 void AppListItemView::SetIconSize(const gfx::Size& size) {
94 if (icon_size_ == size)
95 return;
96
97 icon_size_ = size;
98 UpdateIcon();
99 }
100
101 void AppListItemView::UpdateIcon() {
102 // Skip if |icon_size_| has not been determined.
103 if (icon_size_.IsEmpty())
104 return;
105
106 gfx::ImageSkia icon = model_->icon();
107 // Clear icon and bail out if model icon is empty.
108 if (icon.isNull()) {
109 icon_->SetImage(NULL);
110 return;
111 }
112
113 gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage(icon,
114 skia::ImageOperations::RESIZE_BEST, icon_size_));
115 gfx::ImageSkia shadow(
116 gfx::ImageSkiaOperations::CreateImageWithDropShadow(resized,
117 icon_shadows_));
118 icon_->SetImage(shadow);
119 }
120
121 void AppListItemView::SetUIState(UIState state) {
122 if (ui_state_ == state)
123 return;
124
125 ui_state_ = state;
126
127 #if defined(USE_AURA)
128 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
129 switch (ui_state_) {
130 case UI_STATE_NORMAL:
131 title_->SetVisible(true);
132 layer()->SetTransform(gfx::Transform());
133 break;
134 case UI_STATE_DRAGGING:
135 title_->SetVisible(false);
136 const gfx::Rect bounds(layer()->bounds().size());
137 layer()->SetTransform(gfx::GetScaleTransform(
138 bounds.CenterPoint(),
139 kDraggingIconScale));
140 break;
141 }
142 #endif
143 }
144
145 void AppListItemView::SetTouchDragging(bool touch_dragging) {
146 if (touch_dragging_ == touch_dragging)
147 return;
148
149 touch_dragging_ = touch_dragging;
150 SetUIState(touch_dragging_ ? UI_STATE_DRAGGING : UI_STATE_NORMAL);
151 }
152
153 void AppListItemView::OnMouseDragTimer() {
154 DCHECK(apps_grid_view_->IsDraggedView(this));
155 SetUIState(UI_STATE_DRAGGING);
156 }
157
158 void AppListItemView::ItemIconChanged() {
159 UpdateIcon();
160 }
161
162 void AppListItemView::ItemTitleChanged() {
163 title_->SetText(UTF8ToUTF16(model_->title()));
164 }
165
166 void AppListItemView::ItemHighlightedChanged() {
167 apps_grid_view_->EnsureViewVisible(this);
168 SchedulePaint();
169 }
170
171 std::string AppListItemView::GetClassName() const {
172 return kViewClassName;
173 }
174
175 void AppListItemView::Layout() {
176 gfx::Rect rect(GetContentsBounds());
177
178 const int left_right_padding = kLeftRightPaddingChars *
179 title_->font().GetAverageCharacterWidth();
180 rect.Inset(left_right_padding, kTopPadding, left_right_padding, 0);
181 const int y = rect.y();
182
183 gfx::Rect icon_bounds(rect.x(), y, rect.width(), icon_size_.height());
184 icon_bounds.Inset(gfx::ShadowValue::GetMargin(icon_shadows_));
185 icon_->SetBoundsRect(icon_bounds);
186
187 const gfx::Size title_size = title_->GetPreferredSize();
188 gfx::Rect title_bounds(rect.x() + (rect.width() - title_size.width()) / 2,
189 y + icon_size_.height() + kIconTitleSpacing,
190 title_size.width(),
191 title_size.height());
192 title_bounds.Intersect(rect);
193 title_->SetBoundsRect(title_bounds);
194 }
195
196 void AppListItemView::OnPaint(gfx::Canvas* canvas) {
197 if (apps_grid_view_->IsDraggedView(this))
198 return;
199
200 gfx::Rect rect(GetContentsBounds());
201
202 if (model_->highlighted()) {
203 canvas->FillRect(rect, kHighlightedColor);
204 } else if (hover_animation_->is_animating()) {
205 int alpha = SkColorGetA(kHoverAndPushedColor) *
206 hover_animation_->GetCurrentValue();
207 canvas->FillRect(rect, SkColorSetA(kHoverAndPushedColor, alpha));
208 } else if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
209 canvas->FillRect(rect, kHoverAndPushedColor);
210 } else if (apps_grid_view_->IsSelectedView(this)) {
211 canvas->FillRect(rect, kSelectedColor);
212 }
213 }
214
215 void AppListItemView::GetAccessibleState(ui::AccessibleViewState* state) {
216 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
217 state->name = UTF8ToUTF16(model_->title());
218 }
219
220 void AppListItemView::ShowContextMenuForView(views::View* source,
221 const gfx::Point& point) {
222 ui::MenuModel* menu_model = model_->GetContextMenuModel();
223 if (!menu_model)
224 return;
225
226 views::MenuModelAdapter menu_adapter(menu_model);
227 context_menu_runner_.reset(
228 new views::MenuRunner(new views::MenuItemView(&menu_adapter)));
229 menu_adapter.BuildMenu(context_menu_runner_->GetMenu());
230 if (context_menu_runner_->RunMenuAt(
231 GetWidget(), NULL, gfx::Rect(point, gfx::Size()),
232 views::MenuItemView::TOPLEFT, views::MenuRunner::HAS_MNEMONICS) ==
233 views::MenuRunner::MENU_DELETED)
234 return;
235 }
236
237 void AppListItemView::StateChanged() {
238 if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
239 apps_grid_view_->SetSelectedView(this);
240 title_->SetEnabledColor(kTitleHoverColor);
241 } else {
242 apps_grid_view_->ClearSelectedView(this);
243 model_->SetHighlighted(false);
244 title_->SetEnabledColor(kTitleColor);
245 }
246 }
247
248 bool AppListItemView::ShouldEnterPushedState(const ui::Event& event) {
249 // Don't enter pushed state for ET_GESTURE_TAP_DOWN so that hover gray
250 // background does not show up during scroll.
251 if (event.type() == ui::ET_GESTURE_TAP_DOWN)
252 return false;
253
254 return views::CustomButton::ShouldEnterPushedState(event);
255 }
256
257 bool AppListItemView::OnMousePressed(const ui::MouseEvent& event) {
258 CustomButton::OnMousePressed(event);
259
260 if (!ShouldEnterPushedState(event))
261 return true;
262
263 apps_grid_view_->InitiateDrag(this, AppsGridView::MOUSE, event);
264
265 if (apps_grid_view_->IsDraggedView(this)) {
266 mouse_drag_timer_.Start(FROM_HERE,
267 base::TimeDelta::FromMilliseconds(kMouseDragUIDelayInMs),
268 this, &AppListItemView::OnMouseDragTimer);
269 }
270 return true;
271 }
272
273 void AppListItemView::OnMouseReleased(const ui::MouseEvent& event) {
274 CustomButton::OnMouseReleased(event);
275 apps_grid_view_->EndDrag(false);
276 mouse_drag_timer_.Stop();
277 SetUIState(UI_STATE_NORMAL);
278 }
279
280 void AppListItemView::OnMouseCaptureLost() {
281 CustomButton::OnMouseCaptureLost();
282 apps_grid_view_->EndDrag(true);
283 mouse_drag_timer_.Stop();
284 SetUIState(UI_STATE_NORMAL);
285 }
286
287 bool AppListItemView::OnMouseDragged(const ui::MouseEvent& event) {
288 CustomButton::OnMouseDragged(event);
289 apps_grid_view_->UpdateDrag(this, AppsGridView::MOUSE, event);
290
291 // Shows dragging UI when it's confirmed without waiting for the timer.
292 if (ui_state_ != UI_STATE_DRAGGING &&
293 apps_grid_view_->dragging() &&
294 apps_grid_view_->IsDraggedView(this)) {
295 mouse_drag_timer_.Stop();
296 SetUIState(UI_STATE_DRAGGING);
297 }
298 return true;
299 }
300
301 void AppListItemView::OnGestureEvent(ui::GestureEvent* event) {
302 switch (event->type()) {
303 case ui::ET_GESTURE_SCROLL_BEGIN:
304 if (touch_dragging_) {
305 apps_grid_view_->InitiateDrag(this, AppsGridView::TOUCH, *event);
306 event->SetHandled();
307 }
308 break;
309 case ui::ET_GESTURE_SCROLL_UPDATE:
310 if (touch_dragging_) {
311 apps_grid_view_->UpdateDrag(this, AppsGridView::TOUCH, *event);
312 event->SetHandled();
313 }
314 break;
315 case ui::ET_GESTURE_SCROLL_END:
316 case ui::ET_SCROLL_FLING_START:
317 if (touch_dragging_) {
318 SetTouchDragging(false);
319 apps_grid_view_->EndDrag(false);
320 event->SetHandled();
321 }
322 break;
323 case ui::ET_GESTURE_LONG_PRESS:
324 if (!apps_grid_view_->has_dragged_view())
325 SetTouchDragging(true);
326 event->SetHandled();
327 break;
328 case ui::ET_GESTURE_END:
329 if (touch_dragging_) {
330 SetTouchDragging(false);
331
332 gfx::Point location(event->location());
333 ConvertPointToScreen(this, &location);
334 ShowContextMenu(location, true);
335 }
336 break;
337 default:
338 break;
339 }
340 if (!event->handled())
341 CustomButton::OnGestureEvent(event);
342 }
343
344 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/app_list_item_view.h ('k') | ui/app_list/app_list_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698