Commit 1a51c144 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Add contextual nudge for home to overview gesture

BUG=1008963

Change-Id: I1f40729b3338c12360be783c300bca3ac5c7d7d4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2069438
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Reviewed-by: default avatarYulun Wu <yulunwu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744814}
parent 8f008470
......@@ -608,6 +608,8 @@ component("ash") {
"shelf/home_button.h",
"shelf/home_button_controller.cc",
"shelf/home_button_controller.h",
"shelf/home_to_overview_nudge_controller.cc",
"shelf/home_to_overview_nudge_controller.h",
"shelf/hotseat_transition_animator.cc",
"shelf/hotseat_transition_animator.h",
"shelf/hotseat_widget.cc",
......@@ -1872,6 +1874,7 @@ test("ash_unittests") {
"shelf/back_button_unittest.cc",
"shelf/contextual_tooltip_unittest.cc",
"shelf/home_button_unittest.cc",
"shelf/home_to_overview_nudge_controller_unittest.cc",
"shelf/hotseat_widget_unittest.cc",
"shelf/login_shelf_view_unittest.cc",
"shelf/scrollable_shelf_view_unittest.cc",
......
......@@ -503,6 +503,9 @@ This file contains the strings for ash.
<message name="IDS_ASH_DRAG_HANDLE_NUDGE" desc="The text shown to users above the drag handle when the device is in tablet mode and showing the in-app shelf. Instructs them that they can transition to home screen by swiping up from the shelf.">
Swipe up to go home
</message>
<message name="IDS_ASH_HOME_TO_OVERVIEW_CONTEXTUAL_NUDGE" desc="Text shown to the user below shelf on the home screen in tablet mode, instructing them that they can transition to overview UI by swiping up from the shelf and holding.">
Swipe up and hold to see open apps
</message>
<message name="IDS_ASH_FULLSCREEN_MAGNIFIER_SHORTCUT_DISABLED"
desc="The label used in the notification used to indicate that, the shortcut for full-screen magnifier feature has been disabled.">
the full-screen magnifier
......
bdce7dec724db1b0c24110cfadbdfe831f9d0ed8
\ No newline at end of file
......@@ -24,12 +24,24 @@ constexpr int kTooltipHeight = 18;
// ash/tooltip/tooltip_controller.cc
constexpr int kTooltipMaxWidth = 250;
views::BubbleBorder::Arrow GetArrowForPosition(
ContextualNudge::Position position) {
switch (position) {
case ContextualNudge::Position::kTop:
return views::BubbleBorder::BOTTOM_CENTER;
case ContextualNudge::Position::kBottom:
return views::BubbleBorder::TOP_CENTER;
}
}
} // namespace
ContextualNudge::ContextualNudge(views::View* anchor,
const base::string16& text)
aura::Window* parent_window,
const base::string16& text,
Position position)
: views::BubbleDialogDelegateView(anchor,
views::BubbleBorder::BOTTOM_CENTER,
GetArrowForPosition(position),
views::BubbleBorder::NO_ASSETS) {
set_color(SK_ColorTRANSPARENT);
set_margins(gfx::Insets(0, 0));
......@@ -40,9 +52,13 @@ ContextualNudge::ContextualNudge(views::View* anchor,
set_shadow(views::BubbleBorder::NO_ASSETS);
DialogDelegate::set_buttons(ui::DIALOG_BUTTON_NONE);
set_parent_window(
anchor_widget()->GetNativeWindow()->GetRootWindow()->GetChildById(
kShellWindowId_ShelfContainer));
if (parent_window) {
set_parent_window(parent_window);
} else if (anchor_widget()) {
set_parent_window(
anchor_widget()->GetNativeWindow()->GetRootWindow()->GetChildById(
kShellWindowId_ShelfContainer));
}
SetLayoutManager(std::make_unique<views::FillLayout>());
......@@ -62,6 +78,10 @@ ContextualNudge::ContextualNudge(views::View* anchor,
ContextualNudge::~ContextualNudge() = default;
void ContextualNudge::UpdateAnchorRect(const gfx::Rect& rect) {
SetAnchorRect(rect);
}
gfx::Size ContextualNudge::CalculatePreferredSize() const {
const gfx::Size size = BubbleDialogDelegateView::CalculatePreferredSize();
return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
......
......@@ -18,7 +18,21 @@ namespace ash {
// The implementation of contextual nudge tooltip bubbles.
class ASH_EXPORT ContextualNudge : public views::BubbleDialogDelegateView {
public:
ContextualNudge(views::View* anchor, const base::string16& text);
// Indicates whether the nudge should be shown below or above the anchor.
enum class Position { kBottom, kTop };
// |anchor| - The view to which the nudge bubble should be anchored. May be
// nullptr, in which case anchor bounds should be provided using
// UpdateAnchorRect().
// |parent_window| - if set, the window that should parent the nudge native
// window. If not set, the shelf container in the anchor view's root
// window will be used.
// |text| - The nudge text.
// |position| - The nudge position relative to the anchor rectangle.
ContextualNudge(views::View* anchor,
aura::Window* parent_window,
const base::string16& text,
Position position);
~ContextualNudge() override;
ContextualNudge(const ContextualNudge&) = delete;
......@@ -26,6 +40,10 @@ class ASH_EXPORT ContextualNudge : public views::BubbleDialogDelegateView {
views::Label* label() { return label_; }
// Sets the nudge bubble anchor rect - should be used to set the anchor rect
// if no valid anchor was passed to the nudge bubble.
void UpdateAnchorRect(const gfx::Rect& rect);
// BubbleDialogDelegateView:
gfx::Size CalculatePreferredSize() const override;
ui::LayerType GetLayerType() const override;
......
......@@ -39,6 +39,8 @@ std::string TooltipTypeToString(TooltipType type) {
return "drag_handle";
case TooltipType::kBackGesture:
return "back_gesture";
case TooltipType::kHomeToOverview:
return "home_to_overview";
}
return "invalid";
}
......
......@@ -18,6 +18,7 @@ namespace contextual_tooltip {
enum class TooltipType {
kDragHandle,
kBackGesture,
kHomeToOverview,
};
// Maximum number of times a user can be shown a contextual nudge if the user
......
......@@ -128,8 +128,10 @@ void DragHandle::OnGestureEvent(ui::GestureEvent* event) {
void DragHandle::ShowDragHandleTooltip() {
DCHECK(!drag_handle_nudge_);
drag_handle_nudge_ = new ContextualNudge(
this, l10n_util::GetStringUTF16(IDS_ASH_DRAG_HANDLE_NUDGE));
drag_handle_nudge_ =
new ContextualNudge(this, nullptr /*parent_window*/,
l10n_util::GetStringUTF16(IDS_ASH_DRAG_HANDLE_NUDGE),
ContextualNudge::Position::kTop);
drag_handle_nudge_->GetWidget()->Show();
drag_handle_nudge_->label()->layer()->SetOpacity(0.0f);
......
This diff is collapsed.
// Copyright 2020 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_SHELF_HOME_TO_OVERVIEW_NUDGE_CONTROLLER_H_
#define ASH_SHELF_HOME_TO_OVERVIEW_NUDGE_CONTROLLER_H_
#include <memory>
#include "ash/ash_export.h"
#include "base/scoped_observer.h"
#include "base/timer/timer.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
namespace ash {
class ContextualNudge;
class HotseatWidget;
class ASH_EXPORT HomeToOverviewNudgeController : views::WidgetObserver {
public:
explicit HomeToOverviewNudgeController(HotseatWidget* hotseat_widget);
HomeToOverviewNudgeController(const HomeToOverviewNudgeController& other) =
delete;
~HomeToOverviewNudgeController() override;
HomeToOverviewNudgeController& operator=(
const HomeToOverviewNudgeController& other) = delete;
// Sets whether the home to overview nudge can be shown for the current shelf
// state. If nudge is allowed, controller may show the nudge (if required). If
// the nudge is not allowed, the nudge will be hidden if currently shown.
void SetNudgeAllowedForCurrentShelf(bool allowed);
// views::WidgetObserver:
void OnWidgetDestroying(views::Widget* widget) override;
void OnWidgetBoundsChanged(views::Widget* widget,
const gfx::Rect& new_bounds) override;
ContextualNudge* nudge_for_testing() { return nudge_; }
bool HasShowTimerForTesting() const;
void FireShowTimerForTesting();
bool HasHideTimerForTesting() const;
void FireHideTimerForTesting();
private:
// Creates and shows the nudge bubble, schedules showing animation for the
// nudge and hotseat widgets, and schedules nudge hide timer as needed.
void ShowNudge();
// Sets up hotseat and nudge wdget animation for hiding the nudge, and closes
// the nudge widget when the animation finishes.
void HideNudge();
// Updates the nudge anchor bounds for the current hotseat and shelf bounds.
void UpdateNudgeAnchorBounds();
bool nudge_allowed_for_shelf_state_ = false;
HotseatWidget* const hotseat_widget_;
ContextualNudge* nudge_ = nullptr;
base::OneShotTimer nudge_show_timer_;
base::OneShotTimer nudge_hide_timer_;
// Observes hotseat widget to detect the hotseat bounds changes, and the
// nudge widget to detect that the widget is being destroyed.
ScopedObserver<views::Widget, views::WidgetObserver> widget_observer_{this};
};
} // namespace ash
#endif // ASH_SHELF_HOME_TO_OVERVIEW_NUDGE_CONTROLLER_H_
This diff is collapsed.
......@@ -27,6 +27,7 @@
#include "ash/screen_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/contextual_tooltip.h"
#include "ash/shelf/home_to_overview_nudge_controller.h"
#include "ash/shelf/hotseat_widget.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_layout_manager_observer.h"
......@@ -591,6 +592,9 @@ void ShelfLayoutManager::UpdateAutoHideForMouseEvent(ui::MouseEvent* event,
}
void ShelfLayoutManager::UpdateContextualNudges() {
if (!ash::features::AreContextualNudgesEnabled())
return;
const bool in_app_shelf = ShelfConfig::Get()->is_in_app();
const bool in_tablet_mode = Shell::Get()->IsInTabletMode();
......@@ -603,10 +607,29 @@ void ShelfLayoutManager::UpdateContextualNudges() {
} else {
shelf_widget_->HideDragHandleNudge();
}
// Create home to overview nudge controller if home to overview nudge is
// allowed by the current shelf state.
const bool allow_home_to_overview_nudge = in_tablet_mode && !in_app_shelf;
if (allow_home_to_overview_nudge && !home_to_overview_nudge_controller_) {
home_to_overview_nudge_controller_ =
std::make_unique<HomeToOverviewNudgeController>(
shelf_->hotseat_widget());
}
if (home_to_overview_nudge_controller_) {
home_to_overview_nudge_controller_->SetNudgeAllowedForCurrentShelf(
allow_home_to_overview_nudge);
}
}
void ShelfLayoutManager::HideContextualNudges() {
if (!ash::features::AreContextualNudgesEnabled())
return;
shelf_widget_->HideDragHandleNudge();
if (home_to_overview_nudge_controller_)
home_to_overview_nudge_controller_->SetNudgeAllowedForCurrentShelf(false);
}
void ShelfLayoutManager::ProcessGestureEventOfAutoHideShelf(
......
......@@ -53,6 +53,7 @@ namespace ash {
enum class AnimationChangeType;
class DragWindowFromShelfController;
class HomeToOverviewNudgeController;
class PanelLayoutManagerTest;
class PresentationTimeRecorder;
class Shelf;
......@@ -286,6 +287,11 @@ class ASH_EXPORT ShelfLayoutManager
return window_drag_controller_.get();
}
HomeToOverviewNudgeController*
home_to_overview_nudge_controller_for_testing() {
return home_to_overview_nudge_controller_.get();
}
bool IsDraggingApplist() const {
return drag_status_ == kDragAppListInProgress;
}
......@@ -627,6 +633,9 @@ class ASH_EXPORT ShelfLayoutManager
// up from shelf to homescreen, overview or splitview.
std::unique_ptr<DragWindowFromShelfController> window_drag_controller_;
std::unique_ptr<HomeToOverviewNudgeController>
home_to_overview_nudge_controller_;
// Whether upward fling from shelf should be handled as potential gesture from
// overview to home. This is set when the swipe would otherwise be handled by
// |window_drag_controller_|, but the swipe cannot be associated with a window
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment