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

Side by Side Diff: ui/arc/notification/arc_custom_notification_view.cc

Issue 2319893002: Merge "arc: Defer notification surface creation" (Closed)
Patch Set: Created 4 years, 3 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/arc/notification/arc_custom_notification_view.h" 5 #include "ui/arc/notification/arc_custom_notification_view.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "components/exo/notification_surface.h" 8 #include "components/exo/notification_surface.h"
9 #include "components/exo/surface.h" 9 #include "components/exo/surface.h"
10 #include "third_party/skia/include/core/SkColor.h" 10 #include "third_party/skia/include/core/SkColor.h"
11 #include "ui/base/l10n/l10n_util.h" 11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/base/resource/resource_bundle.h" 12 #include "ui/base/resource/resource_bundle.h"
13 #include "ui/compositor/layer_animation_observer.h" 13 #include "ui/compositor/layer_animation_observer.h"
14 #include "ui/display/screen.h" 14 #include "ui/display/screen.h"
15 #include "ui/events/event_handler.h" 15 #include "ui/events/event_handler.h"
16 #include "ui/gfx/canvas.h"
17 #include "ui/gfx/image/image_skia.h"
16 #include "ui/gfx/transform.h" 18 #include "ui/gfx/transform.h"
17 #include "ui/message_center/message_center_style.h" 19 #include "ui/message_center/message_center_style.h"
18 #include "ui/resources/grit/ui_resources.h" 20 #include "ui/resources/grit/ui_resources.h"
19 #include "ui/strings/grit/ui_strings.h" 21 #include "ui/strings/grit/ui_strings.h"
20 #include "ui/views/background.h" 22 #include "ui/views/background.h"
21 #include "ui/views/border.h" 23 #include "ui/views/border.h"
22 #include "ui/views/controls/button/image_button.h" 24 #include "ui/views/controls/button/image_button.h"
23 #include "ui/views/widget/widget.h" 25 #include "ui/views/widget/widget.h"
24 #include "ui/wm/core/window_util.h" 26 #include "ui/wm/core/window_util.h"
25 27
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {} 136 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {}
135 137
136 ArcCustomNotificationView* const owner_; 138 ArcCustomNotificationView* const owner_;
137 bool sliding_ = false; 139 bool sliding_ = false;
138 std::unique_ptr<ui::LayerTreeOwner> surface_copy_; 140 std::unique_ptr<ui::LayerTreeOwner> surface_copy_;
139 141
140 DISALLOW_COPY_AND_ASSIGN(SlideHelper); 142 DISALLOW_COPY_AND_ASSIGN(SlideHelper);
141 }; 143 };
142 144
143 ArcCustomNotificationView::ArcCustomNotificationView( 145 ArcCustomNotificationView::ArcCustomNotificationView(
144 ArcCustomNotificationItem* item, 146 ArcCustomNotificationItem* item)
145 exo::NotificationSurface* surface) 147 : item_(item),
146 : item_(item), event_forwarder_(new EventForwarder(this)) { 148 notification_key_(item->notification_key()),
147 SetSurface(surface); 149 event_forwarder_(new EventForwarder(this)) {
150 item_->IncrementWindowRefCount();
148 item_->AddObserver(this); 151 item_->AddObserver(this);
149 OnItemPinnedChanged(); 152
153 ArcNotificationSurfaceManager::Get()->AddObserver(this);
154 exo::NotificationSurface* surface =
155 ArcNotificationSurfaceManager::Get()->GetSurface(notification_key_);
156 if (surface)
157 OnNotificationSurfaceAdded(surface);
150 158
151 // Create a layer as an anchor to insert surface copy during a slide. 159 // Create a layer as an anchor to insert surface copy during a slide.
152 SetPaintToLayer(true); 160 SetPaintToLayer(true);
161 UpdatePreferredSize();
153 } 162 }
154 163
155 ArcCustomNotificationView::~ArcCustomNotificationView() { 164 ArcCustomNotificationView::~ArcCustomNotificationView() {
156 SetSurface(nullptr); 165 SetSurface(nullptr);
157 if (item_) 166 if (item_) {
167 item_->DecrementWindowRefCount();
158 item_->RemoveObserver(this); 168 item_->RemoveObserver(this);
169 }
170
171 if (ArcNotificationSurfaceManager::Get())
172 ArcNotificationSurfaceManager::Get()->RemoveObserver(this);
159 } 173 }
160 174
161 void ArcCustomNotificationView::CreateFloatingCloseButton() { 175 void ArcCustomNotificationView::CreateFloatingCloseButton() {
176 if (!surface_)
177 return;
178
162 floating_close_button_ = new views::ImageButton(this); 179 floating_close_button_ = new views::ImageButton(this);
163 floating_close_button_->set_background( 180 floating_close_button_->set_background(
164 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); 181 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT));
165 182
166 // The sizes below are in DIPs. 183 // The sizes below are in DIPs.
167 constexpr int kPaddingFromBorder = 4; 184 constexpr int kPaddingFromBorder = 4;
168 constexpr int kImageSize = 16; 185 constexpr int kImageSize = 16;
169 constexpr int kTouchExtendedPadding = 186 constexpr int kTouchExtendedPadding =
170 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; 187 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder;
171 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder( 188 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder(
(...skipping 27 matching lines...) Expand all
199 if (surface_ && surface_->window()) { 216 if (surface_ && surface_->window()) {
200 surface_->window()->RemoveObserver(this); 217 surface_->window()->RemoveObserver(this);
201 surface_->window()->RemovePreTargetHandler(event_forwarder_.get()); 218 surface_->window()->RemovePreTargetHandler(event_forwarder_.get());
202 } 219 }
203 220
204 surface_ = surface; 221 surface_ = surface;
205 222
206 if (surface_ && surface_->window()) { 223 if (surface_ && surface_->window()) {
207 surface_->window()->AddObserver(this); 224 surface_->window()->AddObserver(this);
208 surface_->window()->AddPreTargetHandler(event_forwarder_.get()); 225 surface_->window()->AddPreTargetHandler(event_forwarder_.get());
226
227 if (GetWidget())
228 AttachSurface();
229
230 UpdatePinnedState();
209 } 231 }
210 } 232 }
211 233
212 void ArcCustomNotificationView::UpdatePreferredSize() { 234 void ArcCustomNotificationView::UpdatePreferredSize() {
213 gfx::Size preferred_size = surface_->GetSize(); 235 gfx::Size preferred_size =
236 surface_ ? surface_->GetSize() : item_ ? item_->snapshot().size()
237 : gfx::Size();
238 if (preferred_size.IsEmpty())
239 return;
240
214 if (preferred_size.width() != message_center::kNotificationWidth) { 241 if (preferred_size.width() != message_center::kNotificationWidth) {
215 const float scale = static_cast<float>(message_center::kNotificationWidth) / 242 const float scale = static_cast<float>(message_center::kNotificationWidth) /
216 preferred_size.width(); 243 preferred_size.width();
217 preferred_size.SetSize(message_center::kNotificationWidth, 244 preferred_size.SetSize(message_center::kNotificationWidth,
218 preferred_size.height() * scale); 245 preferred_size.height() * scale);
219 } 246 }
220 247
221 SetPreferredSize(preferred_size); 248 SetPreferredSize(preferred_size);
222 } 249 }
223 250
224 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() { 251 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() {
225 if (!surface_ || !floating_close_button_widget_) 252 if (!surface_ || !floating_close_button_widget_)
226 return; 253 return;
227 254
228 const bool target_visiblity = 255 const bool target_visiblity =
229 surface_->window()->GetBoundsInScreen().Contains( 256 surface_->window()->GetBoundsInScreen().Contains(
230 display::Screen::GetScreen()->GetCursorScreenPoint()); 257 display::Screen::GetScreen()->GetCursorScreenPoint());
231 if (target_visiblity == floating_close_button_widget_->IsVisible()) 258 if (target_visiblity == floating_close_button_widget_->IsVisible())
232 return; 259 return;
233 260
234 if (target_visiblity) 261 if (target_visiblity)
235 floating_close_button_widget_->Show(); 262 floating_close_button_widget_->Show();
236 else 263 else
237 floating_close_button_widget_->Hide(); 264 floating_close_button_widget_->Hide();
238 } 265 }
239 266
267 void ArcCustomNotificationView::UpdatePinnedState() {
268 if (item_->pinned() && floating_close_button_widget_) {
269 floating_close_button_widget_.reset();
270 } else if (!item_->pinned() && !floating_close_button_widget_) {
271 CreateFloatingCloseButton();
272 }
273 }
274
275 void ArcCustomNotificationView::UpdateSnapshot() {
276 // Bail if we have a |surface_| because it controls the sizes and paints UI.
277 if (surface_)
278 return;
279
280 UpdatePreferredSize();
281 SchedulePaint();
282 }
283
284 void ArcCustomNotificationView::AttachSurface() {
285 if (!GetWidget())
286 return;
287
288 UpdatePreferredSize();
289 Attach(surface_->window());
290
291 // Creates slide helper after this view is added to its parent.
292 slide_helper_.reset(new SlideHelper(this));
293 }
294
240 void ArcCustomNotificationView::ViewHierarchyChanged( 295 void ArcCustomNotificationView::ViewHierarchyChanged(
241 const views::View::ViewHierarchyChangedDetails& details) { 296 const views::View::ViewHierarchyChangedDetails& details) {
242 views::Widget* widget = GetWidget(); 297 views::Widget* widget = GetWidget();
243 298
244 if (!details.is_add) { 299 if (!details.is_add) {
245 // Resets slide helper when this view is removed from its parent. 300 // Resets slide helper when this view is removed from its parent.
246 slide_helper_.reset(); 301 slide_helper_.reset();
247 } 302 }
248 303
249 // Bail if native_view() has attached to a different widget. 304 // Bail if native_view() has attached to a different widget.
250 if (widget && native_view() && 305 if (widget && native_view() &&
251 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { 306 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) {
252 return; 307 return;
253 } 308 }
254 309
255 views::NativeViewHost::ViewHierarchyChanged(details); 310 views::NativeViewHost::ViewHierarchyChanged(details);
256 311
257 if (!widget || !surface_ || !details.is_add) 312 if (!widget || !surface_ || !details.is_add)
258 return; 313 return;
259 314
260 UpdatePreferredSize(); 315 AttachSurface();
261 Attach(surface_->window());
262
263 // Creates slide helper after this view is added to its parent.
264 slide_helper_.reset(new SlideHelper(this));
265 } 316 }
266 317
267 void ArcCustomNotificationView::Layout() { 318 void ArcCustomNotificationView::Layout() {
268 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 319 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
269 320
270 views::NativeViewHost::Layout(); 321 views::NativeViewHost::Layout();
271 322
272 if (!surface_ || !GetWidget()) 323 if (!surface_ || !GetWidget())
273 return; 324 return;
274 325
(...skipping 18 matching lines...) Expand all
293 344
294 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize()); 345 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize());
295 close_button_bounds.set_x(contents_bounds.right() - 346 close_button_bounds.set_x(contents_bounds.right() -
296 close_button_bounds.width()); 347 close_button_bounds.width());
297 close_button_bounds.set_y(contents_bounds.y()); 348 close_button_bounds.set_y(contents_bounds.y());
298 floating_close_button_widget_->SetBounds(close_button_bounds); 349 floating_close_button_widget_->SetBounds(close_button_bounds);
299 350
300 UpdateCloseButtonVisiblity(); 351 UpdateCloseButtonVisiblity();
301 } 352 }
302 353
354 void ArcCustomNotificationView::OnPaint(gfx::Canvas* canvas) {
355 views::NativeViewHost::OnPaint(canvas);
356
357 // Bail if there is a |surface_| or no item or no snapshot image.
358 if (surface_ || !item_ || item_->snapshot().isNull())
359 return;
360 const gfx::Rect contents_bounds = GetContentsBounds();
361 canvas->DrawImageInt(item_->snapshot(), 0, 0, item_->snapshot().width(),
362 item_->snapshot().height(), contents_bounds.x(),
363 contents_bounds.y(), contents_bounds.width(),
364 contents_bounds.height(), false);
365 }
366
303 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) { 367 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) {
304 // Forward to parent CustomNotificationView to handle keyboard dismissal. 368 // Forward to parent CustomNotificationView to handle keyboard dismissal.
305 parent()->OnKeyEvent(event); 369 parent()->OnKeyEvent(event);
306 } 370 }
307 371
308 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) { 372 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) {
309 // Forward to parent CustomNotificationView to handle sliding out. 373 // Forward to parent CustomNotificationView to handle sliding out.
310 parent()->OnGestureEvent(event); 374 parent()->OnGestureEvent(event);
311 slide_helper_->Update(); 375 slide_helper_->Update();
312 } 376 }
(...skipping 18 matching lines...) Expand all
331 const gfx::Rect& old_bounds, 395 const gfx::Rect& old_bounds,
332 const gfx::Rect& new_bounds) { 396 const gfx::Rect& new_bounds) {
333 if (in_layout_) 397 if (in_layout_)
334 return; 398 return;
335 399
336 UpdatePreferredSize(); 400 UpdatePreferredSize();
337 Layout(); 401 Layout();
338 } 402 }
339 403
340 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) { 404 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) {
341 window->RemoveObserver(this); 405 SetSurface(nullptr);
342 } 406 }
343 407
344 void ArcCustomNotificationView::OnItemDestroying() { 408 void ArcCustomNotificationView::OnItemDestroying() {
345 item_->RemoveObserver(this); 409 item_->RemoveObserver(this);
346 item_ = nullptr; 410 item_ = nullptr;
347 411
348 // Reset |surface_| with |item_| since no one is observing the |surface_| 412 // Reset |surface_| with |item_| since no one is observing the |surface_|
349 // after |item_| is gone and this view should be removed soon. 413 // after |item_| is gone and this view should be removed soon.
350 SetSurface(nullptr); 414 SetSurface(nullptr);
351 } 415 }
352 416
353 void ArcCustomNotificationView::OnItemPinnedChanged() { 417 void ArcCustomNotificationView::OnItemUpdated() {
354 if (item_->pinned() && floating_close_button_widget_) { 418 UpdatePinnedState();
355 floating_close_button_widget_.reset(); 419 UpdateSnapshot();
356 } else if (!item_->pinned() && !floating_close_button_widget_) {
357 CreateFloatingCloseButton();
358 }
359 } 420 }
360 421
361 void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() { 422 void ArcCustomNotificationView::OnNotificationSurfaceAdded(
423 exo::NotificationSurface* surface) {
424 if (surface->notification_id() != notification_key_)
425 return;
426
427 SetSurface(surface);
428 }
429
430 void ArcCustomNotificationView::OnNotificationSurfaceRemoved(
431 exo::NotificationSurface* surface) {
432 if (surface->notification_id() != notification_key_)
433 return;
434
362 SetSurface(nullptr); 435 SetSurface(nullptr);
363 } 436 }
364 437
365 } // namespace arc 438 } // namespace arc
OLDNEW
« no previous file with comments | « ui/arc/notification/arc_custom_notification_view.h ('k') | ui/arc/notification/arc_notification_item.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698