14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/shelf/shelf_tooltip_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/shelf/shelf_view.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_animations.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/insets.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_frame_view.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTooltipTopBottomMargin = 3; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTooltipLeftRightMargin = 10; 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int kTooltipAppearanceDelay = 1000; // msec 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTooltipMinHeight = 29 - 2 * kTooltipTopBottomMargin; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kTooltipTextColor = SkColorSetRGB(0x22, 0x22, 0x22); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The maximum width of the tooltip bubble. Borrowed the value from 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ash/tooltip/tooltip_controller.cc 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTooltipMaxWidth = 250; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The offset for the tooltip bubble - making sure that the bubble is flush 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with the shelf. The offset includes the arrow size in pixels as well as 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the activation bar and other spacing elements. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kArrowOffsetLeftRight = 11; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kArrowOffsetTopBottom = 7; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The implementation of tooltip of the launcher. 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ShelfTooltipManager::ShelfTooltipBubble 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::BubbleDelegateView { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShelfTooltipBubble(views::View* anchor, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::BubbleBorder::Arrow arrow, 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShelfTooltipManager* host); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetText(const base::string16& text); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Close(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::WidgetDelegate overrides: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WindowClosing() OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::View overrides: 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShelfTooltipManager* host_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* label_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ShelfTooltipManager::ShelfTooltipBubble::ShelfTooltipBubble( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* anchor, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::BubbleBorder::Arrow arrow, 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ShelfTooltipManager* host) 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : views::BubbleDelegateView(anchor, arrow), host_(host) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kArrowOffsetLeftRight, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kArrowOffsetTopBottom, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kArrowOffsetLeftRight); 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Shelf items can have an asymmetrical border for spacing reasons. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adjust anchor location for this. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (anchor->border()) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insets += anchor->border()->GetInsets(); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) set_anchor_view_insets(insets); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_close_on_esc(false); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_close_on_deactivate(false); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_use_focusless(true); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_accept_events(false); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTooltipTopBottomMargin, kTooltipLeftRightMargin)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_shadow(views::BubbleBorder::SMALL_SHADOW); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetLayoutManager(new views::FillLayout()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The anchor may not have the widget in tests. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (anchor->GetWidget() && anchor->GetWidget()->GetNativeView()) { 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window = 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor->GetWidget()->GetNativeView()->GetRootWindow(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_parent_window(ash::Shell::GetInstance()->GetContainer( 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_window, ash::kShellWindowId_SettingBubbleContainer)); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_ = new views::Label; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetEnabledColor(kTooltipTextColor); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(label_); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::BubbleDelegateView::CreateBubble(this); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShelfTooltipBubble::SetText( 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& text) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetText(text); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeToContents(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShelfTooltipBubble::Close() { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWidget()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_ = NULL; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->Close(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShelfTooltipBubble::WindowClosing() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::BubbleDelegateView::WindowClosing(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->OnBubbleClosed(this); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ShelfTooltipManager::ShelfTooltipBubble::GetPreferredSize() const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pref_size = views::BubbleDelegateView::GetPreferredSize(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pref_size.height() < kTooltipMinHeight) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_size.set_height(kTooltipMinHeight); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pref_size.width() > kTooltipMaxWidth) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_size.set_width(kTooltipMaxWidth); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pref_size; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ShelfTooltipManager::ShelfTooltipManager( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShelfLayoutManager* shelf_layout_manager, 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ShelfView* shelf_view) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : view_(NULL), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_(NULL), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_(NULL), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shelf_layout_manager_(shelf_layout_manager), 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) shelf_view_(shelf_view), 144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch weak_factory_(this) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shelf_layout_manager) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shelf_layout_manager->AddObserver(this); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Shell::HasInstance()) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->AddPreTargetHandler(this); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ShelfTooltipManager::~ShelfTooltipManager() { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelHidingAnimation(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shelf_layout_manager_) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shelf_layout_manager_->RemoveObserver(this); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Shell::HasInstance()) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->RemovePreTargetHandler(this); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShowDelayed(views::View* anchor, 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::string16& text) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timer_.get() && timer_->IsRunning()) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelHidingAnimation(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible()) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBubble(anchor, text); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShowImmediately(views::View* anchor, 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::string16& text) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timer_.get() && timer_->IsRunning()) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTimer(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelHidingAnimation(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible()) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBubble(anchor, text); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowInternal(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::Close() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTimer(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->Close(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_ = NULL; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_ = NULL; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnBubbleClosed(views::BubbleDelegateView* view) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view == view_) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_ = NULL; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_ = NULL; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::UpdateArrow() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelHidingAnimation(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowImmediately(anchor_, text_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ResetTimer() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timer_.get() && timer_->IsRunning()) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_->Reset(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't start the timer if the shelf isn't visible. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shelf_layout_manager_ && !shelf_layout_manager_->IsVisible()) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CreateTimer(kTooltipAppearanceDelay); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::StopTimer() { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.reset(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool ShelfTooltipManager::IsVisible() { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timer_.get() && timer_->IsRunning()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget_ && widget_->IsVisible(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::CreateZeroDelayTimerForTest() { 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CreateTimer(0); 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnMouseEvent(ui::MouseEvent* event) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(event); 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(event->target()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!widget_ || !widget_->IsVisible()) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(view_); 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(shelf_view_); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Pressing the mouse button anywhere should close the tooltip. 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (event->type() == ui::ET_MOUSE_PRESSED) { 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CloseSoon(); 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event->target()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget_->GetNativeWindow()->GetRootWindow() != target->GetRootWindow()) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSoon(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Point location_in_shelf_view = event->location(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window::ConvertPointToTarget( 2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) target, shelf_view_->GetWidget()->GetNativeWindow(), 2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &location_in_shelf_view); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (shelf_view_->ShouldHideTooltip(location_in_shelf_view)) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because this mouse event may arrive to |view_|, here we just schedule 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the closing event rather than directly calling Close(). 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSoon(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnTouchEvent(ui::TouchEvent* event) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event->target()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget_ && widget_->IsVisible() && widget_->GetNativeWindow() != target) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnGestureEvent(ui::GestureEvent* event) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget_ && widget_->IsVisible()) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because this mouse event may arrive to |view_|, here we just schedule 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the closing event rather than directly calling Close(). 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSoon(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnCancelMode(ui::CancelModeEvent* event) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::WillDeleteShelf() { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shelf_layout_manager_ = NULL; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::WillChangeVisibilityState( 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShelfVisibilityState new_state) { 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_state == SHELF_HIDDEN) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTimer(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_state == SHELF_AUTO_HIDE_HIDDEN) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTimer(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AutoHide state change happens during an event filter, so immediate close 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may cause a crash in the HandleMouseEvent() after the filter. So we just 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // schedule the Close here. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSoon(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::CancelHidingAnimation() { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!widget_ || !widget_->GetNativeView()) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeView native_view = widget_->GetNativeView(); 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::SetWindowVisibilityAnimationTransition( 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) native_view, wm::ANIMATE_NONE); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::CloseSoon() { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI::current()->PostTask( 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr())); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::ShowInternal() { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view_->GetWidget()->Show(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.reset(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::CreateBubble(views::View* anchor, 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::string16& text) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!view_); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_ = anchor; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_ = text; 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::BubbleBorder::Arrow arrow = 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shelf_layout_manager_->SelectValueForShelfAlignment( 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::BOTTOM_CENTER, 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::LEFT_CENTER, 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::RIGHT_CENTER, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::TOP_CENTER); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) view_ = new ShelfTooltipBubble(anchor, arrow, this); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_ = view_->GetWidget(); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_->SetText(text_); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeView native_view = widget_->GetNativeView(); 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::SetWindowVisibilityAnimationType( 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::SetWindowVisibilityAnimationTransition( 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) native_view, wm::ANIMATE_HIDE); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ShelfTooltipManager::CreateTimer(int delay_in_ms) { 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::OneShotTimer<ShelfTooltipManager>* new_timer = 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new base::OneShotTimer<ShelfTooltipManager>(); 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_timer->Start(FROM_HERE, 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta::FromMilliseconds(delay_in_ms), 3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this, 3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &ShelfTooltipManager::ShowInternal); 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) timer_.reset(new_timer); 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 376