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

Side by Side Diff: ash/shelf/shelf_tooltip_manager.cc

Issue 2176813002: mash: Migrate ShelfTooltipManager to wm common types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add limited pre-target handler WmWindow interface; Move tooltip manager to common. Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/shelf/shelf_tooltip_manager.h"
6
7 #include "ash/common/shell_window_ids.h"
8 #include "ash/shelf/shelf.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shelf/shelf_view.h"
11 #include "ash/shell.h"
12 #include "ash/wm/window_animations.h"
13 #include "base/bind.h"
14 #include "base/strings/string16.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "ui/aura/window.h"
18 #include "ui/events/event.h"
19 #include "ui/events/event_constants.h"
20 #include "ui/gfx/geometry/insets.h"
21 #include "ui/views/bubble/bubble_dialog_delegate.h"
22 #include "ui/views/controls/label.h"
23 #include "ui/views/layout/fill_layout.h"
24 #include "ui/views/widget/widget.h"
25 #include "ui/wm/core/window_animations.h"
26
27 namespace ash {
28 namespace {
29
30 const int kTooltipTopBottomMargin = 3;
31 const int kTooltipLeftRightMargin = 10;
32 const int kTooltipAppearanceDelay = 1000; // msec
33 const int kTooltipMinHeight = 29 - 2 * kTooltipTopBottomMargin;
34 const SkColor kTooltipTextColor = SkColorSetRGB(0x22, 0x22, 0x22);
35
36 // The maximum width of the tooltip bubble. Borrowed the value from
37 // ash/tooltip/tooltip_controller.cc
38 const int kTooltipMaxWidth = 250;
39
40 // The offset for the tooltip bubble - making sure that the bubble is flush
41 // with the shelf. The offset includes the arrow size in pixels as well as
42 // the activation bar and other spacing elements.
43 const int kArrowOffsetLeftRight = 11;
44 const int kArrowOffsetTopBottom = 7;
45
46 } // namespace
47
48 // The implementation of tooltip of the launcher.
49 class ShelfTooltipManager::ShelfTooltipBubble
50 : public views::BubbleDialogDelegateView {
51 public:
52 ShelfTooltipBubble(views::View* anchor,
53 views::BubbleBorder::Arrow arrow,
54 const base::string16& text)
55 : views::BubbleDialogDelegateView(anchor, arrow) {
56 gfx::Insets insets =
57 gfx::Insets(kArrowOffsetTopBottom, kArrowOffsetLeftRight);
58 // Adjust the anchor location for asymmetrical borders of shelf item.
59 if (anchor->border())
60 insets += anchor->border()->GetInsets();
61
62 set_anchor_view_insets(insets);
63 set_close_on_deactivate(false);
64 set_can_activate(false);
65 set_accept_events(false);
66 set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
67 set_shadow(views::BubbleBorder::SMALL_SHADOW);
68 SetLayoutManager(new views::FillLayout());
69 // The anchor may not have the widget in tests.
70 if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) {
71 set_parent_window(ash::Shell::GetContainer(
72 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
73 ash::kShellWindowId_SettingBubbleContainer));
74 }
75 views::Label* label = new views::Label(text);
76 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
77 label->SetEnabledColor(kTooltipTextColor);
78 AddChildView(label);
79 views::BubbleDialogDelegateView::CreateBubble(this);
80 }
81
82 private:
83 // BubbleDialogDelegateView overrides:
84 gfx::Size GetPreferredSize() const override {
85 const gfx::Size size = BubbleDialogDelegateView::GetPreferredSize();
86 return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
87 std::max(size.height(), kTooltipMinHeight));
88 }
89
90 int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; }
91
92 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble);
93 };
94
95 ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view)
96 : timer_delay_(kTooltipAppearanceDelay),
97 shelf_view_(shelf_view),
98 root_window_(nullptr),
99 shelf_layout_manager_(nullptr),
100 bubble_(nullptr),
101 weak_factory_(this) {}
102
103 ShelfTooltipManager::~ShelfTooltipManager() {
104 WillDeleteShelfLayoutManager();
105
106 Shell::GetInstance()->RemovePointerWatcher(this);
107
108 if (root_window_) {
109 root_window_->RemoveObserver(this);
110 root_window_->RemovePreTargetHandler(this);
111 root_window_ = nullptr;
112 }
113 }
114
115 void ShelfTooltipManager::Init() {
116 shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager();
117 shelf_layout_manager_->AddObserver(this);
118
119 root_window_ = shelf_view_->GetWidget()->GetNativeWindow()->GetRootWindow();
120 root_window_->AddPreTargetHandler(this);
121 root_window_->AddObserver(this);
122
123 Shell::GetInstance()->AddPointerWatcher(this);
124 }
125
126 void ShelfTooltipManager::Close() {
127 timer_.Stop();
128 if (bubble_)
129 bubble_->GetWidget()->Close();
130 bubble_ = nullptr;
131 }
132
133 bool ShelfTooltipManager::IsVisible() const {
134 return bubble_ && bubble_->GetWidget()->IsVisible();
135 }
136
137 views::View* ShelfTooltipManager::GetCurrentAnchorView() const {
138 return bubble_ ? bubble_->GetAnchorView() : nullptr;
139 }
140
141 void ShelfTooltipManager::ShowTooltip(views::View* view) {
142 timer_.Stop();
143 if (bubble_) {
144 // Cancel the hiding animation to hide the old bubble immediately.
145 gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
146 ::wm::SetWindowVisibilityAnimationTransition(native_view,
147 ::wm::ANIMATE_NONE);
148 Close();
149 }
150
151 if (!ShouldShowTooltipForView(view))
152 return;
153
154 Shelf* shelf = shelf_view_->shelf();
155 views::BubbleBorder::Arrow arrow = shelf->SelectValueForShelfAlignment(
156 views::BubbleBorder::BOTTOM_CENTER, views::BubbleBorder::LEFT_CENTER,
157 views::BubbleBorder::RIGHT_CENTER);
158
159 base::string16 text = shelf_view_->GetTitleForView(view);
160 bubble_ = new ShelfTooltipBubble(view, arrow, text);
161 gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
162 ::wm::SetWindowVisibilityAnimationType(
163 native_view, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
164 ::wm::SetWindowVisibilityAnimationTransition(native_view, ::wm::ANIMATE_HIDE);
165 bubble_->GetWidget()->Show();
166 }
167
168 void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) {
169 if (ShouldShowTooltipForView(view)) {
170 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_),
171 base::Bind(&ShelfTooltipManager::ShowTooltip,
172 weak_factory_.GetWeakPtr(), view));
173 }
174 }
175
176 void ShelfTooltipManager::OnMousePressed(const ui::MouseEvent& event,
177 const gfx::Point& location_in_screen,
178 views::Widget* target) {
179 // Close on any mouse press events inside or outside the tooltip.
180 Close();
181 }
182
183 void ShelfTooltipManager::OnTouchPressed(const ui::TouchEvent& event,
184 const gfx::Point& location_in_screen,
185 views::Widget* target) {
186 // Close on any touch press events inside or outside the tooltip.
187 Close();
188 }
189
190 void ShelfTooltipManager::OnEvent(ui::Event* event) {
191 // Mouse and touch press events are handled via views::PointerWatcher.
192 if (event->type() == ui::ET_MOUSE_PRESSED ||
193 event->type() == ui::ET_TOUCH_PRESSED) {
194 return;
195 }
196
197 if (event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent() ||
198 event->target() != shelf_view_->GetWidget()->GetNativeWindow()) {
199 if (!event->IsKeyEvent())
200 Close();
201 return;
202 }
203
204 gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location();
205 aura::Window::ConvertPointToTarget(
206 static_cast<aura::Window*>(event->target()),
207 shelf_view_->GetWidget()->GetNativeWindow(), &point);
208 views::View::ConvertPointFromWidget(shelf_view_, &point);
209 views::View* view = shelf_view_->GetTooltipHandlerForPoint(point);
210 const bool should_show = ShouldShowTooltipForView(view);
211
212 timer_.Stop();
213 if (IsVisible() && should_show && bubble_->GetAnchorView() != view)
214 ShowTooltip(view);
215 else if (!IsVisible() && should_show && event->type() == ui::ET_MOUSE_MOVED)
216 ShowTooltipWithDelay(view);
217 else if (IsVisible() && shelf_view_->ShouldHideTooltip(point))
218 Close();
219 }
220
221 void ShelfTooltipManager::OnWindowDestroying(aura::Window* window) {
222 if (window == root_window_) {
223 root_window_->RemoveObserver(this);
224 root_window_->RemovePreTargetHandler(this);
225 root_window_ = nullptr;
226 }
227 }
228
229 void ShelfTooltipManager::WillDeleteShelfLayoutManager() {
230 if (shelf_layout_manager_)
231 shelf_layout_manager_->RemoveObserver(this);
232 shelf_layout_manager_ = nullptr;
233 shelf_view_ = nullptr;
234 }
235
236 void ShelfTooltipManager::WillChangeVisibilityState(
237 ShelfVisibilityState new_state) {
238 if (new_state == SHELF_HIDDEN)
239 Close();
240 }
241
242 void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
243 if (new_state == SHELF_AUTO_HIDE_HIDDEN) {
244 timer_.Stop();
245 // AutoHide state change happens during an event filter, so immediate close
246 // may cause a crash in the HandleMouseEvent() after the filter. So we just
247 // schedule the Close here.
248 base::ThreadTaskRunnerHandle::Get()->PostTask(
249 FROM_HERE,
250 base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
251 }
252 }
253
254 bool ShelfTooltipManager::ShouldShowTooltipForView(views::View* view) {
255 return shelf_view_ && shelf_view_->ShouldShowTooltipForView(view) &&
256 shelf_layout_manager_ && shelf_layout_manager_->IsVisible();
257 }
258
259 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698