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

Side by Side Diff: views/controls/link.cc

Issue 8221027: Make views::Label and views::Link auto-color themselves to be readable over their background colo... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
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
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
OLDNEW
« views/controls/label.cc ('K') | « views/controls/link.h ('k') | views/view_text_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698