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.
5 #include "chrome/browser/ui/views/autofill/tooltip_icon.h"
7 #include "base/basictypes.h"
8 #include "base/timer/timer.h"
9 #include "chrome/browser/ui/views/autofill/info_bubble.h"
10 #include "grit/theme_resources.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/views/bubble/bubble_frame_view.h"
13 #include "ui/views/mouse_watcher_view_host.h"
14 #include "ui/views/painter.h"
20 gfx::Insets
GetPreferredInsets(views::View
* view
) {
21 gfx::Size pref_size
= view
->GetPreferredSize();
22 gfx::Rect local_bounds
= view
->GetLocalBounds();
23 gfx::Point origin
= local_bounds
.CenterPoint();
24 origin
.Offset(-pref_size
.width() / 2, -pref_size
.height() / 2);
25 return gfx::Insets(origin
.y(),
27 local_bounds
.bottom() - (origin
.y() + pref_size
.height()),
28 local_bounds
.right() - (origin
.x() + pref_size
.width()));
31 // An info bubble with some extra positioning magic for tooltip icons.
32 class TooltipBubble
: public InfoBubble
{
34 TooltipBubble(views::View
* anchor
, const base::string16
& message
)
35 : InfoBubble(anchor
, message
) {}
36 virtual ~TooltipBubble() {}
40 virtual gfx::Rect
GetAnchorRect() OVERRIDE
{
41 gfx::Rect bounds
= views::BubbleDelegateView::GetAnchorRect();
42 bounds
.Inset(GetPreferredInsets(anchor()));
47 DISALLOW_COPY_AND_ASSIGN(TooltipBubble
);
52 TooltipIcon::TooltipIcon(const base::string16
& tooltip
)
57 ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON
);
61 TooltipIcon::~TooltipIcon() {
66 const char TooltipIcon::kViewClassName
[] = "autofill/TooltipIcon";
68 const char* TooltipIcon::GetClassName() const {
69 return TooltipIcon::kViewClassName
;
72 void TooltipIcon::OnMouseEntered(const ui::MouseEvent
& event
) {
74 show_timer_
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(150), this,
75 &TooltipIcon::ShowBubble
);
78 void TooltipIcon::OnMouseExited(const ui::MouseEvent
& event
) {
82 void TooltipIcon::OnGestureEvent(ui::GestureEvent
* event
) {
83 if (event
->type() == ui::ET_GESTURE_TAP
) {
89 void TooltipIcon::OnBoundsChanged(const gfx::Rect
& prev_bounds
) {
90 SetFocusPainter(views::Painter::CreateDashedFocusPainterWithInsets(
91 GetPreferredInsets(this)));
94 void TooltipIcon::OnFocus() {
98 void TooltipIcon::OnBlur() {
103 void TooltipIcon::MouseMovedOutOfHost() {
104 if (IsMouseHovered()) {
105 mouse_watcher_
->Start();
109 mouse_inside_
= false;
114 void TooltipIcon::ChangeImageTo(int idr
) {
115 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
116 SetImage(rb
.GetImageNamed(idr
).ToImageSkia());
119 void TooltipIcon::ShowBubble() {
123 ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON_H
);
125 bubble_
= new TooltipBubble(this, tooltip_
);
126 // When shown due to a gesture event, close on deactivate (i.e. don't use
128 bubble_
->set_use_focusless(mouse_inside_
|| HasFocus());
131 observer_
.Add(bubble_
->GetWidget());
134 views::View
* frame
= bubble_
->GetWidget()->non_client_view()->frame_view();
135 scoped_ptr
<views::MouseWatcherHost
> host(
136 new views::MouseWatcherViewHost(frame
, gfx::Insets()));
137 mouse_watcher_
.reset(new views::MouseWatcher(host
.release(), this));
138 mouse_watcher_
->Start();
142 void TooltipIcon::HideBubble() {
147 void TooltipIcon::OnWidgetDestroyed(views::Widget
* widget
) {
148 observer_
.Remove(widget
);
150 ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON
);
151 mouse_watcher_
.reset();
155 } // namespace autofill