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

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: Update comment. Created 4 years, 4 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
« no previous file with comments | « ash/shelf/shelf_tooltip_manager.h ('k') | ash/shelf/shelf_tooltip_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 kTooltipAppearanceDelay = 1000; // msec
31
32 // Tooltip layout constants.
33
34 // Shelf item tooltip height.
35 const int kTooltipHeight = 24;
36
37 // The maximum width of the tooltip bubble. Borrowed the value from
38 // ash/tooltip/tooltip_controller.cc
39 const int kTooltipMaxWidth = 250;
40
41 // Shelf item tooltip internal text margins.
42 const int kTooltipTopBottomMargin = 4;
43 const int kTooltipLeftRightMargin = 8;
44
45 // The offset for the tooltip bubble - making sure that the bubble is spaced
46 // with a fixed gap. The gap is accounted for by the transparent arrow in the
47 // bubble and an additional 1px padding for the shelf item views.
48 const int kArrowTopBottomOffset = 1;
49 const int kArrowLeftRightOffset = 1;
50
51 // Tooltip's border interior thickness that defines its minimum height.
52 const int kBorderInteriorThickness = kTooltipHeight / 2;
53
54 } // namespace
55
56 // The implementation of tooltip of the launcher.
57 class ShelfTooltipManager::ShelfTooltipBubble
58 : public views::BubbleDialogDelegateView {
59 public:
60 ShelfTooltipBubble(views::View* anchor,
61 views::BubbleBorder::Arrow arrow,
62 const base::string16& text)
63 : views::BubbleDialogDelegateView(anchor, arrow) {
64 gfx::Insets insets(kArrowTopBottomOffset, kArrowLeftRightOffset);
65 // Adjust the anchor location for asymmetrical borders of shelf item.
66 if (anchor->border())
67 insets += anchor->border()->GetInsets();
68
69 set_anchor_view_insets(insets);
70 set_close_on_deactivate(false);
71 set_can_activate(false);
72 set_accept_events(false);
73 set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
74 set_shadow(views::BubbleBorder::NO_ASSETS);
75 SetLayoutManager(new views::FillLayout());
76 // The anchor may not have the widget in tests.
77 if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) {
78 set_parent_window(ash::Shell::GetContainer(
79 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
80 ash::kShellWindowId_SettingBubbleContainer));
81 }
82 views::Label* label = new views::Label(text);
83 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
84 ui::NativeTheme* theme = anchor->GetWidget()->GetNativeTheme();
85 label->SetEnabledColor(
86 theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipText));
87 SkColor background_color =
88 theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipBackground);
89 set_color(background_color);
90 label->SetBackgroundColor(background_color);
91 AddChildView(label);
92 views::BubbleDialogDelegateView::CreateBubble(this);
93 // The bubble border has its own background so the background created by the
94 // BubbleDialogDelegateView is redundant and would cause extra opacity.
95 set_background(nullptr);
96 SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT);
97 SetBorderInteriorThickness(kBorderInteriorThickness);
98 }
99
100 private:
101 // BubbleDialogDelegateView overrides:
102 gfx::Size GetPreferredSize() const override {
103 const gfx::Size size = BubbleDialogDelegateView::GetPreferredSize();
104 const int kTooltipMinHeight = kTooltipHeight - 2 * kTooltipTopBottomMargin;
105 return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
106 std::max(size.height(), kTooltipMinHeight));
107 }
108
109 int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; }
110
111 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble);
112 };
113
114 ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view)
115 : timer_delay_(kTooltipAppearanceDelay),
116 shelf_view_(shelf_view),
117 root_window_(nullptr),
118 shelf_layout_manager_(nullptr),
119 bubble_(nullptr),
120 weak_factory_(this) {}
121
122 ShelfTooltipManager::~ShelfTooltipManager() {
123 WillDeleteShelfLayoutManager();
124
125 Shell::GetInstance()->RemovePointerWatcher(this);
126
127 if (root_window_) {
128 root_window_->RemoveObserver(this);
129 root_window_->RemovePreTargetHandler(this);
130 root_window_ = nullptr;
131 }
132 }
133
134 void ShelfTooltipManager::Init() {
135 shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager();
136 shelf_layout_manager_->AddObserver(this);
137
138 root_window_ = shelf_view_->GetWidget()->GetNativeWindow()->GetRootWindow();
139 root_window_->AddPreTargetHandler(this);
140 root_window_->AddObserver(this);
141
142 Shell::GetInstance()->AddPointerWatcher(this);
143 }
144
145 void ShelfTooltipManager::Close() {
146 timer_.Stop();
147 if (bubble_)
148 bubble_->GetWidget()->Close();
149 bubble_ = nullptr;
150 }
151
152 bool ShelfTooltipManager::IsVisible() const {
153 return bubble_ && bubble_->GetWidget()->IsVisible();
154 }
155
156 views::View* ShelfTooltipManager::GetCurrentAnchorView() const {
157 return bubble_ ? bubble_->GetAnchorView() : nullptr;
158 }
159
160 void ShelfTooltipManager::ShowTooltip(views::View* view) {
161 timer_.Stop();
162 if (bubble_) {
163 // Cancel the hiding animation to hide the old bubble immediately.
164 gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
165 ::wm::SetWindowVisibilityAnimationTransition(native_view,
166 ::wm::ANIMATE_NONE);
167 Close();
168 }
169
170 if (!ShouldShowTooltipForView(view))
171 return;
172
173 Shelf* shelf = shelf_view_->shelf();
174 views::BubbleBorder::Arrow arrow = shelf->SelectValueForShelfAlignment(
175 views::BubbleBorder::BOTTOM_CENTER, views::BubbleBorder::LEFT_CENTER,
176 views::BubbleBorder::RIGHT_CENTER);
177
178 base::string16 text = shelf_view_->GetTitleForView(view);
179 bubble_ = new ShelfTooltipBubble(view, arrow, text);
180 gfx::NativeView native_view = bubble_->GetWidget()->GetNativeView();
181 ::wm::SetWindowVisibilityAnimationType(
182 native_view, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
183 ::wm::SetWindowVisibilityAnimationTransition(native_view, ::wm::ANIMATE_HIDE);
184 bubble_->GetWidget()->Show();
185 }
186
187 void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) {
188 if (ShouldShowTooltipForView(view)) {
189 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_),
190 base::Bind(&ShelfTooltipManager::ShowTooltip,
191 weak_factory_.GetWeakPtr(), view));
192 }
193 }
194
195 void ShelfTooltipManager::OnMousePressed(const ui::MouseEvent& event,
196 const gfx::Point& location_in_screen,
197 views::Widget* target) {
198 // Close on any mouse press events inside or outside the tooltip.
199 Close();
200 }
201
202 void ShelfTooltipManager::OnTouchPressed(const ui::TouchEvent& event,
203 const gfx::Point& location_in_screen,
204 views::Widget* target) {
205 // Close on any touch press events inside or outside the tooltip.
206 Close();
207 }
208
209 void ShelfTooltipManager::OnEvent(ui::Event* event) {
210 // Mouse and touch press events are handled via views::PointerWatcher.
211 if (event->type() == ui::ET_MOUSE_PRESSED ||
212 event->type() == ui::ET_TOUCH_PRESSED) {
213 return;
214 }
215
216 if (event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent() ||
217 event->target() != shelf_view_->GetWidget()->GetNativeWindow()) {
218 if (!event->IsKeyEvent())
219 Close();
220 return;
221 }
222
223 gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location();
224 aura::Window::ConvertPointToTarget(
225 static_cast<aura::Window*>(event->target()),
226 shelf_view_->GetWidget()->GetNativeWindow(), &point);
227 views::View::ConvertPointFromWidget(shelf_view_, &point);
228 views::View* view = shelf_view_->GetTooltipHandlerForPoint(point);
229 const bool should_show = ShouldShowTooltipForView(view);
230
231 timer_.Stop();
232 if (IsVisible() && should_show && bubble_->GetAnchorView() != view)
233 ShowTooltip(view);
234 else if (!IsVisible() && should_show && event->type() == ui::ET_MOUSE_MOVED)
235 ShowTooltipWithDelay(view);
236 else if (IsVisible() && shelf_view_->ShouldHideTooltip(point))
237 Close();
238 }
239
240 void ShelfTooltipManager::OnWindowDestroying(aura::Window* window) {
241 if (window == root_window_) {
242 root_window_->RemoveObserver(this);
243 root_window_->RemovePreTargetHandler(this);
244 root_window_ = nullptr;
245 }
246 }
247
248 void ShelfTooltipManager::WillDeleteShelfLayoutManager() {
249 if (shelf_layout_manager_)
250 shelf_layout_manager_->RemoveObserver(this);
251 shelf_layout_manager_ = nullptr;
252 shelf_view_ = nullptr;
253 }
254
255 void ShelfTooltipManager::WillChangeVisibilityState(
256 ShelfVisibilityState new_state) {
257 if (new_state == SHELF_HIDDEN)
258 Close();
259 }
260
261 void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
262 if (new_state == SHELF_AUTO_HIDE_HIDDEN) {
263 timer_.Stop();
264 // AutoHide state change happens during an event filter, so immediate close
265 // may cause a crash in the HandleMouseEvent() after the filter. So we just
266 // schedule the Close here.
267 base::ThreadTaskRunnerHandle::Get()->PostTask(
268 FROM_HERE,
269 base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
270 }
271 }
272
273 bool ShelfTooltipManager::ShouldShowTooltipForView(views::View* view) {
274 return shelf_view_ && shelf_view_->ShouldShowTooltipForView(view) &&
275 shelf_layout_manager_ && shelf_layout_manager_->IsVisible();
276 }
277
278 } // namespace ash
OLDNEW
« no previous file with comments | « ash/shelf/shelf_tooltip_manager.h ('k') | ash/shelf/shelf_tooltip_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698