OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/controls/link.h" | 5 #include "views/controls/link.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #if defined(TOOLKIT_USES_GTK) | 9 #if defined(TOOLKIT_USES_GTK) |
10 #include <gdk/gdk.h> | 10 #include <gdk/gdk.h> |
11 #endif | 11 #endif |
12 | 12 |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "ui/base/accessibility/accessible_view_state.h" | 15 #include "ui/base/accessibility/accessible_view_state.h" |
16 #include "ui/base/keycodes/keyboard_codes.h" | 16 #include "ui/base/keycodes/keyboard_codes.h" |
17 #include "ui/gfx/color_utils.h" | 17 #include "ui/gfx/color_utils.h" |
18 #include "ui/gfx/font.h" | 18 #include "ui/gfx/font.h" |
19 #include "views/controls/link_listener.h" | 19 #include "views/controls/link_listener.h" |
20 #include "views/events/event.h" | 20 #include "views/events/event.h" |
21 | 21 |
22 #if defined(TOOLKIT_USES_GTK) | 22 #if defined(TOOLKIT_USES_GTK) |
23 #include "ui/gfx/gtk_util.h" | 23 #include "ui/gfx/gtk_util.h" |
24 #endif | 24 #endif |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 void GetColors(const SkColor* background_color, // NULL means "use default" | 28 // The colors to use for enabled and disabled labels. |
29 SkColor* highlighted_color, | 29 SkColor kDefaultEnabledColor; |
sky
2011/10/11 00:42:35
Same comment here as in Label.
| |
30 SkColor* disabled_color, | 30 SkColor kDefaultDisabledColor; |
31 SkColor* normal_color) { | 31 SkColor kDefaultPressedColor; |
32 static SkColor kHighlightedColor, kDisabledColor, kNormalColor; | |
33 static bool initialized = false; | |
34 if (!initialized) { | |
35 #if defined(OS_WIN) | |
36 kHighlightedColor = color_utils::GetReadableColor( | |
37 SkColorSetRGB(200, 0, 0), color_utils::GetSysSkColor(COLOR_WINDOW)); | |
38 kDisabledColor = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); | |
39 kNormalColor = color_utils::GetSysSkColor(COLOR_HOTLIGHT); | |
40 #else | |
41 // TODO(beng): source from theme provider. | |
42 kHighlightedColor = SK_ColorRED; | |
43 kDisabledColor = SK_ColorBLACK; | |
44 kNormalColor = SkColorSetRGB(0, 51, 153); | |
45 #endif | |
46 | 32 |
47 initialized = true; | 33 }; |
48 } | |
49 | |
50 if (background_color) { | |
51 *highlighted_color = color_utils::GetReadableColor(kHighlightedColor, | |
52 *background_color); | |
53 *disabled_color = color_utils::GetReadableColor(kDisabledColor, | |
54 *background_color); | |
55 *normal_color = color_utils::GetReadableColor(kNormalColor, | |
56 *background_color); | |
57 } else { | |
58 *highlighted_color = kHighlightedColor; | |
59 *disabled_color = kDisabledColor; | |
60 *normal_color = kNormalColor; | |
61 } | |
62 } | |
63 } | |
64 | 34 |
65 namespace views { | 35 namespace views { |
66 | 36 |
67 const char Link::kViewClassName[] = "views/Link"; | 37 const char Link::kViewClassName[] = "views/Link"; |
68 | 38 |
69 Link::Link() : Label(string16()), | 39 Link::Link() : Label(string16()) { |
70 listener_(NULL), | |
71 highlighted_(false) { | |
72 Init(); | 40 Init(); |
73 set_focusable(true); | |
74 } | 41 } |
75 | 42 |
76 Link::Link(const string16& title) : Label(title), | 43 Link::Link(const string16& title) : Label(title) { |
77 listener_(NULL), | |
78 highlighted_(false) { | |
79 Init(); | 44 Init(); |
80 set_focusable(true); | |
81 } | |
82 | |
83 void Link::Init() { | |
84 GetColors(NULL, &highlighted_color_, &disabled_color_, &normal_color_); | |
85 SetColor(normal_color_); | |
86 ValidateStyle(); | |
87 } | 45 } |
88 | 46 |
89 Link::~Link() { | 47 Link::~Link() { |
90 } | 48 } |
91 | 49 |
92 void Link::OnEnabledChanged() { | 50 void Link::OnEnabledChanged() { |
93 ValidateStyle(); | 51 RecalculateFont(); |
94 View::OnEnabledChanged(); | 52 View::OnEnabledChanged(); |
95 } | 53 } |
96 | 54 |
97 std::string Link::GetClassName() const { | 55 std::string Link::GetClassName() const { |
98 return kViewClassName; | 56 return kViewClassName; |
99 } | 57 } |
100 | 58 |
101 gfx::NativeCursor Link::GetCursor(const MouseEvent& event) { | 59 gfx::NativeCursor Link::GetCursor(const MouseEvent& event) { |
102 if (!IsEnabled()) | 60 if (!IsEnabled()) |
103 return NULL; | 61 return NULL; |
(...skipping 11 matching lines...) Expand all Loading... | |
115 bool Link::HitTest(const gfx::Point& l) const { | 73 bool Link::HitTest(const gfx::Point& l) const { |
116 // We need to allow clicks on the link. So we override the implementation in | 74 // We need to allow clicks on the link. So we override the implementation in |
117 // Label and use the default implementation of View. | 75 // Label and use the default implementation of View. |
118 return View::HitTest(l); | 76 return View::HitTest(l); |
119 } | 77 } |
120 | 78 |
121 bool Link::OnMousePressed(const MouseEvent& event) { | 79 bool Link::OnMousePressed(const MouseEvent& event) { |
122 if (!IsEnabled() || | 80 if (!IsEnabled() || |
123 (!event.IsLeftMouseButton() && !event.IsMiddleMouseButton())) | 81 (!event.IsLeftMouseButton() && !event.IsMiddleMouseButton())) |
124 return false; | 82 return false; |
125 SetHighlighted(true); | 83 SetPressed(true); |
126 return true; | 84 return true; |
127 } | 85 } |
128 | 86 |
129 bool Link::OnMouseDragged(const MouseEvent& event) { | 87 bool Link::OnMouseDragged(const MouseEvent& event) { |
130 SetHighlighted(IsEnabled() && | 88 SetPressed(IsEnabled() && |
131 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && | 89 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && |
132 HitTest(event.location())); | 90 HitTest(event.location())); |
133 return true; | 91 return true; |
134 } | 92 } |
135 | 93 |
136 void Link::OnMouseReleased(const MouseEvent& event) { | 94 void Link::OnMouseReleased(const MouseEvent& event) { |
137 // Change the highlight first just in case this instance is deleted | 95 // Change the highlight first just in case this instance is deleted |
138 // while calling the controller | 96 // while calling the controller |
139 OnMouseCaptureLost(); | 97 OnMouseCaptureLost(); |
140 if (IsEnabled() && | 98 if (IsEnabled() && |
141 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && | 99 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && |
142 HitTest(event.location())) { | 100 HitTest(event.location())) { |
143 // Focus the link on click. | 101 // Focus the link on click. |
144 RequestFocus(); | 102 RequestFocus(); |
145 | 103 |
146 if (listener_) | 104 if (listener_) |
147 listener_->LinkClicked(this, event.flags()); | 105 listener_->LinkClicked(this, event.flags()); |
148 } | 106 } |
149 } | 107 } |
150 | 108 |
151 void Link::OnMouseCaptureLost() { | 109 void Link::OnMouseCaptureLost() { |
152 SetHighlighted(false); | 110 SetPressed(false); |
153 } | 111 } |
154 | 112 |
155 bool Link::OnKeyPressed(const KeyEvent& event) { | 113 bool Link::OnKeyPressed(const KeyEvent& event) { |
156 bool activate = ((event.key_code() == ui::VKEY_SPACE) || | 114 bool activate = ((event.key_code() == ui::VKEY_SPACE) || |
157 (event.key_code() == ui::VKEY_RETURN)); | 115 (event.key_code() == ui::VKEY_RETURN)); |
158 if (!activate) | 116 if (!activate) |
159 return false; | 117 return false; |
160 | 118 |
161 SetHighlighted(false); | 119 SetPressed(false); |
162 | 120 |
163 // Focus the link on key pressed. | 121 // Focus the link on key pressed. |
164 RequestFocus(); | 122 RequestFocus(); |
165 | 123 |
166 if (listener_) | 124 if (listener_) |
167 listener_->LinkClicked(this, event.flags()); | 125 listener_->LinkClicked(this, event.flags()); |
168 | 126 |
169 return true; | 127 return true; |
170 } | 128 } |
171 | 129 |
172 bool Link::SkipDefaultKeyEventProcessing(const KeyEvent& event) { | 130 bool Link::SkipDefaultKeyEventProcessing(const KeyEvent& event) { |
173 // Make sure we don't process space or enter as accelerators. | 131 // Make sure we don't process space or enter as accelerators. |
174 return (event.key_code() == ui::VKEY_SPACE) || | 132 return (event.key_code() == ui::VKEY_SPACE) || |
175 (event.key_code() == ui::VKEY_RETURN); | 133 (event.key_code() == ui::VKEY_RETURN); |
176 } | 134 } |
177 | 135 |
178 void Link::GetAccessibleState(ui::AccessibleViewState* state) { | 136 void Link::GetAccessibleState(ui::AccessibleViewState* state) { |
179 Label::GetAccessibleState(state); | 137 Label::GetAccessibleState(state); |
180 state->role = ui::AccessibilityTypes::ROLE_LINK; | 138 state->role = ui::AccessibilityTypes::ROLE_LINK; |
181 } | 139 } |
182 | 140 |
183 void Link::SetFont(const gfx::Font& font) { | 141 void Link::SetFont(const gfx::Font& font) { |
184 Label::SetFont(font); | 142 Label::SetFont(font); |
185 ValidateStyle(); | 143 RecalculateFont(); |
186 } | 144 } |
187 | 145 |
188 void Link::SetHighlightedColor(const SkColor& color) { | 146 void Link::SetEnabledColor(const SkColor& color) { |
189 highlighted_color_ = color; | 147 requested_enabled_color_ = color; |
190 ValidateStyle(); | 148 if (!pressed_) |
149 Label::SetEnabledColor(requested_enabled_color_); | |
191 } | 150 } |
192 | 151 |
193 void Link::SetDisabledColor(const SkColor& color) { | 152 void Link::SetPressedColor(const SkColor& color) { |
194 disabled_color_ = color; | 153 requested_pressed_color_ = color; |
195 ValidateStyle(); | 154 if (pressed_) |
155 Label::SetEnabledColor(requested_pressed_color_); | |
196 } | 156 } |
197 | 157 |
198 void Link::SetNormalColor(const SkColor& color) { | 158 void Link::Init() { |
199 normal_color_ = color; | 159 static bool initialized = false; |
200 ValidateStyle(); | 160 if (!initialized) { |
161 #if defined(OS_WIN) | |
162 kDefaultEnabledColor = color_utils::GetSysSkColor(COLOR_HOTLIGHT); | |
163 kDefaultDisabledColor = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); | |
164 kDefaultPressedColor = SkColorSetRGB(200, 0, 0); | |
165 #else | |
166 // TODO(beng): source from theme provider. | |
167 kDefaultEnabledColor = SkColorSetRGB(0, 51, 153); | |
168 kDefaultDisabledColor = SK_ColorBLACK; | |
169 kDefaultPressedColor = SK_ColorRED; | |
170 #endif | |
171 | |
172 initialized = true; | |
173 } | |
174 | |
175 listener_ = NULL; | |
176 pressed_ = false; | |
177 SetEnabledColor(kDefaultEnabledColor); | |
178 SetDisabledColor(kDefaultDisabledColor); | |
179 SetPressedColor(kDefaultPressedColor); | |
180 RecalculateFont(); | |
181 set_focusable(true); | |
201 } | 182 } |
202 | 183 |
203 void Link::MakeReadableOverBackgroundColor(const SkColor& color) { | 184 void Link::SetPressed(bool pressed) { |
204 GetColors(&color, &highlighted_color_, &disabled_color_, &normal_color_); | 185 if (pressed_ != pressed) { |
205 ValidateStyle(); | 186 pressed_ = pressed; |
206 } | 187 Label::SetEnabledColor(pressed_ ? |
207 | 188 requested_pressed_color_ : requested_enabled_color_); |
208 void Link::SetHighlighted(bool f) { | 189 RecalculateFont(); |
209 if (f != highlighted_) { | |
210 highlighted_ = f; | |
211 ValidateStyle(); | |
212 SchedulePaint(); | 190 SchedulePaint(); |
213 } | 191 } |
214 } | 192 } |
215 | 193 |
216 void Link::ValidateStyle() { | 194 void Link::RecalculateFont() { |
217 if (IsEnabled()) { | 195 // The font should be underlined iff the link is enabled. |
218 if (!(font().GetStyle() & gfx::Font::UNDERLINED)) { | 196 if (IsEnabled() == !(font().GetStyle() & gfx::Font::UNDERLINED)) { |
219 Label::SetFont( | 197 Label::SetFont(font().DeriveFont(0, IsEnabled() ? |
220 font().DeriveFont(0, font().GetStyle() | gfx::Font::UNDERLINED)); | 198 (font().GetStyle() | gfx::Font::UNDERLINED) : |
221 } | 199 (font().GetStyle() & ~gfx::Font::UNDERLINED))); |
222 Label::SetColor(highlighted_ ? highlighted_color_ : normal_color_); | |
223 } else { | |
224 if (font().GetStyle() & gfx::Font::UNDERLINED) { | |
225 Label::SetFont( | |
226 font().DeriveFont(0, font().GetStyle() & ~gfx::Font::UNDERLINED)); | |
227 } | |
228 Label::SetColor(disabled_color_); | |
229 } | 200 } |
230 } | 201 } |
231 | 202 |
232 } // namespace views | 203 } // namespace views |
OLD | NEW |