Commit 623c7e4e authored by mohsen's avatar mohsen Committed by Commit bot

Add ink drop ripple to shelf overflow button

It uses a flood fill ripple that remains active while the overflow shelf
is active. InkDropHostView and CustomButton are updated to handle active
case:
 - CustomButton does not hide the ripple if it is not a pending ripple;
 - InkDropHostView does not show or hide a pending ripple if it is
   showing an active ripple.

BUG=612579
TEST=OverflowButtonInkDropTest.* in ash_unittests, manual

Review-Url: https://codereview.chromium.org/2178163002
Cr-Commit-Position: refs/heads/master@{#419232}
parent 2ad909df
......@@ -5,6 +5,7 @@
#include "ash/common/shelf/overflow_bubble.h"
#include "ash/common/shelf/overflow_bubble_view.h"
#include "ash/common/shelf/overflow_button.h"
#include "ash/common/shelf/shelf_view.h"
#include "ash/common/shelf/wm_shelf.h"
#include "ash/common/system/tray/tray_background_view.h"
......@@ -17,7 +18,7 @@ namespace ash {
OverflowBubble::OverflowBubble(WmShelf* wm_shelf)
: wm_shelf_(wm_shelf),
bubble_(nullptr),
anchor_(nullptr),
overflow_button_(nullptr),
shelf_view_(nullptr) {
WmShell::Get()->AddPointerWatcher(this,
views::PointerWatcherEventTypes::BASIC);
......@@ -28,50 +29,47 @@ OverflowBubble::~OverflowBubble() {
WmShell::Get()->RemovePointerWatcher(this);
}
void OverflowBubble::Show(views::View* anchor, ShelfView* shelf_view) {
DCHECK(anchor);
void OverflowBubble::Show(OverflowButton* overflow_button,
ShelfView* shelf_view) {
DCHECK(overflow_button);
DCHECK(shelf_view);
Hide();
bubble_ = new OverflowBubbleView(wm_shelf_);
bubble_->InitOverflowBubble(anchor, shelf_view);
bubble_->InitOverflowBubble(overflow_button, shelf_view);
shelf_view_ = shelf_view;
anchor_ = anchor;
overflow_button_ = overflow_button;
TrayBackgroundView::InitializeBubbleAnimations(bubble_->GetWidget());
bubble_->GetWidget()->AddObserver(this);
bubble_->GetWidget()->Show();
overflow_button->OnOverflowBubbleShown();
}
void OverflowBubble::Hide() {
if (!IsShowing())
return;
OverflowButton* overflow_button = overflow_button_;
bubble_->GetWidget()->RemoveObserver(this);
bubble_->GetWidget()->Close();
bubble_ = NULL;
anchor_ = NULL;
shelf_view_ = NULL;
}
void OverflowBubble::HideBubbleAndRefreshButton() {
if (!IsShowing())
return;
bubble_ = nullptr;
overflow_button_ = nullptr;
shelf_view_ = nullptr;
views::View* anchor = anchor_;
Hide();
// Update overflow button (|anchor|) status when overflow bubble is hidden
// by outside event of overflow button.
anchor->SchedulePaint();
overflow_button->OnOverflowBubbleHidden();
}
void OverflowBubble::ProcessPressedEvent(
const gfx::Point& event_location_in_screen) {
if (IsShowing() && !shelf_view_->IsShowingMenu() &&
!bubble_->GetBoundsInScreen().Contains(event_location_in_screen) &&
!anchor_->GetBoundsInScreen().Contains(event_location_in_screen)) {
HideBubbleAndRefreshButton();
!overflow_button_->GetBoundsInScreen().Contains(
event_location_in_screen)) {
Hide();
}
}
......@@ -86,9 +84,9 @@ void OverflowBubble::OnPointerEventObserved(
void OverflowBubble::OnWidgetDestroying(views::Widget* widget) {
DCHECK(widget == bubble_->GetWidget());
// Update the overflow button in the parent ShelfView.
anchor_->SchedulePaint();
overflow_button_->SchedulePaint();
bubble_ = nullptr;
anchor_ = nullptr;
overflow_button_ = nullptr;
shelf_view_ = nullptr;
}
......
......@@ -19,6 +19,7 @@ class View;
namespace ash {
class OverflowBubbleView;
class OverflowButton;
class ShelfView;
class WmShelf;
......@@ -31,16 +32,13 @@ class OverflowBubble : public views::PointerWatcher,
explicit OverflowBubble(WmShelf* wm_shelf);
~OverflowBubble() override;
// Shows an bubble pointing to |anchor| with |shelf_view| as its content.
// This |shelf_view| is different than the main shelf's view and only contains
// the overflow items.
void Show(views::View* anchor, ShelfView* shelf_view);
// Shows an bubble pointing to |overflow_button| with |shelf_view| as its
// content. This |shelf_view| is different than the main shelf's view and
// only contains the overflow items.
void Show(OverflowButton* overflow_button, ShelfView* shelf_view);
void Hide();
// Hides the bubble and schedules paint for overflow button.
void HideBubbleAndRefreshButton();
bool IsShowing() const { return !!bubble_; }
ShelfView* shelf_view() { return shelf_view_; }
OverflowBubbleView* bubble_view() { return bubble_; }
......@@ -57,8 +55,8 @@ class OverflowBubble : public views::PointerWatcher,
void OnWidgetDestroying(views::Widget* widget) override;
WmShelf* wm_shelf_;
OverflowBubbleView* bubble_; // Owned by views hierarchy.
views::View* anchor_; // Owned by ShelfView.
OverflowBubbleView* bubble_; // Owned by views hierarchy.
OverflowButton* overflow_button_; // Owned by ShelfView.
// ShelfView containing the overflow items. Owned by |bubble_|.
ShelfView* shelf_view_;
......
......@@ -11,6 +11,7 @@
#include "ash/common/shelf/shelf_view.h"
#include "ash/common/shelf/wm_shelf.h"
#include "ash/common/shelf/wm_shelf_util.h"
#include "base/memory/ptr_util.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "third_party/skia/include/core/SkPaint.h"
......@@ -24,6 +25,7 @@
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/vector_icons_public.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
namespace ash {
......@@ -35,6 +37,10 @@ OverflowButton::OverflowButton(ShelfView* shelf_view, WmShelf* wm_shelf)
background_alpha_(0) {
DCHECK(shelf_view_);
if (MaterialDesignController::IsShelfMaterial()) {
SetInkDropMode(InkDropMode::ON);
set_ink_drop_base_color(kShelfInkDropBaseColor);
set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity);
set_hide_ink_drop_when_showing_context_menu(false);
bottom_image_md_ =
CreateVectorIcon(gfx::VectorIconId::SHELF_OVERFLOW, kShelfIconColor);
bottom_image_ = &bottom_image_md_;
......@@ -53,6 +59,18 @@ void OverflowButton::OnShelfAlignmentChanged() {
SchedulePaint();
}
void OverflowButton::OnOverflowBubbleShown() {
AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr);
if (!ash::MaterialDesignController::IsShelfMaterial())
SchedulePaint();
}
void OverflowButton::OnOverflowBubbleHidden() {
AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr);
if (!ash::MaterialDesignController::IsShelfMaterial())
SchedulePaint();
}
void OverflowButton::SetBackgroundAlpha(int alpha) {
background_alpha_ = alpha;
SchedulePaint();
......@@ -64,6 +82,24 @@ void OverflowButton::OnPaint(gfx::Canvas* canvas) {
PaintForeground(canvas, bounds);
}
std::unique_ptr<views::InkDropRipple> OverflowButton::CreateInkDropRipple()
const {
return base::MakeUnique<views::FloodFillInkDropRipple>(
CalculateButtonBounds(), GetInkDropCenterBasedOnLastEvent(),
GetInkDropBaseColor(), ink_drop_visible_opacity());
}
bool OverflowButton::ShouldEnterPushedState(const ui::Event& event) {
if (shelf_view_->IsShowingOverflowBubble())
return false;
return CustomButton::ShouldEnterPushedState(event);
}
bool OverflowButton::ShouldShowInkDropHighlight() const {
return false;
}
void OverflowButton::NotifyClick(const ui::Event& event) {
CustomButton::NotifyClick(event);
shelf_view_->ButtonPressed(this, event, ink_drop());
......@@ -77,14 +113,6 @@ void OverflowButton::PaintBackground(gfx::Canvas* canvas,
background_paint.setColor(SkColorSetA(kShelfBaseColor, background_alpha_));
canvas->DrawRoundRect(bounds, kOverflowButtonCornerRadius,
background_paint);
if (shelf_view_->IsShowingOverflowBubble()) {
SkPaint highlight_paint;
highlight_paint.setFlags(SkPaint::kAntiAlias_Flag);
highlight_paint.setColor(kShelfButtonActivatedHighlightColor);
canvas->DrawRoundRect(bounds, kOverflowButtonCornerRadius,
highlight_paint);
}
} else {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
const gfx::ImageSkia* background =
......@@ -122,7 +150,7 @@ void OverflowButton::PaintForeground(gfx::Canvas* canvas,
bounds.y() + ((bounds.height() - image->height()) / 2));
}
int OverflowButton::NonMaterialBackgroundImageId() {
int OverflowButton::NonMaterialBackgroundImageId() const {
if (shelf_view_->IsShowingOverflowBubble())
return IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
else if (wm_shelf_->IsDimmed())
......@@ -130,7 +158,7 @@ int OverflowButton::NonMaterialBackgroundImageId() {
return IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
}
gfx::Rect OverflowButton::CalculateButtonBounds() {
gfx::Rect OverflowButton::CalculateButtonBounds() const {
ShelfAlignment alignment = wm_shelf_->GetAlignment();
gfx::Rect bounds(GetContentsBounds());
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
......
......@@ -21,15 +21,18 @@ class OverflowButton : public views::CustomButton {
~OverflowButton() override;
void OnShelfAlignmentChanged();
void OnOverflowBubbleShown();
void OnOverflowBubbleHidden();
// Sets alpha value of the background and schedules a paint.
void SetBackgroundAlpha(int alpha);
private:
// views::View:
void OnPaint(gfx::Canvas* canvas) override;
// views::CustomButton:
void OnPaint(gfx::Canvas* canvas) override;
std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
bool ShouldEnterPushedState(const ui::Event& event) override;
bool ShouldShowInkDropHighlight() const override;
void NotifyClick(const ui::Event& event) override;
// Helper functions to paint the background and foreground of the button
......@@ -41,10 +44,10 @@ class OverflowButton : public views::CustomButton {
// current shelf state.
// TODO(tdanderson): Remove this once the material design shelf is enabled
// by default. See crbug.com/614453.
int NonMaterialBackgroundImageId();
int NonMaterialBackgroundImageId() const;
// Calculates the bounds of the overflow button based on the shelf alignment.
gfx::Rect CalculateButtonBounds();
gfx::Rect CalculateButtonBounds() const;
// Used for bottom shelf alignment. |bottom_image_| points to
// |bottom_image_md_| for material design, otherwise it is points to a
......
......@@ -1854,7 +1854,7 @@ void ShelfView::OnMenuClosed(views::InkDrop* ink_drop) {
// Hide the hide overflow bubble after showing a context menu for its items.
if (owner_overflow_bubble_)
owner_overflow_bubble_->HideBubbleAndRefreshButton();
owner_overflow_bubble_->Hide();
closing_event_time_ = launcher_menu_runner_->closing_event_time();
......
This diff is collapsed.
......@@ -68,8 +68,17 @@ bool ShelfViewTestAPI::IsOverflowButtonVisible() {
}
void ShelfViewTestAPI::ShowOverflowBubble() {
if (!shelf_view_->IsShowingOverflowBubble())
shelf_view_->ToggleOverflowBubble();
DCHECK(!shelf_view_->IsShowingOverflowBubble());
shelf_view_->ToggleOverflowBubble();
}
void ShelfViewTestAPI::HideOverflowBubble() {
DCHECK(shelf_view_->IsShowingOverflowBubble());
shelf_view_->ToggleOverflowBubble();
}
bool ShelfViewTestAPI::IsShowingOverflowBubble() const {
return shelf_view_->IsShowingOverflowBubble();
}
const gfx::Rect& ShelfViewTestAPI::GetBoundsByIndex(int index) {
......@@ -110,6 +119,10 @@ OverflowBubble* ShelfViewTestAPI::overflow_bubble() {
return shelf_view_->overflow_bubble_.get();
}
OverflowButton* ShelfViewTestAPI::overflow_button() const {
return shelf_view_->overflow_button_;
}
ShelfTooltipManager* ShelfViewTestAPI::tooltip_manager() {
return &shelf_view_->tooltip_;
}
......
......@@ -25,6 +25,7 @@ class InkDrop;
namespace ash {
class OverflowBubble;
class OverflowButton;
class ShelfButton;
class ShelfButtonPressedMetricTracker;
class ShelfDelegate;
......@@ -61,6 +62,12 @@ class ShelfViewTestAPI {
// Makes shelf view show its overflow bubble.
void ShowOverflowBubble();
// Makes shelf view hide its overflow bubble.
void HideOverflowBubble();
// Returns true if the overflow bubble is visible.
bool IsShowingOverflowBubble() const;
// Sets animation duration in milliseconds for test.
void SetAnimationDuration(int duration_ms);
......@@ -79,6 +86,9 @@ class ShelfViewTestAPI {
// An accessor for overflow bubble.
OverflowBubble* overflow_bubble();
// An accessor for overflow button.
OverflowButton* overflow_button() const;
// Returns the preferred size of |shelf_view_|.
gfx::Size GetPreferredSize();
......
......@@ -58,6 +58,8 @@ class InkDropHostView::InkDropGestureHandler : public ui::EventHandler {
InkDropState ink_drop_state = InkDropState::HIDDEN;
switch (event->type()) {
case ui::ET_GESTURE_TAP_DOWN:
if (current_ink_drop_state == InkDropState::ACTIVATED)
return;
ink_drop_state = InkDropState::ACTION_PENDING;
// The ui::ET_GESTURE_TAP_DOWN event needs to be marked as handled so
// that
......@@ -65,16 +67,17 @@ class InkDropHostView::InkDropGestureHandler : public ui::EventHandler {
event->SetHandled();
break;
case ui::ET_GESTURE_LONG_PRESS:
if (current_ink_drop_state == InkDropState::ACTIVATED)
return;
ink_drop_state = InkDropState::ALTERNATE_ACTION_PENDING;
break;
case ui::ET_GESTURE_LONG_TAP:
ink_drop_state = InkDropState::ALTERNATE_ACTION_TRIGGERED;
break;
case ui::ET_GESTURE_END:
case ui::ET_GESTURE_SCROLL_BEGIN:
if (current_ink_drop_state == InkDropState::ACTIVATED)
return;
// Fall through to ui::ET_GESTURE_SCROLL_BEGIN case.
case ui::ET_GESTURE_SCROLL_BEGIN:
ink_drop_state = InkDropState::HIDDEN;
break;
default:
......
......@@ -470,8 +470,13 @@ void CustomButton::NotifyClick(const ui::Event& event) {
}
void CustomButton::OnClickCanceled(const ui::Event& event) {
AnimateInkDrop(views::InkDropState::HIDDEN,
ui::LocatedEvent::FromIfValid(&event));
if (ink_drop()->GetTargetInkDropState() ==
views::InkDropState::ACTION_PENDING ||
ink_drop()->GetTargetInkDropState() ==
views::InkDropState::ALTERNATE_ACTION_PENDING) {
AnimateInkDrop(views::InkDropState::HIDDEN,
ui::LocatedEvent::FromIfValid(&event));
}
Button::OnClickCanceled(event);
}
......
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