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

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
« no previous file with comments | « views/controls/link.h ('k') | views/view_text_utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 {
27
28 void GetColors(const SkColor* background_color, // NULL means "use default"
29 SkColor* highlighted_color,
30 SkColor* disabled_color,
31 SkColor* normal_color) {
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
47 initialized = true;
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
65 namespace views { 26 namespace views {
66 27
67 const char Link::kViewClassName[] = "views/Link"; 28 const char Link::kViewClassName[] = "views/Link";
68 29
69 Link::Link() : Label(string16()), 30 Link::Link() : Label(string16()) {
70 listener_(NULL),
71 highlighted_(false) {
72 Init(); 31 Init();
73 set_focusable(true);
74 } 32 }
75 33
76 Link::Link(const string16& title) : Label(title), 34 Link::Link(const string16& title) : Label(title) {
77 listener_(NULL),
78 highlighted_(false) {
79 Init(); 35 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 } 36 }
88 37
89 Link::~Link() { 38 Link::~Link() {
90 } 39 }
91 40
92 void Link::OnEnabledChanged() { 41 void Link::OnEnabledChanged() {
93 ValidateStyle(); 42 RecalculateFont();
94 View::OnEnabledChanged(); 43 View::OnEnabledChanged();
95 } 44 }
96 45
97 std::string Link::GetClassName() const { 46 std::string Link::GetClassName() const {
98 return kViewClassName; 47 return kViewClassName;
99 } 48 }
100 49
101 gfx::NativeCursor Link::GetCursor(const MouseEvent& event) { 50 gfx::NativeCursor Link::GetCursor(const MouseEvent& event) {
102 if (!IsEnabled()) 51 if (!IsEnabled())
103 return gfx::kNullCursor; 52 return gfx::kNullCursor;
(...skipping 11 matching lines...) Expand all
115 bool Link::HitTest(const gfx::Point& l) const { 64 bool Link::HitTest(const gfx::Point& l) const {
116 // We need to allow clicks on the link. So we override the implementation in 65 // We need to allow clicks on the link. So we override the implementation in
117 // Label and use the default implementation of View. 66 // Label and use the default implementation of View.
118 return View::HitTest(l); 67 return View::HitTest(l);
119 } 68 }
120 69
121 bool Link::OnMousePressed(const MouseEvent& event) { 70 bool Link::OnMousePressed(const MouseEvent& event) {
122 if (!IsEnabled() || 71 if (!IsEnabled() ||
123 (!event.IsLeftMouseButton() && !event.IsMiddleMouseButton())) 72 (!event.IsLeftMouseButton() && !event.IsMiddleMouseButton()))
124 return false; 73 return false;
125 SetHighlighted(true); 74 SetPressed(true);
126 return true; 75 return true;
127 } 76 }
128 77
129 bool Link::OnMouseDragged(const MouseEvent& event) { 78 bool Link::OnMouseDragged(const MouseEvent& event) {
130 SetHighlighted(IsEnabled() && 79 SetPressed(IsEnabled() &&
131 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && 80 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) &&
132 HitTest(event.location())); 81 HitTest(event.location()));
133 return true; 82 return true;
134 } 83 }
135 84
136 void Link::OnMouseReleased(const MouseEvent& event) { 85 void Link::OnMouseReleased(const MouseEvent& event) {
137 // Change the highlight first just in case this instance is deleted 86 // Change the highlight first just in case this instance is deleted
138 // while calling the controller 87 // while calling the controller
139 OnMouseCaptureLost(); 88 OnMouseCaptureLost();
140 if (IsEnabled() && 89 if (IsEnabled() &&
141 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) && 90 (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) &&
142 HitTest(event.location())) { 91 HitTest(event.location())) {
143 // Focus the link on click. 92 // Focus the link on click.
144 RequestFocus(); 93 RequestFocus();
145 94
146 if (listener_) 95 if (listener_)
147 listener_->LinkClicked(this, event.flags()); 96 listener_->LinkClicked(this, event.flags());
148 } 97 }
149 } 98 }
150 99
151 void Link::OnMouseCaptureLost() { 100 void Link::OnMouseCaptureLost() {
152 SetHighlighted(false); 101 SetPressed(false);
153 } 102 }
154 103
155 bool Link::OnKeyPressed(const KeyEvent& event) { 104 bool Link::OnKeyPressed(const KeyEvent& event) {
156 bool activate = ((event.key_code() == ui::VKEY_SPACE) || 105 bool activate = ((event.key_code() == ui::VKEY_SPACE) ||
157 (event.key_code() == ui::VKEY_RETURN)); 106 (event.key_code() == ui::VKEY_RETURN));
158 if (!activate) 107 if (!activate)
159 return false; 108 return false;
160 109
161 SetHighlighted(false); 110 SetPressed(false);
162 111
163 // Focus the link on key pressed. 112 // Focus the link on key pressed.
164 RequestFocus(); 113 RequestFocus();
165 114
166 if (listener_) 115 if (listener_)
167 listener_->LinkClicked(this, event.flags()); 116 listener_->LinkClicked(this, event.flags());
168 117
169 return true; 118 return true;
170 } 119 }
171 120
172 bool Link::SkipDefaultKeyEventProcessing(const KeyEvent& event) { 121 bool Link::SkipDefaultKeyEventProcessing(const KeyEvent& event) {
173 // Make sure we don't process space or enter as accelerators. 122 // Make sure we don't process space or enter as accelerators.
174 return (event.key_code() == ui::VKEY_SPACE) || 123 return (event.key_code() == ui::VKEY_SPACE) ||
175 (event.key_code() == ui::VKEY_RETURN); 124 (event.key_code() == ui::VKEY_RETURN);
176 } 125 }
177 126
178 void Link::GetAccessibleState(ui::AccessibleViewState* state) { 127 void Link::GetAccessibleState(ui::AccessibleViewState* state) {
179 Label::GetAccessibleState(state); 128 Label::GetAccessibleState(state);
180 state->role = ui::AccessibilityTypes::ROLE_LINK; 129 state->role = ui::AccessibilityTypes::ROLE_LINK;
181 } 130 }
182 131
183 void Link::SetFont(const gfx::Font& font) { 132 void Link::SetFont(const gfx::Font& font) {
184 Label::SetFont(font); 133 Label::SetFont(font);
185 ValidateStyle(); 134 RecalculateFont();
186 } 135 }
187 136
188 void Link::SetHighlightedColor(const SkColor& color) { 137 void Link::SetEnabledColor(const SkColor& color) {
189 highlighted_color_ = color; 138 requested_enabled_color_ = color;
190 ValidateStyle(); 139 if (!pressed_)
140 Label::SetEnabledColor(requested_enabled_color_);
191 } 141 }
192 142
193 void Link::SetDisabledColor(const SkColor& color) { 143 void Link::SetPressedColor(const SkColor& color) {
194 disabled_color_ = color; 144 requested_pressed_color_ = color;
195 ValidateStyle(); 145 if (pressed_)
146 Label::SetEnabledColor(requested_pressed_color_);
196 } 147 }
197 148
198 void Link::SetNormalColor(const SkColor& color) { 149 void Link::Init() {
199 normal_color_ = color; 150 static bool initialized = false;
200 ValidateStyle(); 151 static SkColor kDefaultEnabledColor;
152 static SkColor kDefaultDisabledColor;
153 static SkColor kDefaultPressedColor;
154 if (!initialized) {
155 #if defined(OS_WIN)
156 kDefaultEnabledColor = color_utils::GetSysSkColor(COLOR_HOTLIGHT);
157 kDefaultDisabledColor = color_utils::GetSysSkColor(COLOR_WINDOWTEXT);
158 kDefaultPressedColor = SkColorSetRGB(200, 0, 0);
159 #else
160 // TODO(beng): source from theme provider.
161 kDefaultEnabledColor = SkColorSetRGB(0, 51, 153);
162 kDefaultDisabledColor = SK_ColorBLACK;
163 kDefaultPressedColor = SK_ColorRED;
164 #endif
165
166 initialized = true;
167 }
168
169 listener_ = NULL;
170 pressed_ = false;
171 SetEnabledColor(kDefaultEnabledColor);
172 SetDisabledColor(kDefaultDisabledColor);
173 SetPressedColor(kDefaultPressedColor);
174 RecalculateFont();
175 set_focusable(true);
201 } 176 }
202 177
203 void Link::MakeReadableOverBackgroundColor(const SkColor& color) { 178 void Link::SetPressed(bool pressed) {
204 GetColors(&color, &highlighted_color_, &disabled_color_, &normal_color_); 179 if (pressed_ != pressed) {
205 ValidateStyle(); 180 pressed_ = pressed;
206 } 181 Label::SetEnabledColor(pressed_ ?
207 182 requested_pressed_color_ : requested_enabled_color_);
208 void Link::SetHighlighted(bool f) { 183 RecalculateFont();
209 if (f != highlighted_) {
210 highlighted_ = f;
211 ValidateStyle();
212 SchedulePaint(); 184 SchedulePaint();
213 } 185 }
214 } 186 }
215 187
216 void Link::ValidateStyle() { 188 void Link::RecalculateFont() {
217 if (IsEnabled()) { 189 // The font should be underlined iff the link is enabled.
218 if (!(font().GetStyle() & gfx::Font::UNDERLINED)) { 190 if (IsEnabled() == !(font().GetStyle() & gfx::Font::UNDERLINED)) {
219 Label::SetFont( 191 Label::SetFont(font().DeriveFont(0, IsEnabled() ?
220 font().DeriveFont(0, font().GetStyle() | gfx::Font::UNDERLINED)); 192 (font().GetStyle() | gfx::Font::UNDERLINED) :
221 } 193 (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 } 194 }
230 } 195 }
231 196
232 } // namespace views 197 } // namespace views
OLDNEW
« no previous file with comments | « 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