summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/system/tray/hover_highlight_view.cc36
-rw-r--r--ash/system/tray/hover_highlight_view.h4
-rw-r--r--ash/system/tray/system_tray_bubble.cc68
-rw-r--r--ash/system/tray/system_tray_unittest.cc73
-rw-r--r--ash/system/tray/tray_details_view_unittest.cc85
-rw-r--r--ash/system/tray/tray_popup_item_container.cc88
-rw-r--r--ash/system/tray/tray_popup_item_container.h51
8 files changed, 324 insertions, 83 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 4c232b6..6aa2dd2 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -427,6 +427,8 @@
'system/tray/tray_notification_view.h',
'system/tray/tray_popup_header_button.cc',
'system/tray/tray_popup_header_button.h',
+ 'system/tray/tray_popup_item_container.cc',
+ 'system/tray/tray_popup_item_container.h',
'system/tray/tray_popup_label_button.cc',
'system/tray/tray_popup_label_button.h',
'system/tray/tray_popup_label_button_border.cc',
diff --git a/ash/system/tray/hover_highlight_view.cc b/ash/system/tray/hover_highlight_view.cc
index be2efc2..d81f5a6 100644
--- a/ash/system/tray/hover_highlight_view.cc
+++ b/ash/system/tray/hover_highlight_view.cc
@@ -9,6 +9,7 @@
#include "ash/system/tray/view_click_listener.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
#include "ui/resources/grit/ui_resources.h"
@@ -130,6 +131,19 @@ void HoverHighlightView::SetExpandable(bool expandable) {
}
}
+void HoverHighlightView::SetHoverHighlight(bool hover) {
+ if (hover_ == hover)
+ return;
+ hover_ = hover;
+ if (!text_label_)
+ return;
+ if (hover_ && text_highlight_color_)
+ text_label_->SetEnabledColor(text_highlight_color_);
+ if (!hover_ && text_default_color_)
+ text_label_->SetEnabledColor(text_default_color_);
+ SchedulePaint();
+}
+
bool HoverHighlightView::PerformAction(const ui::Event& event) {
if (!listener_)
return false;
@@ -159,17 +173,23 @@ int HoverHighlightView::GetHeightForWidth(int width) const {
}
void HoverHighlightView::OnMouseEntered(const ui::MouseEvent& event) {
- hover_ = true;
- if (text_highlight_color_ && text_label_)
- text_label_->SetEnabledColor(text_highlight_color_);
- SchedulePaint();
+ SetHoverHighlight(true);
}
void HoverHighlightView::OnMouseExited(const ui::MouseEvent& event) {
- hover_ = false;
- if (text_default_color_ && text_label_)
- text_label_->SetEnabledColor(text_default_color_);
- SchedulePaint();
+ SetHoverHighlight(false);
+}
+
+void HoverHighlightView::OnGestureEvent(ui::GestureEvent* event) {
+ if (switches::IsTouchFeedbackEnabled()) {
+ if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
+ SetHoverHighlight(true);
+ } else if (event->type() == ui::ET_GESTURE_TAP_CANCEL ||
+ event->type() == ui::ET_GESTURE_TAP) {
+ SetHoverHighlight(false);
+ }
+ }
+ ActionableView::OnGestureEvent(event);
}
void HoverHighlightView::OnEnabledChanged() {
diff --git a/ash/system/tray/hover_highlight_view.h b/ash/system/tray/hover_highlight_view.h
index 6df822f..ffd83a2 100644
--- a/ash/system/tray/hover_highlight_view.h
+++ b/ash/system/tray/hover_highlight_view.h
@@ -64,6 +64,9 @@ class HoverHighlightView : public ActionableView {
virtual void GetAccessibleState(ui::AXViewState* state) override;
private:
+ // Sets the highlighted color on a text label if |hover| is set.
+ void SetHoverHighlight(bool hover);
+
// Overridden from ActionableView:
virtual bool PerformAction(const ui::Event& event) override;
@@ -72,6 +75,7 @@ class HoverHighlightView : public ActionableView {
virtual int GetHeightForWidth(int width) const override;
virtual void OnMouseEntered(const ui::MouseEvent& event) override;
virtual void OnMouseExited(const ui::MouseEvent& event) override;
+ virtual void OnGestureEvent(ui::GestureEvent* event) override;
virtual void OnEnabledChanged() override;
virtual void OnPaintBackground(gfx::Canvas* canvas) override;
virtual void OnFocus() override;
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc
index 97500df..96e19c2 100644
--- a/ash/system/tray/system_tray_bubble.cc
+++ b/ash/system/tray/system_tray_bubble.cc
@@ -10,6 +10,7 @@
#include "ash/system/tray/system_tray_item.h"
#include "ash/system/tray/tray_bubble_wrapper.h"
#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_popup_item_container.h"
#include "base/message_loop/message_loop.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
@@ -37,73 +38,6 @@ const int kDetailedBubbleMaxHeight = kTrayPopupItemHeight * 5;
// detailed view or vice versa.
const int kSwipeDelayMS = 150;
-// A view with some special behaviour for tray items in the popup:
-// - optionally changes background color on hover.
-class TrayPopupItemContainer : public views::View {
- public:
- TrayPopupItemContainer(views::View* view,
- bool change_background,
- bool draw_border)
- : hover_(false),
- change_background_(change_background) {
- set_notify_enter_exit_on_child(true);
- if (draw_border) {
- SetBorder(
- views::Border::CreateSolidSidedBorder(0, 0, 1, 0, kBorderLightColor));
- }
- views::BoxLayout* layout = new views::BoxLayout(
- views::BoxLayout::kVertical, 0, 0, 0);
- layout->SetDefaultFlex(1);
- SetLayoutManager(layout);
- SetPaintToLayer(view->layer() != NULL);
- if (view->layer())
- SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely());
- AddChildView(view);
- SetVisible(view->visible());
- }
-
- virtual ~TrayPopupItemContainer() {}
-
- private:
- // Overridden from views::View.
- virtual void ChildVisibilityChanged(View* child) override {
- if (visible() == child->visible())
- return;
- SetVisible(child->visible());
- PreferredSizeChanged();
- }
-
- virtual void ChildPreferredSizeChanged(View* child) override {
- PreferredSizeChanged();
- }
-
- virtual void OnMouseEntered(const ui::MouseEvent& event) override {
- hover_ = true;
- SchedulePaint();
- }
-
- virtual void OnMouseExited(const ui::MouseEvent& event) override {
- hover_ = false;
- SchedulePaint();
- }
-
- virtual void OnPaintBackground(gfx::Canvas* canvas) override {
- if (child_count() == 0)
- return;
-
- views::View* view = child_at(0);
- if (!view->background()) {
- canvas->FillRect(gfx::Rect(size()), (hover_ && change_background_) ?
- kHoverBackgroundColor : kBackgroundColor);
- }
- }
-
- bool hover_;
- bool change_background_;
-
- DISALLOW_COPY_AND_ASSIGN(TrayPopupItemContainer);
-};
-
// Implicit animation observer that deletes itself and the layer at the end of
// the animation.
class AnimationObserverDeleteLayer : public ui::ImplicitAnimationObserver {
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index f06b648..4cfe64b 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -12,16 +12,21 @@
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
+#include "ash/system/tray/system_tray_bubble.h"
#include "ash/system/tray/system_tray_item.h"
#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_popup_item_container.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_util.h"
+#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/window.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/events/test/event_generator.h"
+#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
@@ -157,7 +162,20 @@ class ModalWidgetDelegate : public views::WidgetDelegateView {
} // namespace
-typedef AshTestBase SystemTrayTest;
+class SystemTrayTest : public AshTestBase {
+ public:
+ SystemTrayTest() {}
+ virtual ~SystemTrayTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableTouchFeedback);
+ test::AshTestBase::SetUp();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SystemTrayTest);
+};
TEST_F(SystemTrayTest, SystemTrayDefaultView) {
SystemTray* tray = GetSystemTray();
@@ -505,5 +523,58 @@ TEST_F(SystemTrayTest, SetVisibleDuringHideAnimation) {
EXPECT_EQ(1.0f, tray->layer()->GetTargetOpacity());
}
+#if defined(OS_CHROMEOS)
+// Tests that touch on an item in the system bubble triggers it to become
+// active.
+TEST_F(SystemTrayTest, TrayPopupItemContainerTouchFeedback) {
+ SystemTray* tray = GetSystemTray();
+ tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+
+ TrayPopupItemContainer* view =
+ static_cast<TrayPopupItemContainer*>(tray->GetSystemBubble()->
+ bubble_view()->child_at(0));
+ EXPECT_FALSE(view->active());
+
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+ generator.set_current_location(view->GetBoundsInScreen().CenterPoint());
+ generator.PressTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(view->active());
+
+ generator.ReleaseTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->active());
+}
+
+// Tests that touch events on an item in the system bubble cause it to stop
+// being active.
+TEST_F(SystemTrayTest, TrayPopupItemContainerTouchFeedbackCancellation) {
+ SystemTray* tray = GetSystemTray();
+ tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+
+ TrayPopupItemContainer* view =
+ static_cast<TrayPopupItemContainer*>(tray->GetSystemBubble()->
+ bubble_view()->child_at(0));
+ EXPECT_FALSE(view->active());
+
+ gfx::Rect view_bounds = view->GetBoundsInScreen();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+ generator.set_current_location(view_bounds.CenterPoint());
+ generator.PressTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(view->active());
+
+ gfx::Point move_point(view_bounds.x(), view_bounds.CenterPoint().y());
+ generator.MoveTouch(move_point);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->active());
+
+ generator.set_current_location(move_point);
+ generator.ReleaseTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->active());
+}
+#endif // OS_CHROMEOS
+
} // namespace test
} // namespace ash
diff --git a/ash/system/tray/tray_details_view_unittest.cc b/ash/system/tray/tray_details_view_unittest.cc
index 32c859a..3430c76 100644
--- a/ash/system/tray/tray_details_view_unittest.cc
+++ b/ash/system/tray/tray_details_view_unittest.cc
@@ -8,14 +8,19 @@
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
+#include "ash/system/tray/hover_highlight_view.h"
+#include "ash/system/tray/special_popup_row.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_item.h"
#include "ash/system/tray/tray_details_view.h"
#include "ash/system/tray/view_click_listener.h"
#include "ash/test/ash_test_base.h"
+#include "base/command_line.h"
#include "base/run_loop.h"
#include "grit/ash_strings.h"
#include "ui/aura/window.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/events/test/event_generator.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
@@ -31,14 +36,15 @@ SystemTray* GetSystemTray() {
class TestDetailsView : public TrayDetailsView, public ViewClickListener {
public:
- explicit TestDetailsView(SystemTrayItem* owner) : TrayDetailsView(owner) {}
-
- virtual ~TestDetailsView() {}
-
- void CreateFooterAndFocus() {
+ explicit TestDetailsView(SystemTrayItem* owner) : TrayDetailsView(owner) {
// Uses bluetooth label for testing purpose. It can be changed to any
// string_id.
CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this);
+ }
+
+ virtual ~TestDetailsView() {}
+
+ void FocusFooter() {
footer()->content()->RequestFocus();
}
@@ -92,7 +98,33 @@ class TestItem : public SystemTrayItem {
} // namespace
-typedef AshTestBase TrayDetailsViewTest;
+class TrayDetailsViewTest : public AshTestBase {
+ public:
+ TrayDetailsViewTest() {}
+ virtual ~TrayDetailsViewTest() {}
+
+ HoverHighlightView* CreateAndShowHoverHighlightView() {
+ SystemTray* tray = GetSystemTray();
+ TestItem* test_item = new TestItem;
+ tray->AddTrayItem(test_item);
+ tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+ RunAllPendingInMessageLoop();
+ tray->ShowDetailedView(test_item, 0, true, BUBBLE_USE_EXISTING);
+ RunAllPendingInMessageLoop();
+
+ return static_cast<HoverHighlightView*>(test_item->detailed_view()->
+ footer()->content());
+ }
+
+ virtual void SetUp() OVERRIDE {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableTouchFeedback);
+ test::AshTestBase::SetUp();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TrayDetailsViewTest);
+};
TEST_F(TrayDetailsViewTest, TransitionToDefaultViewTest) {
SystemTray* tray = GetSystemTray();
@@ -119,7 +151,7 @@ TEST_F(TrayDetailsViewTest, TransitionToDefaultViewTest) {
// Transition back to default view, the default view of item 2 should have
// focus.
- test_item_2->detailed_view()->CreateFooterAndFocus();
+ test_item_2->detailed_view()->FocusFooter();
test_item_2->detailed_view()->TransitionToDefaultView();
RunAllPendingInMessageLoop();
@@ -143,5 +175,44 @@ TEST_F(TrayDetailsViewTest, TransitionToDefaultViewTest) {
EXPECT_FALSE(test_item_2->default_view()->HasFocus());
}
+// Tests that HoverHighlightView enters hover state in response to touch.
+TEST_F(TrayDetailsViewTest, HoverHighlightViewTouchFeedback) {
+ HoverHighlightView* view = CreateAndShowHoverHighlightView();
+ EXPECT_FALSE(view->hover());
+
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+ generator.set_current_location(view->GetBoundsInScreen().CenterPoint());
+ generator.PressTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(view->hover());
+
+ generator.ReleaseTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->hover());
+}
+
+// Tests that touch events leaving HoverHighlightView cancel the hover state.
+TEST_F(TrayDetailsViewTest, HoverHighlightViewTouchFeedbackCancellation) {
+ HoverHighlightView* view = CreateAndShowHoverHighlightView();
+ EXPECT_FALSE(view->hover());
+
+ gfx::Rect view_bounds = view->GetBoundsInScreen();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+ generator.set_current_location(view_bounds.CenterPoint());
+ generator.PressTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(view->hover());
+
+ gfx::Point move_point(view_bounds.x(), view_bounds.CenterPoint().y());
+ generator.MoveTouch(move_point);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->hover());
+
+ generator.set_current_location(move_point);
+ generator.ReleaseTouch();
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(view->hover());
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/system/tray/tray_popup_item_container.cc b/ash/system/tray/tray_popup_item_container.cc
new file mode 100644
index 0000000..9a21399
--- /dev/null
+++ b/ash/system/tray/tray_popup_item_container.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/tray/tray_popup_item_container.h"
+
+#include "ash/system/tray/tray_constants.h"
+#include "base/command_line.h"
+#include "ui/base/ui_base_switches_util.h"
+#include "ui/gfx/canvas.h"
+#include "ui/views/border.h"
+#include "ui/views/layout/box_layout.h"
+
+namespace ash {
+
+TrayPopupItemContainer::TrayPopupItemContainer(views::View* view,
+ bool change_background,
+ bool draw_border)
+ : active_(false),
+ change_background_(change_background) {
+ set_notify_enter_exit_on_child(true);
+ if (draw_border) {
+ SetBorder(
+ views::Border::CreateSolidSidedBorder(0, 0, 1, 0, kBorderLightColor));
+ }
+ views::BoxLayout* layout = new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, 0, 0);
+ layout->SetDefaultFlex(1);
+ SetLayoutManager(layout);
+ SetPaintToLayer(view->layer() != NULL);
+ if (view->layer())
+ SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely());
+ AddChildView(view);
+ SetVisible(view->visible());
+}
+
+TrayPopupItemContainer::~TrayPopupItemContainer() {
+}
+
+void TrayPopupItemContainer::SetActive(bool active) {
+ if (!change_background_ || active_ == active)
+ return;
+ active_ = active;
+ SchedulePaint();
+}
+
+void TrayPopupItemContainer::ChildVisibilityChanged(View* child) {
+ if (visible() == child->visible())
+ return;
+ SetVisible(child->visible());
+ PreferredSizeChanged();
+}
+
+void TrayPopupItemContainer::ChildPreferredSizeChanged(View* child) {
+ PreferredSizeChanged();
+}
+
+void TrayPopupItemContainer::OnMouseEntered(const ui::MouseEvent& event) {
+ SetActive(true);
+}
+
+void TrayPopupItemContainer::OnMouseExited(const ui::MouseEvent& event) {
+ SetActive(false);
+}
+
+void TrayPopupItemContainer::OnGestureEvent(ui::GestureEvent* event) {
+ if (!switches::IsTouchFeedbackEnabled())
+ return;
+ if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
+ SetActive(true);
+ } else if (event->type() == ui::ET_GESTURE_TAP_CANCEL ||
+ event->type() == ui::ET_GESTURE_TAP) {
+ SetActive(false);
+ }
+}
+
+void TrayPopupItemContainer::OnPaintBackground(gfx::Canvas* canvas) {
+ if (child_count() == 0)
+ return;
+
+ views::View* view = child_at(0);
+ if (!view->background()) {
+ canvas->FillRect(gfx::Rect(size()), (active_) ? kHoverBackgroundColor
+ : kBackgroundColor);
+ }
+}
+
+} // namespace ash
diff --git a/ash/system/tray/tray_popup_item_container.h b/ash/system/tray/tray_popup_item_container.h
new file mode 100644
index 0000000..8992b21
--- /dev/null
+++ b/ash/system/tray/tray_popup_item_container.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_
+#define ASH_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_
+
+#include "ui/views/view.h"
+
+namespace ash {
+
+// A view which can optionally change the background color when a mouse is
+// hovering or a user is interacting via touch.
+class TrayPopupItemContainer : public views::View {
+ public:
+ TrayPopupItemContainer(views::View* view,
+ bool change_background,
+ bool draw_border);
+
+ virtual ~TrayPopupItemContainer();
+
+ bool active() {
+ return active_;
+ }
+
+ private:
+ // Sets whether the active background is to be used, and triggers a paint.
+ void SetActive(bool active);
+
+ // views::View:
+ virtual void ChildVisibilityChanged(views::View* child) override;
+ virtual void ChildPreferredSizeChanged(views::View* child) override;
+ virtual void OnMouseEntered(const ui::MouseEvent& event) override;
+ virtual void OnMouseExited(const ui::MouseEvent& event) override;
+ virtual void OnGestureEvent(ui::GestureEvent* event) override;
+ virtual void OnPaintBackground(gfx::Canvas* canvas) override;
+
+ // True if either a mouse is hovering over this view, or if a user has touched
+ // down.
+ bool active_;
+
+ // True if mouse hover and touch feedback can alter the background color of
+ // the container.
+ bool change_background_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrayPopupItemContainer);
+};
+
+} // namespace ash
+
+#endif // ASH_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_