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

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

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 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 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/common/shelf/shelf_tooltip_manager.h"
6
7 #include "ash/common/shelf/shelf_view.h"
8 #include "ash/common/shelf/wm_shelf.h"
9 #include "ash/common/system/tray/tray_constants.h"
10 #include "ash/common/wm_shell.h"
11 #include "ash/common/wm_window.h"
12 #include "ash/public/cpp/shell_window_ids.h"
13 #include "ash/root_window_controller.h"
14 #include "base/bind.h"
15 #include "base/strings/string16.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h"
18 #include "ui/base/material_design/material_design_controller.h"
19 #include "ui/events/event.h"
20 #include "ui/events/event_constants.h"
21 #include "ui/gfx/geometry/insets.h"
22 #include "ui/views/bubble/bubble_dialog_delegate.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/layout/fill_layout.h"
25 #include "ui/views/widget/widget.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 set_close_on_deactivate(false);
65 set_can_activate(false);
66 set_accept_events(false);
67 set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
68 set_shadow(views::BubbleBorder::NO_ASSETS);
69 SetLayoutManager(new views::FillLayout());
70 views::Label* label = new views::Label(text);
71 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
72 ui::NativeTheme* theme = anchor->GetWidget()->GetNativeTheme();
73 label->SetEnabledColor(
74 theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipText));
75 SkColor background_color =
76 theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipBackground);
77 set_color(background_color);
78 label->SetBackgroundColor(background_color);
79 // The background is not opaque, so we can't do subpixel rendering.
80 label->SetSubpixelRenderingEnabled(false);
81 AddChildView(label);
82
83 gfx::Insets insets(kArrowTopBottomOffset, kArrowLeftRightOffset);
84 // Adjust the anchor location for asymmetrical borders of shelf item.
85 if (anchor->border())
86 insets += anchor->border()->GetInsets();
87 if (ui::MaterialDesignController::IsSecondaryUiMaterial())
88 insets += gfx::Insets(-kBubblePaddingHorizontalBottom);
89 set_anchor_view_insets(insets);
90
91 views::BubbleDialogDelegateView::CreateBubble(this);
92 if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
93 // These must both be called after CreateBubble.
94 SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT);
95 SetBorderInteriorThickness(kBorderInteriorThickness);
96 }
97 }
98
99 private:
100 // BubbleDialogDelegateView overrides:
101 gfx::Size GetPreferredSize() const override {
102 const gfx::Size size = BubbleDialogDelegateView::GetPreferredSize();
103 const int kTooltipMinHeight = kTooltipHeight - 2 * kTooltipTopBottomMargin;
104 return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
105 std::max(size.height(), kTooltipMinHeight));
106 }
107
108 void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
109 views::Widget* bubble_widget) const override {
110 // Place the bubble in the same display as the anchor.
111 WmWindow::Get(anchor_widget()->GetNativeWindow())
112 ->GetRootWindowController()
113 ->ConfigureWidgetInitParamsForContainer(
114 bubble_widget, kShellWindowId_SettingBubbleContainer, params);
115 }
116
117 int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; }
118
119 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble);
120 };
121
122 ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view)
123 : timer_delay_(kTooltipAppearanceDelay),
124 shelf_view_(shelf_view),
125 bubble_(nullptr),
126 weak_factory_(this) {
127 shelf_view_->wm_shelf()->AddObserver(this);
128 WmShell::Get()->AddPointerWatcher(this,
129 views::PointerWatcherEventTypes::BASIC);
130 }
131
132 ShelfTooltipManager::~ShelfTooltipManager() {
133 WmShell::Get()->RemovePointerWatcher(this);
134 shelf_view_->wm_shelf()->RemoveObserver(this);
135 WmWindow* window = nullptr;
136 if (shelf_view_->GetWidget())
137 window = WmWindow::Get(shelf_view_->GetWidget()->GetNativeWindow());
138 if (window)
139 window->RemoveLimitedPreTargetHandler(this);
140 }
141
142 void ShelfTooltipManager::Init() {
143 WmWindow* window = WmWindow::Get(shelf_view_->GetWidget()->GetNativeWindow());
144 window->AddLimitedPreTargetHandler(this);
145 }
146
147 void ShelfTooltipManager::Close() {
148 timer_.Stop();
149 if (bubble_)
150 bubble_->GetWidget()->Close();
151 bubble_ = nullptr;
152 }
153
154 bool ShelfTooltipManager::IsVisible() const {
155 return bubble_ && bubble_->GetWidget()->IsVisible();
156 }
157
158 views::View* ShelfTooltipManager::GetCurrentAnchorView() const {
159 return bubble_ ? bubble_->GetAnchorView() : nullptr;
160 }
161
162 void ShelfTooltipManager::ShowTooltip(views::View* view) {
163 timer_.Stop();
164 if (bubble_) {
165 // Cancel the hiding animation to hide the old bubble immediately.
166 WmWindow::Get(bubble_->GetWidget()->GetNativeWindow())
167 ->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE);
168 Close();
169 }
170
171 if (!ShouldShowTooltipForView(view))
172 return;
173
174 views::BubbleBorder::Arrow arrow = views::BubbleBorder::Arrow::NONE;
175 switch (shelf_view_->wm_shelf()->GetAlignment()) {
176 case SHELF_ALIGNMENT_BOTTOM:
177 case SHELF_ALIGNMENT_BOTTOM_LOCKED:
178 arrow = views::BubbleBorder::BOTTOM_CENTER;
179 break;
180 case SHELF_ALIGNMENT_LEFT:
181 arrow = views::BubbleBorder::LEFT_CENTER;
182 break;
183 case SHELF_ALIGNMENT_RIGHT:
184 arrow = views::BubbleBorder::RIGHT_CENTER;
185 break;
186 }
187
188 base::string16 text = shelf_view_->GetTitleForView(view);
189 bubble_ = new ShelfTooltipBubble(view, arrow, text);
190 WmWindow* window = WmWindow::Get(bubble_->GetWidget()->GetNativeWindow());
191 window->SetVisibilityAnimationType(
192 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
193 window->SetVisibilityAnimationTransition(::wm::ANIMATE_HIDE);
194 bubble_->GetWidget()->Show();
195 }
196
197 void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) {
198 if (ShouldShowTooltipForView(view)) {
199 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_),
200 base::Bind(&ShelfTooltipManager::ShowTooltip,
201 weak_factory_.GetWeakPtr(), view));
202 }
203 }
204
205 void ShelfTooltipManager::OnPointerEventObserved(
206 const ui::PointerEvent& event,
207 const gfx::Point& location_in_screen,
208 views::Widget* target) {
209 // Close on any press events inside or outside the tooltip.
210 if (event.type() == ui::ET_POINTER_DOWN)
211 Close();
212 }
213
214 void ShelfTooltipManager::OnMouseEvent(ui::MouseEvent* event) {
215 if (event->type() == ui::ET_MOUSE_EXITED) {
216 Close();
217 return;
218 }
219
220 if (event->type() != ui::ET_MOUSE_MOVED)
221 return;
222
223 gfx::Point point = event->location();
224 views::View::ConvertPointFromWidget(shelf_view_, &point);
225 views::View* view = shelf_view_->GetTooltipHandlerForPoint(point);
226 const bool should_show = ShouldShowTooltipForView(view);
227
228 timer_.Stop();
229 if (IsVisible() && should_show && bubble_->GetAnchorView() != view)
230 ShowTooltip(view);
231 else if (!IsVisible() && should_show)
232 ShowTooltipWithDelay(view);
233 else if (IsVisible() && shelf_view_->ShouldHideTooltip(point))
234 Close();
235 }
236
237 void ShelfTooltipManager::WillChangeVisibilityState(
238 ShelfVisibilityState new_state) {
239 if (new_state == SHELF_HIDDEN)
240 Close();
241 }
242
243 void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
244 if (new_state == SHELF_AUTO_HIDE_HIDDEN) {
245 timer_.Stop();
246 // AutoHide state change happens during an event filter, so immediate close
247 // may cause a crash in the HandleMouseEvent() after the filter. So we just
248 // schedule the Close here.
249 base::ThreadTaskRunnerHandle::Get()->PostTask(
250 FROM_HERE,
251 base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
252 }
253 }
254
255 bool ShelfTooltipManager::ShouldShowTooltipForView(views::View* view) {
256 WmShelf* shelf = shelf_view_ ? shelf_view_->wm_shelf() : nullptr;
257 return shelf && shelf_view_->ShouldShowTooltipForView(view) &&
258 (shelf->GetVisibilityState() == SHELF_VISIBLE ||
259 (shelf->GetVisibilityState() == SHELF_AUTO_HIDE &&
260 shelf->GetAutoHideState() == SHELF_AUTO_HIDE_SHOWN));
261 }
262
263 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/shelf/shelf_tooltip_manager.h ('k') | ash/common/shelf/shelf_tooltip_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698