Chromium Code Reviews| 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 |