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

Side by Side Diff: ash/system/web_notification/web_notification_view.cc

Issue 11229022: Move ash/system/web_notification message_center to ui/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase again. Created 8 years, 1 month 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
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 "ash/system/web_notification/web_notification_view.h"
6
7 #include "grit/ash_resources.h"
8 #include "grit/ash_strings.h"
9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/base/models/simple_menu_model.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h"
13 #include "ui/views/controls/button/image_button.h"
14 #include "ui/views/controls/image_view.h"
15 #include "ui/views/controls/scroll_view.h"
16 #include "ui/views/controls/label.h"
17 #include "ui/views/controls/menu/menu_model_adapter.h"
18 #include "ui/views/controls/menu/menu_runner.h"
19 #include "ui/views/layout/grid_layout.h"
20 #include "ui/views/widget/widget.h"
21
22 namespace {
23 const int kPaddingHorizontal = 18;
24 const int kPaddingBetweenItems = 10;
25 }
26
27 namespace message_center {
28
29 const SkColor kNotificationColor = SkColorSetRGB(0xfe, 0xfe, 0xfe);
30 const SkColor kNotificationReadColor = SkColorSetRGB(0xfa, 0xfa, 0xfa);
31
32 // Menu constants
33 const int kTogglePermissionCommand = 0;
34 const int kToggleExtensionCommand = 1;
35 const int kShowSettingsCommand = 2;
36
37 // A dropdown menu for notifications.
38 class WebNotificationMenuModel : public ui::SimpleMenuModel,
39 public ui::SimpleMenuModel::Delegate {
40 public:
41 WebNotificationMenuModel(WebNotificationList::Delegate* list_delegate,
42 const WebNotification& notification)
43 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
44 list_delegate_(list_delegate),
45 notification_(notification) {
46 // Add 'disable notifications' menu item.
47 if (!notification.extension_id.empty()) {
48 AddItem(kToggleExtensionCommand,
49 GetLabelForCommandId(kToggleExtensionCommand));
50 } else if (!notification.display_source.empty()) {
51 AddItem(kTogglePermissionCommand,
52 GetLabelForCommandId(kTogglePermissionCommand));
53 }
54 // Add settings menu item.
55 if (!notification.display_source.empty()) {
56 AddItem(kShowSettingsCommand,
57 GetLabelForCommandId(kShowSettingsCommand));
58 }
59 }
60
61 virtual ~WebNotificationMenuModel() {
62 }
63
64 // Overridden from ui::SimpleMenuModel:
65 virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE {
66 switch (command_id) {
67 case kToggleExtensionCommand:
68 return l10n_util::GetStringUTF16(
69 IDS_ASH_WEB_NOTFICATION_TRAY_EXTENSIONS_DISABLE);
70 case kTogglePermissionCommand:
71 return l10n_util::GetStringFUTF16(
72 IDS_ASH_WEB_NOTFICATION_TRAY_SITE_DISABLE,
73 notification_.display_source);
74 case kShowSettingsCommand:
75 return l10n_util::GetStringUTF16(
76 IDS_ASH_WEB_NOTFICATION_TRAY_SETTINGS);
77 default:
78 NOTREACHED();
79 }
80 return string16();
81 }
82
83 // Overridden from ui::SimpleMenuModel::Delegate:
84 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
85 return false;
86 }
87
88 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
89 return false;
90 }
91
92 virtual bool GetAcceleratorForCommandId(
93 int command_id,
94 ui::Accelerator* accelerator) OVERRIDE {
95 return false;
96 }
97
98 virtual void ExecuteCommand(int command_id) OVERRIDE {
99 switch (command_id) {
100 case kToggleExtensionCommand:
101 list_delegate_->DisableNotificationByExtension(notification_.id);
102 break;
103 case kTogglePermissionCommand:
104 list_delegate_->DisableNotificationByUrl(notification_.id);
105 break;
106 case kShowSettingsCommand:
107 list_delegate_->ShowNotificationSettings(notification_.id);
108 break;
109 default:
110 NOTREACHED();
111 }
112 }
113
114 private:
115 WebNotificationList::Delegate* list_delegate_;
116 WebNotification notification_;
117
118 DISALLOW_COPY_AND_ASSIGN(WebNotificationMenuModel);
119 };
120
121 WebNotificationView::WebNotificationView(
122 WebNotificationList::Delegate* list_delegate,
123 const WebNotification& notification,
124 int scroll_bar_width)
125 : list_delegate_(list_delegate),
126 notification_(notification),
127 icon_(NULL),
128 close_button_(NULL),
129 scroller_(NULL),
130 gesture_scroll_amount_(0.f) {
131 SkColor bg_color = notification.is_read ?
132 kNotificationReadColor : kNotificationColor;
133 set_background(views::Background::CreateSolidBackground(bg_color));
134 SetPaintToLayer(true);
135 SetFillsBoundsOpaquely(false);
136
137 icon_ = new views::ImageView;
138 icon_->SetImageSize(
139 gfx::Size(kWebNotificationIconSize, kWebNotificationIconSize));
140 icon_->SetImage(notification.image);
141
142 views::Label* title = new views::Label(notification.title);
143 title->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
144 title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD));
145 views::Label* message = new views::Label(notification.message);
146 message->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
147 message->SetMultiLine(true);
148
149 close_button_ = new views::ImageButton(this);
150 close_button_->SetImage(
151 views::CustomButton::BS_NORMAL,
152 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
153 IDR_AURA_UBER_TRAY_NOTIFY_CLOSE));
154 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
155 views::ImageButton::ALIGN_MIDDLE);
156
157 views::GridLayout* layout = new views::GridLayout(this);
158 SetLayoutManager(layout);
159
160 views::ColumnSet* columns = layout->AddColumnSet(0);
161
162 const int padding_width = kPaddingHorizontal / 2;
163 columns->AddPaddingColumn(0, padding_width);
164
165 // Notification Icon.
166 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
167 0, /* resize percent */
168 views::GridLayout::FIXED,
169 kWebNotificationIconSize, kWebNotificationIconSize);
170
171 columns->AddPaddingColumn(0, padding_width);
172
173 // Notification message text.
174 const int message_width = kWebNotificationWidth - kWebNotificationIconSize -
175 kWebNotificationButtonWidth - (padding_width * 3) - scroll_bar_width;
176 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
177 100, /* resize percent */
178 views::GridLayout::FIXED,
179 message_width, message_width);
180
181 columns->AddPaddingColumn(0, padding_width);
182
183 // Close button.
184 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
185 0, /* resize percent */
186 views::GridLayout::FIXED,
187 kWebNotificationButtonWidth,
188 kWebNotificationButtonWidth);
189
190 // Layout rows
191 layout->AddPaddingRow(0, kPaddingBetweenItems);
192
193 layout->StartRow(0, 0);
194 layout->AddView(icon_, 1, 2);
195 layout->AddView(title, 1, 1);
196 layout->AddView(close_button_, 1, 1);
197
198 layout->StartRow(0, 0);
199 layout->SkipColumns(2);
200 layout->AddView(message, 1, 1);
201 layout->AddPaddingRow(0, kPaddingBetweenItems);
202 }
203
204 WebNotificationView::~WebNotificationView() {
205 }
206
207 bool WebNotificationView::OnMousePressed(const ui::MouseEvent& event) {
208 if (event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) {
209 ShowMenu(event.location());
210 return true;
211 }
212 list_delegate_->OnNotificationClicked(notification_.id);
213 return true;
214 }
215
216 ui::EventResult WebNotificationView::OnGestureEvent(
217 const ui::GestureEvent& event) {
218 if (event.type() == ui::ET_GESTURE_TAP) {
219 list_delegate_->OnNotificationClicked(notification_.id);
220 return ui::ER_CONSUMED;
221 }
222
223 if (event.type() == ui::ET_GESTURE_LONG_PRESS) {
224 ShowMenu(event.location());
225 return ui::ER_CONSUMED;
226 }
227
228 if (event.type() == ui::ET_SCROLL_FLING_START) {
229 // The threshold for the fling velocity is computed empirically.
230 // The unit is in pixels/second.
231 const float kFlingThresholdForClose = 800.f;
232 if (fabsf(event.details().velocity_x()) > kFlingThresholdForClose) {
233 SlideOutAndClose(event.details().velocity_x() < 0 ? SLIDE_LEFT :
234 SLIDE_RIGHT);
235 } else if (scroller_) {
236 RestoreVisualState();
237 scroller_->OnGestureEvent(event);
238 }
239 return ui::ER_CONSUMED;
240 }
241
242 if (!event.IsScrollGestureEvent())
243 return ui::ER_UNHANDLED;
244
245 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) {
246 gesture_scroll_amount_ = 0.f;
247 } else if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) {
248 // The scroll-update events include the incremental scroll amount.
249 gesture_scroll_amount_ += event.details().scroll_x();
250
251 gfx::Transform transform;
252 transform.SetTranslateX(gesture_scroll_amount_);
253 layer()->SetTransform(transform);
254 layer()->SetOpacity(
255 1.f - std::min(fabsf(gesture_scroll_amount_) / width(), 1.f));
256
257 } else if (event.type() == ui::ET_GESTURE_SCROLL_END) {
258 const float kScrollRatioForClosingNotification = 0.5f;
259 float scrolled_ratio = fabsf(gesture_scroll_amount_) / width();
260 if (scrolled_ratio >= kScrollRatioForClosingNotification)
261 SlideOutAndClose(gesture_scroll_amount_ < 0 ? SLIDE_LEFT : SLIDE_RIGHT);
262 else
263 RestoreVisualState();
264 }
265
266 if (scroller_)
267 scroller_->OnGestureEvent(event);
268 return ui::ER_CONSUMED;
269 }
270
271 void WebNotificationView::ButtonPressed(views::Button* sender,
272 const ui::Event& event) {
273 if (sender == close_button_)
274 list_delegate_->SendRemoveNotification(notification_.id);
275 }
276
277 void WebNotificationView::OnImplicitAnimationsCompleted() {
278 list_delegate_->SendRemoveNotification(notification_.id);
279 }
280
281 void WebNotificationView::ShowMenu(gfx::Point screen_location) {
282 WebNotificationMenuModel menu_model(list_delegate_, notification_);
283 if (menu_model.GetItemCount() == 0)
284 return;
285
286 views::MenuModelAdapter menu_model_adapter(&menu_model);
287 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
288
289 views::View::ConvertPointToScreen(this, &screen_location);
290 ignore_result(menu_runner.RunMenuAt(
291 GetWidget()->GetTopLevelWidget(),
292 NULL,
293 gfx::Rect(screen_location, gfx::Size()),
294 views::MenuItemView::TOPRIGHT,
295 views::MenuRunner::HAS_MNEMONICS));
296 }
297
298 void WebNotificationView::RestoreVisualState() {
299 // Restore the layer state.
300 const int kSwipeRestoreDurationMS = 150;
301 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
302 settings.SetTransitionDuration(
303 base::TimeDelta::FromMilliseconds(kSwipeRestoreDurationMS));
304 layer()->SetTransform(gfx::Transform());
305 layer()->SetOpacity(1.f);
306 }
307
308 void WebNotificationView::SlideOutAndClose(SlideDirection direction) {
309 const int kSwipeOutTotalDurationMS = 150;
310 int swipe_out_duration = kSwipeOutTotalDurationMS * layer()->opacity();
311 ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
312 settings.SetTransitionDuration(
313 base::TimeDelta::FromMilliseconds(swipe_out_duration));
314 settings.AddObserver(this);
315
316 gfx::Transform transform;
317 transform.SetTranslateX(direction == SLIDE_LEFT ? -width() : width());
318 layer()->SetTransform(transform);
319 layer()->SetOpacity(0.f);
320 }
321
322 } // namespace message_center
OLDNEW
« no previous file with comments | « ash/system/web_notification/web_notification_view.h ('k') | ash/wm/gestures/tray_gesture_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698