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

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

Issue 2221073002: arc: Custom notification improvements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix style Created 4 years, 4 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/arc/notification/arc_custom_notification_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "components/exo/notification_surface.h" 7 #include "components/exo/notification_surface.h"
8 #include "components/exo/surface.h" 8 #include "components/exo/surface.h"
9 #include "third_party/skia/include/core/SkColor.h" 9 #include "third_party/skia/include/core/SkColor.h"
10 #include "ui/base/l10n/l10n_util.h" 10 #include "ui/base/l10n/l10n_util.h"
11 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/layer_animation_observer.h"
13 #include "ui/display/screen.h"
14 #include "ui/events/event_handler.h"
15 #include "ui/gfx/transform.h"
12 #include "ui/message_center/message_center_style.h" 16 #include "ui/message_center/message_center_style.h"
13 #include "ui/resources/grit/ui_resources.h" 17 #include "ui/resources/grit/ui_resources.h"
14 #include "ui/strings/grit/ui_strings.h" 18 #include "ui/strings/grit/ui_strings.h"
15 #include "ui/views/background.h" 19 #include "ui/views/background.h"
16 #include "ui/views/border.h" 20 #include "ui/views/border.h"
17 #include "ui/views/controls/button/image_button.h" 21 #include "ui/views/controls/button/image_button.h"
18 #include "ui/views/widget/widget.h" 22 #include "ui/views/widget/widget.h"
23 #include "ui/wm/core/window_util.h"
19 24
20 namespace arc { 25 namespace arc {
21 26
27 class ArcCustomNotificationView::EventForwarder : public ui::EventHandler {
28 public:
29 explicit EventForwarder(ArcCustomNotificationView* owner) : owner_(owner) {}
30 ~EventForwarder() override = default;
31
32 private:
33 // ui::EventHandler
34 void OnKeyEvent(ui::KeyEvent* event) override { owner_->OnKeyEvent(event); }
35 void OnMouseEvent(ui::MouseEvent* event) override {
36 owner_->OnMouseEvent(event);
37 }
38 void OnGestureEvent(ui::GestureEvent* event) override {
39 owner_->OnGestureEvent(event);
40 }
41
42 ArcCustomNotificationView* const owner_;
43
44 DISALLOW_COPY_AND_ASSIGN(EventForwarder);
45 };
46
47 class ArcCustomNotificationView::SlideHelper
48 : public ui::LayerAnimationObserver {
49 public:
50 SlideHelper(ArcCustomNotificationView* owner) : owner_(owner) {
51 owner_->parent()->layer()->GetAnimator()->AddObserver(this);
52
53 // Reset opacity to 1 to handle to case when the surface is sliding before
54 // getting managed by this class, e.g. sliding in a popup before showing
55 // in a message center view.
56 owner_->surface_->window()->layer()->SetOpacity(1.0f);
yoshiki 2016/08/09 16:01:57 Shouldn't we check if owner_->surface_->window() !
xiyuan 2016/08/09 16:08:09 Done.
57 }
58 ~SlideHelper() override {
59 owner_->parent()->layer()->GetAnimator()->RemoveObserver(this);
60 }
61
62 void Update() {
63 const bool has_animation =
64 owner_->parent()->layer()->GetAnimator()->is_animating();
65 const bool has_transform = !owner_->parent()->GetTransform().IsIdentity();
66 const bool sliding = has_transform || has_animation;
67 if (sliding_ == sliding)
68 return;
69
70 sliding_ = sliding;
71
72 if (sliding_)
73 OnSlideStart();
74 else
75 OnSlideEnd();
76 }
77
78 private:
79 void OnSlideStart() {
80 if (!owner_->surface_ || !owner_->surface_->window())
81 return;
82 surface_copy_ = ::wm::RecreateLayers(owner_->surface_->window(), nullptr);
83 owner_->layer()->Add(surface_copy_->root());
84 owner_->surface_->window()->layer()->SetOpacity(0.0f);
85 }
86
87 void OnSlideEnd() {
88 if (!owner_->surface_ || !owner_->surface_->window())
89 return;
90 owner_->surface_->window()->layer()->SetOpacity(1.0f);
91 owner_->Layout();
92 surface_copy_.reset();
yoshiki 2016/08/09 16:01:57 Shouldn't we remove |surface_copy_| from owner_->l
xiyuan 2016/08/09 16:08:09 This is okay because Layer removes itself from its
yoshiki 2016/08/09 16:15:01 Acknowledged.
93 }
94
95 // ui::LayerAnimationObserver
96 void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq) override {
97 Update();
98 }
99 void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq) override {
100 Update();
101 }
102 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {}
103
104 ArcCustomNotificationView* const owner_;
105 bool sliding_ = false;
106 std::unique_ptr<ui::LayerTreeOwner> surface_copy_;
107
108 DISALLOW_COPY_AND_ASSIGN(SlideHelper);
109 };
110
22 ArcCustomNotificationView::ArcCustomNotificationView( 111 ArcCustomNotificationView::ArcCustomNotificationView(
23 ArcCustomNotificationItem* item, 112 ArcCustomNotificationItem* item,
24 exo::NotificationSurface* surface) 113 exo::NotificationSurface* surface)
25 : item_(item), surface_(surface) { 114 : item_(item), event_forwarder_(new EventForwarder(this)) {
115 SetSurface(surface);
26 item_->AddObserver(this); 116 item_->AddObserver(this);
27 OnItemPinnedChanged(); 117 OnItemPinnedChanged();
28 surface_->window()->AddObserver(this); 118
119 // Create a layer as an anchor to insert surface copy during a slide.
120 SetPaintToLayer(true);
29 } 121 }
30 122
31 ArcCustomNotificationView::~ArcCustomNotificationView() { 123 ArcCustomNotificationView::~ArcCustomNotificationView() {
124 SetSurface(nullptr);
32 if (item_) 125 if (item_)
33 item_->RemoveObserver(this); 126 item_->RemoveObserver(this);
34 if (surface_ && surface_->window())
35 surface_->window()->RemoveObserver(this);
36 } 127 }
37 128
38 void ArcCustomNotificationView::CreateFloatingCloseButton() { 129 void ArcCustomNotificationView::CreateFloatingCloseButton() {
39 floating_close_button_ = new views::ImageButton(this); 130 floating_close_button_ = new views::ImageButton(this);
40 floating_close_button_->set_background( 131 floating_close_button_->set_background(
41 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); 132 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT));
42 floating_close_button_->SetBorder( 133 floating_close_button_->SetBorder(
43 views::Border::CreateEmptyBorder(5, 5, 5, 5)); 134 views::Border::CreateEmptyBorder(5, 5, 5, 5));
44 135
45 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 136 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
(...skipping 11 matching lines...) Expand all
57 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); 148 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME));
58 149
59 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); 150 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
60 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 151 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
61 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 152 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
62 params.parent = surface_->window(); 153 params.parent = surface_->window();
63 154
64 floating_close_button_widget_.reset(new views::Widget); 155 floating_close_button_widget_.reset(new views::Widget);
65 floating_close_button_widget_->Init(params); 156 floating_close_button_widget_->Init(params);
66 floating_close_button_widget_->SetContentsView(floating_close_button_); 157 floating_close_button_widget_->SetContentsView(floating_close_button_);
67 floating_close_button_widget_->Show();
68 158
69 Layout(); 159 Layout();
70 } 160 }
71 161
162 void ArcCustomNotificationView::SetSurface(exo::NotificationSurface* surface) {
163 if (surface_ == surface)
164 return;
165
166 if (surface_ && surface_->window()) {
167 surface_->window()->RemoveObserver(this);
168 surface_->window()->RemovePreTargetHandler(event_forwarder_.get());
169 }
170
171 surface_ = surface;
172
173 if (surface_ && surface_->window()) {
174 surface_->window()->AddObserver(this);
175 surface_->window()->AddPreTargetHandler(event_forwarder_.get());
176 }
177 }
178
72 void ArcCustomNotificationView::UpdatePreferredSize() { 179 void ArcCustomNotificationView::UpdatePreferredSize() {
73 gfx::Size preferred_size = surface_->GetSize(); 180 gfx::Size preferred_size = surface_->GetSize();
74 if (preferred_size.width() != message_center::kNotificationWidth) { 181 if (preferred_size.width() != message_center::kNotificationWidth) {
75 const float scale = static_cast<float>(message_center::kNotificationWidth) / 182 const float scale = static_cast<float>(message_center::kNotificationWidth) /
76 preferred_size.width(); 183 preferred_size.width();
77 preferred_size.SetSize(message_center::kNotificationWidth, 184 preferred_size.SetSize(message_center::kNotificationWidth,
78 preferred_size.height() * scale); 185 preferred_size.height() * scale);
79 } 186 }
80 187
81 SetPreferredSize(preferred_size); 188 SetPreferredSize(preferred_size);
82 } 189 }
83 190
191 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() {
192 if (!surface_ || !floating_close_button_widget_)
193 return;
194
195 const bool target_visiblity =
196 surface_->window()->GetBoundsInScreen().Contains(
197 display::Screen::GetScreen()->GetCursorScreenPoint());
198 if (target_visiblity == floating_close_button_widget_->IsVisible())
199 return;
200
201 if (target_visiblity)
202 floating_close_button_widget_->Show();
203 else
204 floating_close_button_widget_->Hide();
205 }
206
84 void ArcCustomNotificationView::ViewHierarchyChanged( 207 void ArcCustomNotificationView::ViewHierarchyChanged(
85 const views::View::ViewHierarchyChangedDetails& details) { 208 const views::View::ViewHierarchyChangedDetails& details) {
86 views::Widget* widget = GetWidget(); 209 views::Widget* widget = GetWidget();
87 210
211 if (!details.is_add) {
212 // Resets slide helper when this view is removed from its parent.
213 slide_helper_.reset();
214 }
215
88 // Bail if native_view() has attached to a different widget. 216 // Bail if native_view() has attached to a different widget.
89 if (widget && native_view() && 217 if (widget && native_view() &&
90 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { 218 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) {
91 return; 219 return;
92 } 220 }
93 221
94 views::NativeViewHost::ViewHierarchyChanged(details); 222 views::NativeViewHost::ViewHierarchyChanged(details);
95 223
96 if (!widget || !surface_ || !details.is_add) 224 if (!widget || !surface_ || !details.is_add)
97 return; 225 return;
98 226
99 UpdatePreferredSize(); 227 UpdatePreferredSize();
100 Attach(surface_->window()); 228 Attach(surface_->window());
229
230 // Creates slide helper after this view is added to its parent.
231 slide_helper_.reset(new SlideHelper(this));
101 } 232 }
102 233
103 void ArcCustomNotificationView::Layout() { 234 void ArcCustomNotificationView::Layout() {
104 views::NativeViewHost::Layout(); 235 views::NativeViewHost::Layout();
105 236
106 if (!surface_ || !GetWidget()) 237 if (!surface_ || !GetWidget())
107 return; 238 return;
108 239
109 // Scale notification surface if necessary. 240 // Scale notification surface if necessary.
110 gfx::Transform transform; 241 gfx::Transform transform;
111 const gfx::Size surface_size = surface_->GetSize(); 242 const gfx::Size surface_size = surface_->GetSize();
112 const gfx::Size contents_size = GetContentsBounds().size(); 243 const gfx::Size contents_size = GetContentsBounds().size();
113 if (!surface_size.IsEmpty() && !contents_size.IsEmpty()) { 244 if (!surface_size.IsEmpty() && !contents_size.IsEmpty()) {
114 transform.Scale( 245 transform.Scale(
115 static_cast<float>(contents_size.width()) / surface_size.width(), 246 static_cast<float>(contents_size.width()) / surface_size.width(),
116 static_cast<float>(contents_size.height()) / surface_size.height()); 247 static_cast<float>(contents_size.height()) / surface_size.height());
117 } 248 }
118 surface_->window()->SetTransform(transform); 249 surface_->window()->SetTransform(transform);
119 250
120 if (!floating_close_button_widget_) 251 if (!floating_close_button_widget_)
121 return; 252 return;
122 253
123 gfx::Rect surface_local_bounds(surface_->GetSize()); 254 gfx::Rect surface_local_bounds(surface_->GetSize());
124 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize()); 255 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize());
125 close_button_bounds.set_x(surface_local_bounds.right() - 256 close_button_bounds.set_x(surface_local_bounds.right() -
126 close_button_bounds.width()); 257 close_button_bounds.width());
127 close_button_bounds.set_y(surface_local_bounds.y()); 258 close_button_bounds.set_y(surface_local_bounds.y());
128 floating_close_button_widget_->SetBounds(close_button_bounds); 259 floating_close_button_widget_->SetBounds(close_button_bounds);
260
261 UpdateCloseButtonVisiblity();
262 }
263
264 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) {
265 // Forward to parent CustomNotificationView to handle keyboard dismissal.
266 parent()->OnKeyEvent(event);
267 }
268
269 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) {
270 // Forward to parent CustomNotificationView to handle sliding out.
271 parent()->OnGestureEvent(event);
272 slide_helper_->Update();
273 }
274
275 void ArcCustomNotificationView::OnMouseEntered(const ui::MouseEvent&) {
276 UpdateCloseButtonVisiblity();
277 }
278
279 void ArcCustomNotificationView::OnMouseExited(const ui::MouseEvent&) {
280 UpdateCloseButtonVisiblity();
129 } 281 }
130 282
131 void ArcCustomNotificationView::ButtonPressed(views::Button* sender, 283 void ArcCustomNotificationView::ButtonPressed(views::Button* sender,
132 const ui::Event& event) { 284 const ui::Event& event) {
133 if (item_ && !item_->pinned() && sender == floating_close_button_) { 285 if (item_ && !item_->pinned() && sender == floating_close_button_) {
134 item_->CloseFromCloseButton(); 286 item_->CloseFromCloseButton();
135 } 287 }
136 } 288 }
137 289
138 void ArcCustomNotificationView::OnWindowBoundsChanged(aura::Window* window, 290 void ArcCustomNotificationView::OnWindowBoundsChanged(
139 const gfx::Rect& old_bounds, 291 aura::Window* window,
140 const gfx::Rect& new_bounds) { 292 const gfx::Rect& old_bounds,
293 const gfx::Rect& new_bounds) {
141 UpdatePreferredSize(); 294 UpdatePreferredSize();
142 } 295 }
143 296
144 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) { 297 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) {
145 window->RemoveObserver(this); 298 window->RemoveObserver(this);
146 } 299 }
147 300
148 void ArcCustomNotificationView::OnItemDestroying() { 301 void ArcCustomNotificationView::OnItemDestroying() {
149 item_->RemoveObserver(this); 302 item_->RemoveObserver(this);
150 item_ = nullptr; 303 item_ = nullptr;
151 304
152 // Reset |surface_| with |item_| since no one is observing the |surface_| 305 // Reset |surface_| with |item_| since no one is observing the |surface_|
153 // after |item_| is gone and this view should be removed soon. 306 // after |item_| is gone and this view should be removed soon.
154 surface_ = nullptr; 307 SetSurface(nullptr);
155 } 308 }
156 309
157 void ArcCustomNotificationView::OnItemPinnedChanged() { 310 void ArcCustomNotificationView::OnItemPinnedChanged() {
158 if (item_->pinned() && floating_close_button_widget_) { 311 if (item_->pinned() && floating_close_button_widget_) {
159 floating_close_button_widget_.reset(); 312 floating_close_button_widget_.reset();
160 } else if (!item_->pinned() && !floating_close_button_widget_) { 313 } else if (!item_->pinned() && !floating_close_button_widget_) {
161 CreateFloatingCloseButton(); 314 CreateFloatingCloseButton();
162 } 315 }
163 } 316 }
164 317
165 void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() { 318 void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() {
166 surface_ = nullptr; 319 SetSurface(nullptr);
167 } 320 }
168 321
169 } // namespace arc 322 } // namespace arc
OLDNEW
« no previous file with comments | « ui/arc/notification/arc_custom_notification_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698