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

Unified Diff: ash/shelf/shelf_tooltip_manager.cc

Issue 1816753002: Enable mash shelf tooltips. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revise tooltip event testing. Created 4 years, 9 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
Index: ash/shelf/shelf_tooltip_manager.cc
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc
index 3252ae1c16a89f7f7c929929d3be1d7588cfdaca..e2f920e8ad2b26313febb5fece2a0c5a4138a6c6 100644
--- a/ash/shelf/shelf_tooltip_manager.cc
+++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -13,14 +13,11 @@
#include "base/bind.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "base/timer/timer.h"
#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
@@ -50,36 +47,24 @@ class ShelfTooltipManager::ShelfTooltipBubble
: public views::BubbleDelegateView {
public:
ShelfTooltipBubble(views::View* anchor,
- views::BubbleBorder::Arrow arrow,
- ShelfTooltipManager* host);
-
- void SetText(const base::string16& text);
- void Close();
+ views::BubbleBorder::Arrow arrow,
+ const base::string16& text);
private:
- // views::WidgetDelegate overrides:
- void WindowClosing() override;
-
// views::View overrides:
gfx::Size GetPreferredSize() const override;
- ShelfTooltipManager* host_;
- views::Label* label_;
-
DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble);
};
ShelfTooltipManager::ShelfTooltipBubble::ShelfTooltipBubble(
views::View* anchor,
views::BubbleBorder::Arrow arrow,
- ShelfTooltipManager* host)
- : views::BubbleDelegateView(anchor, arrow), host_(host) {
+ const base::string16& text)
+ : views::BubbleDelegateView(anchor, arrow) {
gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
- kArrowOffsetLeftRight,
- kArrowOffsetTopBottom,
kArrowOffsetLeftRight);
- // Shelf items can have an asymmetrical border for spacing reasons.
- // Adjust anchor location for this.
+ // Adjust the anchor location for asymmetrical borders of shelf item.
if (anchor->border())
insets += anchor->border()->GetInsets();
@@ -88,286 +73,145 @@ ShelfTooltipManager::ShelfTooltipBubble::ShelfTooltipBubble(
set_close_on_deactivate(false);
set_can_activate(false);
set_accept_events(false);
- set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin,
- kTooltipTopBottomMargin, kTooltipLeftRightMargin));
+ set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
set_shadow(views::BubbleBorder::SMALL_SHADOW);
SetLayoutManager(new views::FillLayout());
// The anchor may not have the widget in tests.
- if (anchor->GetWidget() && anchor->GetWidget()->GetNativeView()) {
- aura::Window* root_window =
- anchor->GetWidget()->GetNativeView()->GetRootWindow();
- set_parent_window(ash::Shell::GetInstance()->GetContainer(
- root_window, ash::kShellWindowId_SettingBubbleContainer));
+ if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) {
+ set_parent_window(ash::Shell::GetContainer(
+ anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
+ ash::kShellWindowId_SettingBubbleContainer));
}
- label_ = new views::Label;
- label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- label_->SetEnabledColor(kTooltipTextColor);
- AddChildView(label_);
+ views::Label* label = new views::Label(text);
+ label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ label->SetEnabledColor(kTooltipTextColor);
+ AddChildView(label);
views::BubbleDelegateView::CreateBubble(this);
-}
-
-void ShelfTooltipManager::ShelfTooltipBubble::SetText(
- const base::string16& text) {
- label_->SetText(text);
SizeToContents();
}
-void ShelfTooltipManager::ShelfTooltipBubble::Close() {
- if (GetWidget()) {
- host_ = NULL;
- GetWidget()->Close();
- }
-}
-
-void ShelfTooltipManager::ShelfTooltipBubble::WindowClosing() {
- views::BubbleDelegateView::WindowClosing();
- if (host_)
- host_->OnBubbleClosed(this);
-}
-
gfx::Size ShelfTooltipManager::ShelfTooltipBubble::GetPreferredSize() const {
- gfx::Size pref_size = views::BubbleDelegateView::GetPreferredSize();
- if (pref_size.height() < kTooltipMinHeight)
- pref_size.set_height(kTooltipMinHeight);
- if (pref_size.width() > kTooltipMaxWidth)
- pref_size.set_width(kTooltipMaxWidth);
- return pref_size;
+ const gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
+ return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
+ std::max(size.height(), kTooltipMinHeight));
}
-ShelfTooltipManager::ShelfTooltipManager(
- ShelfLayoutManager* shelf_layout_manager,
- ShelfView* shelf_view)
- : view_(NULL),
- widget_(NULL),
- anchor_(NULL),
- shelf_layout_manager_(shelf_layout_manager),
+ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view)
+ : timer_delay_(kTooltipAppearanceDelay),
shelf_view_(shelf_view),
- weak_factory_(this) {
- if (shelf_layout_manager)
- shelf_layout_manager->AddObserver(this);
- if (Shell::HasInstance())
- Shell::GetInstance()->AddPreTargetHandler(this);
-}
+ shelf_layout_manager_(nullptr),
+ bubble_(nullptr),
+ weak_factory_(this) {}
-ShelfTooltipManager::~ShelfTooltipManager() {
- CancelHidingAnimation();
- Close();
- if (shelf_layout_manager_)
- shelf_layout_manager_->RemoveObserver(this);
- if (Shell::HasInstance())
- Shell::GetInstance()->RemovePreTargetHandler(this);
-}
-
-void ShelfTooltipManager::ShowDelayed(views::View* anchor,
- const base::string16& text) {
- if (view_) {
- if (timer_.get() && timer_->IsRunning()) {
- return;
- } else {
- CancelHidingAnimation();
- Close();
- }
- }
+ShelfTooltipManager::~ShelfTooltipManager() {}
- if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible())
- return;
-
- CreateBubble(anchor, text);
- ResetTimer();
-}
-
-void ShelfTooltipManager::ShowImmediately(views::View* anchor,
- const base::string16& text) {
- if (view_) {
- if (timer_.get() && timer_->IsRunning())
- StopTimer();
- CancelHidingAnimation();
- Close();
- }
-
- if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible())
- return;
-
- CreateBubble(anchor, text);
- ShowInternal();
+void ShelfTooltipManager::Init() {
+ shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager();
+ shelf_layout_manager_->AddObserver(this);
+ // TODO(msw): Capture events outside the shelf to close tooltips?
+ shelf_view_->GetWidget()->GetNativeWindow()->AddPreTargetHandler(this);
}
void ShelfTooltipManager::Close() {
- StopTimer();
- if (view_) {
- view_->Close();
- view_ = NULL;
- widget_ = NULL;
- }
+ timer_.Stop();
+ if (bubble_)
+ bubble_->GetWidget()->Close();
+ bubble_ = nullptr;
}
-void ShelfTooltipManager::OnBubbleClosed(views::BubbleDelegateView* view) {
- if (view == view_) {
- view_ = NULL;
- widget_ = NULL;
- }
+bool ShelfTooltipManager::IsVisible() const {
+ return bubble_ && bubble_->GetWidget()->IsVisible();
}
-void ShelfTooltipManager::UpdateArrow() {
- if (view_) {
- CancelHidingAnimation();
- Close();
- ShowImmediately(anchor_, text_);
- }
+views::View* ShelfTooltipManager::GetCurrentAnchorView() const {
+ return bubble_ ? bubble_->GetAnchorView() : nullptr;
}
-void ShelfTooltipManager::ResetTimer() {
- if (timer_.get() && timer_->IsRunning()) {
- timer_->Reset();
- return;
+void ShelfTooltipManager::ShowTooltip(views::View* view) {
+ timer_.Stop();
+ if (bubble_) {
+ // Cancel the hiding animation to hide the old bubble immediately.
+ gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
+ wm::SetWindowVisibilityAnimationTransition(native_view, wm::ANIMATE_NONE);
+ Close();
}
- // We don't start the timer if the shelf isn't visible.
if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible())
return;
- CreateTimer(kTooltipAppearanceDelay);
-}
-
-void ShelfTooltipManager::StopTimer() {
- timer_.reset();
-}
-
-bool ShelfTooltipManager::IsVisible() {
- if (timer_.get() && timer_->IsRunning())
- return false;
+ Shelf* shelf = shelf_view_->shelf();
+ views::BubbleBorder::Arrow arrow = shelf->SelectValueForShelfAlignment(
+ views::BubbleBorder::BOTTOM_CENTER, views::BubbleBorder::LEFT_CENTER,
+ views::BubbleBorder::RIGHT_CENTER, views::BubbleBorder::TOP_CENTER);
- return widget_ && widget_->IsVisible();
+ base::string16 text = shelf_view_->GetTitleForView(view);
+ bubble_ = new ShelfTooltipBubble(view, arrow, text);
+ gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
+ wm::SetWindowVisibilityAnimationType(
+ native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
+ wm::SetWindowVisibilityAnimationTransition(native_view, wm::ANIMATE_HIDE);
+ bubble_->GetWidget()->Show();
}
-void ShelfTooltipManager::CreateZeroDelayTimerForTest() {
- CreateTimer(0);
+void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) {
+ if (!shelf_layout_manager_ || shelf_layout_manager_->IsVisible()) {
+ timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_),
+ base::Bind(&ShelfTooltipManager::ShowTooltip,
+ weak_factory_.GetWeakPtr(), view));
+ }
}
-void ShelfTooltipManager::OnMouseEvent(ui::MouseEvent* event) {
- DCHECK(event);
- DCHECK(event->target());
- if (!widget_ || !widget_->IsVisible())
- return;
-
- DCHECK(view_);
- DCHECK(shelf_view_);
-
- // Pressing the mouse button anywhere should close the tooltip.
- if (event->type() == ui::ET_MOUSE_PRESSED) {
- CloseSoon();
+void ShelfTooltipManager::OnEvent(ui::Event* event) {
+ // Close the tooltip on mouse press or exit, and on most non-mouse events.
+ if (event->type() == ui::ET_MOUSE_PRESSED ||
+ event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent()) {
+ if (!event->IsKeyEvent())
sky 2016/03/23 17:53:03 Did you mean !IsMouseEvent here? If not, how come
msw 2016/03/23 18:58:01 This closes for non-mouse and non-kbd events (touc
+ Close();
return;
}
- aura::Window* target = static_cast<aura::Window*>(event->target());
- if (widget_->GetNativeWindow()->GetRootWindow() != target->GetRootWindow()) {
- CloseSoon();
+ gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location();
+ views::View::ConvertPointFromWidget(shelf_view_, &point);
+ if (IsVisible() && shelf_view_->ShouldHideTooltip(point)) {
+ Close();
return;
}
- gfx::Point location_in_shelf_view = event->location();
- aura::Window::ConvertPointToTarget(
- target, shelf_view_->GetWidget()->GetNativeWindow(),
- &location_in_shelf_view);
-
- if (shelf_view_->ShouldHideTooltip(location_in_shelf_view)) {
- // Because this mouse event may arrive to |view_|, here we just schedule
- // the closing event rather than directly calling Close().
- CloseSoon();
- }
-}
-
-void ShelfTooltipManager::OnTouchEvent(ui::TouchEvent* event) {
- aura::Window* target = static_cast<aura::Window*>(event->target());
- if (widget_ && widget_->IsVisible() && widget_->GetNativeWindow() != target)
- Close();
-}
+ views::View* view = shelf_view_->GetTooltipHandlerForPoint(point);
+ const bool should_show = shelf_view_->ShouldShowTooltipForView(view);
+ if (IsVisible() && bubble_->GetAnchorView() != view && should_show)
+ ShowTooltip(view);
-void ShelfTooltipManager::OnGestureEvent(ui::GestureEvent* event) {
- if (widget_ && widget_->IsVisible()) {
- // Because this mouse event may arrive to |view_|, here we just schedule
- // the closing event rather than directly calling Close().
- CloseSoon();
+ if (!IsVisible() && event->type() == ui::ET_MOUSE_MOVED) {
+ timer_.Stop();
+ if (should_show)
+ ShowTooltipWithDelay(view);
}
}
-void ShelfTooltipManager::OnCancelMode(ui::CancelModeEvent* event) {
- Close();
-}
-
void ShelfTooltipManager::WillDeleteShelf() {
sky 2016/03/23 17:53:03 Should this be called from the destructor too? I'm
msw 2016/03/23 18:58:01 Done with some added checks that avoid test crashe
- shelf_layout_manager_ = NULL;
+ if (shelf_layout_manager_)
+ shelf_layout_manager_->RemoveObserver(this);
+ if (shelf_view_->GetWidget()->GetNativeWindow())
+ shelf_view_->GetWidget()->GetNativeWindow()->RemovePreTargetHandler(this);
}
void ShelfTooltipManager::WillChangeVisibilityState(
ShelfVisibilityState new_state) {
- if (new_state == SHELF_HIDDEN) {
- StopTimer();
+ if (new_state == SHELF_HIDDEN)
Close();
- }
}
void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
if (new_state == SHELF_AUTO_HIDE_HIDDEN) {
- StopTimer();
+ timer_.Stop();
// AutoHide state change happens during an event filter, so immediate close
// may cause a crash in the HandleMouseEvent() after the filter. So we just
// schedule the Close here.
- CloseSoon();
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
}
}
-void ShelfTooltipManager::CancelHidingAnimation() {
- if (!widget_ || !widget_->GetNativeView())
- return;
-
- gfx::NativeView native_view = widget_->GetNativeView();
- wm::SetWindowVisibilityAnimationTransition(
- native_view, wm::ANIMATE_NONE);
-}
-
-void ShelfTooltipManager::CloseSoon() {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
-}
-
-void ShelfTooltipManager::ShowInternal() {
- if (view_)
- view_->GetWidget()->Show();
-
- timer_.reset();
-}
-
-void ShelfTooltipManager::CreateBubble(views::View* anchor,
- const base::string16& text) {
- DCHECK(!view_);
-
- anchor_ = anchor;
- text_ = text;
- Shelf* shelf = shelf_layout_manager_->shelf_widget()->shelf();
- views::BubbleBorder::Arrow arrow = shelf->SelectValueForShelfAlignment(
- views::BubbleBorder::BOTTOM_CENTER, views::BubbleBorder::LEFT_CENTER,
- views::BubbleBorder::RIGHT_CENTER, views::BubbleBorder::TOP_CENTER);
-
- view_ = new ShelfTooltipBubble(anchor, arrow, this);
- widget_ = view_->GetWidget();
- view_->SetText(text_);
-
- gfx::NativeView native_view = widget_->GetNativeView();
- wm::SetWindowVisibilityAnimationType(
- native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
- wm::SetWindowVisibilityAnimationTransition(
- native_view, wm::ANIMATE_HIDE);
-}
-
-void ShelfTooltipManager::CreateTimer(int delay_in_ms) {
- base::OneShotTimer* new_timer = new base::OneShotTimer();
- new_timer->Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(delay_in_ms),
- this,
- &ShelfTooltipManager::ShowInternal);
- timer_.reset(new_timer);
-}
-
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698