1 // Copyright (c) 2012 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 "ui/views/controls/link.h"
7 #include "build/build_config.h"
9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "ui/base/accessibility/accessible_view_state.h"
12 #include "ui/events/event.h"
13 #include "ui/events/keycodes/keyboard_codes.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/color_utils.h"
16 #include "ui/gfx/font.h"
17 #include "ui/views/controls/link_listener.h"
20 #include "ui/base/cursor/cursor.h"
25 const char Link::kViewClassName
[] = "Link";
27 Link::Link() : Label(base::string16()) {
31 Link::Link(const base::string16
& title
) : Label(title
) {
38 SkColor
Link::GetDefaultEnabledColor() {
40 return color_utils::GetSysSkColor(COLOR_HOTLIGHT
);
42 return SkColorSetRGB(0, 51, 153);
46 void Link::OnEnabledChanged() {
48 View::OnEnabledChanged();
51 const char* Link::GetClassName() const {
52 return kViewClassName
;
55 gfx::NativeCursor
Link::GetCursor(const ui::MouseEvent
& event
) {
57 return gfx::kNullCursor
;
59 return ui::kCursorHand
;
61 static HCURSOR g_hand_cursor
= LoadCursor(NULL
, IDC_HAND
);
66 void Link::OnPaint(gfx::Canvas
* canvas
) {
67 Label::OnPaint(canvas
);
70 canvas
->DrawFocusRect(GetLocalBounds());
73 void Link::OnFocus() {
75 // We render differently focused.
81 // We render differently focused.
85 bool Link::HitTestRect(const gfx::Rect
& rect
) const {
86 // We need to allow clicks on the link. So we override the implementation in
87 // Label and use the default implementation of View.
88 return View::HitTestRect(rect
);
91 bool Link::OnMousePressed(const ui::MouseEvent
& event
) {
93 (!event
.IsLeftMouseButton() && !event
.IsMiddleMouseButton()))
99 bool Link::OnMouseDragged(const ui::MouseEvent
& event
) {
100 SetPressed(enabled() &&
101 (event
.IsLeftMouseButton() || event
.IsMiddleMouseButton()) &&
102 HitTestPoint(event
.location()));
106 void Link::OnMouseReleased(const ui::MouseEvent
& event
) {
107 // Change the highlight first just in case this instance is deleted
108 // while calling the controller
109 OnMouseCaptureLost();
111 (event
.IsLeftMouseButton() || event
.IsMiddleMouseButton()) &&
112 HitTestPoint(event
.location())) {
113 // Focus the link on click.
117 listener_
->LinkClicked(this, event
.flags());
121 void Link::OnMouseCaptureLost() {
125 bool Link::OnKeyPressed(const ui::KeyEvent
& event
) {
126 bool activate
= ((event
.key_code() == ui::VKEY_SPACE
) ||
127 (event
.key_code() == ui::VKEY_RETURN
));
133 // Focus the link on key pressed.
137 listener_
->LinkClicked(this, event
.flags());
142 bool Link::SkipDefaultKeyEventProcessing(const ui::KeyEvent
& event
) {
143 // Make sure we don't process space or enter as accelerators.
144 return (event
.key_code() == ui::VKEY_SPACE
) ||
145 (event
.key_code() == ui::VKEY_RETURN
);
148 void Link::GetAccessibleState(ui::AccessibleViewState
* state
) {
149 Label::GetAccessibleState(state
);
150 state
->role
= ui::AccessibilityTypes::ROLE_LINK
;
153 void Link::OnGestureEvent(ui::GestureEvent
* event
) {
157 if (event
->type() == ui::ET_GESTURE_TAP_DOWN
) {
159 } else if (event
->type() == ui::ET_GESTURE_TAP
) {
162 listener_
->LinkClicked(this, event
->flags());
170 void Link::SetFont(const gfx::Font
& font
) {
171 Label::SetFont(font
);
175 void Link::SetEnabledColor(SkColor color
) {
176 requested_enabled_color_
= color
;
178 Label::SetEnabledColor(requested_enabled_color_
);
181 void Link::SetPressedColor(SkColor color
) {
182 requested_pressed_color_
= color
;
184 Label::SetEnabledColor(requested_pressed_color_
);
187 void Link::SetUnderline(bool underline
) {
188 if (underline_
== underline
)
190 underline_
= underline
;
198 SetEnabledColor(GetDefaultEnabledColor());
200 SetDisabledColor(color_utils::GetSysSkColor(COLOR_WINDOWTEXT
));
201 SetPressedColor(SkColorSetRGB(200, 0, 0));
203 // TODO(beng): source from theme provider.
204 SetDisabledColor(SK_ColorBLACK
);
205 SetPressedColor(SK_ColorRED
);
211 void Link::SetPressed(bool pressed
) {
212 if (pressed_
!= pressed
) {
214 Label::SetEnabledColor(pressed_
?
215 requested_pressed_color_
: requested_enabled_color_
);
221 void Link::RecalculateFont() {
222 // Underline the link iff it is enabled and |underline_| is true.
223 const int style
= font().GetStyle();
224 const int intended_style
= (enabled() && underline_
) ?
225 (style
| gfx::Font::UNDERLINE
) : (style
& ~gfx::Font::UNDERLINE
);
226 if (style
!= intended_style
)
227 Label::SetFont(font().DeriveFont(0, intended_style
));