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

Unified 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: for #3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/arc/notification/arc_custom_notification_view.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/arc/notification/arc_custom_notification_view.cc
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc
index 95a6c88e8e2021542f38ac3a36a8507e94a01974..7c171d135e83284eb7e9c0fb9552c9c629cf99d3 100644
--- a/ui/arc/notification/arc_custom_notification_view.cc
+++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -9,6 +9,10 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/display/screen.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/transform.h"
#include "ui/message_center/message_center_style.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
@@ -16,23 +20,105 @@
#include "ui/views/border.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/widget.h"
+#include "ui/wm/core/window_util.h"
namespace arc {
+class ArcCustomNotificationView::EventForwarder : public ui::EventHandler {
+ public:
+ explicit EventForwarder(ArcCustomNotificationView* owner) : owner_(owner) {}
+ ~EventForwarder() override = default;
+
+ private:
+ // ui::EventHandler
+ void OnEvent(ui::Event* event) override { owner_->OnEvent(event); }
+
+ ArcCustomNotificationView* const owner_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventForwarder);
+};
+
+class ArcCustomNotificationView::SlideHelper
+ : public ui::LayerAnimationObserver {
+ public:
+ explicit SlideHelper(ArcCustomNotificationView* owner) : owner_(owner) {
+ owner_->parent()->layer()->GetAnimator()->AddObserver(this);
+
+ // Reset opacity to 1 to handle to case when the surface is sliding before
+ // getting managed by this class, e.g. sliding in a popup before showing
+ // in a message center view.
+ if (owner_->surface_ && owner_->surface_->window())
+ owner_->surface_->window()->layer()->SetOpacity(1.0f);
+ }
+ ~SlideHelper() override {
+ owner_->parent()->layer()->GetAnimator()->RemoveObserver(this);
+ }
+
+ void Update() {
+ const bool has_animation =
+ owner_->parent()->layer()->GetAnimator()->is_animating();
+ const bool has_transform = !owner_->parent()->GetTransform().IsIdentity();
+ const bool sliding = has_transform || has_animation;
+ if (sliding_ == sliding)
+ return;
+
+ sliding_ = sliding;
+
+ if (sliding_)
+ OnSlideStart();
+ else
+ OnSlideEnd();
+ }
+
+ private:
+ void OnSlideStart() {
+ if (!owner_->surface_ || !owner_->surface_->window())
+ return;
+ surface_copy_ = ::wm::RecreateLayers(owner_->surface_->window(), nullptr);
+ owner_->layer()->Add(surface_copy_->root());
+ owner_->surface_->window()->layer()->SetOpacity(0.0f);
+ }
+
+ void OnSlideEnd() {
+ if (!owner_->surface_ || !owner_->surface_->window())
+ return;
+ owner_->surface_->window()->layer()->SetOpacity(1.0f);
+ owner_->Layout();
+ surface_copy_.reset();
+ }
+
+ // ui::LayerAnimationObserver
+ void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq) override {
+ Update();
+ }
+ void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq) override {
+ Update();
+ }
+ void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {}
+
+ ArcCustomNotificationView* const owner_;
+ bool sliding_ = false;
+ std::unique_ptr<ui::LayerTreeOwner> surface_copy_;
+
+ DISALLOW_COPY_AND_ASSIGN(SlideHelper);
+};
+
ArcCustomNotificationView::ArcCustomNotificationView(
ArcCustomNotificationItem* item,
exo::NotificationSurface* surface)
- : item_(item), surface_(surface) {
+ : item_(item), event_forwarder_(new EventForwarder(this)) {
+ SetSurface(surface);
item_->AddObserver(this);
OnItemPinnedChanged();
- surface_->window()->AddObserver(this);
+
+ // Create a layer as an anchor to insert surface copy during a slide.
+ SetPaintToLayer(true);
}
ArcCustomNotificationView::~ArcCustomNotificationView() {
+ SetSurface(nullptr);
if (item_)
item_->RemoveObserver(this);
- if (surface_ && surface_->window())
- surface_->window()->RemoveObserver(this);
}
void ArcCustomNotificationView::CreateFloatingCloseButton() {
@@ -64,11 +150,27 @@ void ArcCustomNotificationView::CreateFloatingCloseButton() {
floating_close_button_widget_.reset(new views::Widget);
floating_close_button_widget_->Init(params);
floating_close_button_widget_->SetContentsView(floating_close_button_);
- floating_close_button_widget_->Show();
Layout();
}
+void ArcCustomNotificationView::SetSurface(exo::NotificationSurface* surface) {
+ if (surface_ == surface)
+ return;
+
+ if (surface_ && surface_->window()) {
+ surface_->window()->RemoveObserver(this);
+ surface_->window()->RemovePreTargetHandler(event_forwarder_.get());
+ }
+
+ surface_ = surface;
+
+ if (surface_ && surface_->window()) {
+ surface_->window()->AddObserver(this);
+ surface_->window()->AddPreTargetHandler(event_forwarder_.get());
+ }
+}
+
void ArcCustomNotificationView::UpdatePreferredSize() {
gfx::Size preferred_size = surface_->GetSize();
if (preferred_size.width() != message_center::kNotificationWidth) {
@@ -81,10 +183,31 @@ void ArcCustomNotificationView::UpdatePreferredSize() {
SetPreferredSize(preferred_size);
}
+void ArcCustomNotificationView::UpdateCloseButtonVisiblity() {
+ if (!surface_ || !floating_close_button_widget_)
+ return;
+
+ const bool target_visiblity =
+ surface_->window()->GetBoundsInScreen().Contains(
+ display::Screen::GetScreen()->GetCursorScreenPoint());
+ if (target_visiblity == floating_close_button_widget_->IsVisible())
+ return;
+
+ if (target_visiblity)
+ floating_close_button_widget_->Show();
+ else
+ floating_close_button_widget_->Hide();
+}
+
void ArcCustomNotificationView::ViewHierarchyChanged(
const views::View::ViewHierarchyChangedDetails& details) {
views::Widget* widget = GetWidget();
+ if (!details.is_add) {
+ // Resets slide helper when this view is removed from its parent.
+ slide_helper_.reset();
+ }
+
// Bail if native_view() has attached to a different widget.
if (widget && native_view() &&
views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) {
@@ -98,6 +221,9 @@ void ArcCustomNotificationView::ViewHierarchyChanged(
UpdatePreferredSize();
Attach(surface_->window());
+
+ // Creates slide helper after this view is added to its parent.
+ slide_helper_.reset(new SlideHelper(this));
}
void ArcCustomNotificationView::Layout() {
@@ -126,6 +252,27 @@ void ArcCustomNotificationView::Layout() {
close_button_bounds.width());
close_button_bounds.set_y(surface_local_bounds.y());
floating_close_button_widget_->SetBounds(close_button_bounds);
+
+ UpdateCloseButtonVisiblity();
+}
+
+void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) {
+ // Forward to parent CustomNotificationView to handle keyboard dismissal.
+ parent()->OnKeyEvent(event);
+}
+
+void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) {
+ // Forward to parent CustomNotificationView to handle sliding out.
+ parent()->OnGestureEvent(event);
+ slide_helper_->Update();
+}
+
+void ArcCustomNotificationView::OnMouseEntered(const ui::MouseEvent&) {
+ UpdateCloseButtonVisiblity();
+}
+
+void ArcCustomNotificationView::OnMouseExited(const ui::MouseEvent&) {
+ UpdateCloseButtonVisiblity();
}
void ArcCustomNotificationView::ButtonPressed(views::Button* sender,
@@ -135,9 +282,10 @@ void ArcCustomNotificationView::ButtonPressed(views::Button* sender,
}
}
-void ArcCustomNotificationView::OnWindowBoundsChanged(aura::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
+void ArcCustomNotificationView::OnWindowBoundsChanged(
+ aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
UpdatePreferredSize();
}
@@ -151,7 +299,7 @@ void ArcCustomNotificationView::OnItemDestroying() {
// Reset |surface_| with |item_| since no one is observing the |surface_|
// after |item_| is gone and this view should be removed soon.
- surface_ = nullptr;
+ SetSurface(nullptr);
}
void ArcCustomNotificationView::OnItemPinnedChanged() {
@@ -163,7 +311,7 @@ void ArcCustomNotificationView::OnItemPinnedChanged() {
}
void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() {
- surface_ = nullptr;
+ SetSurface(nullptr);
}
} // namespace arc
« 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