| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/controls/button/label_button.h" | 5 #include "ui/views/controls/button/label_button.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "ui/views/controls/button/label_button_border.h" | 23 #include "ui/views/controls/button/label_button_border.h" |
| 24 #include "ui/views/painter.h" | 24 #include "ui/views/painter.h" |
| 25 #include "ui/views/style/platform_style.h" | 25 #include "ui/views/style/platform_style.h" |
| 26 #include "ui/views/window/dialog_delegate.h" | 26 #include "ui/views/window/dialog_delegate.h" |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 // The default spacing between the icon and text. | 30 // The default spacing between the icon and text. |
| 31 const int kSpacing = 5; | 31 const int kSpacing = 5; |
| 32 | 32 |
| 33 #if !(defined(OS_LINUX) && !defined(OS_CHROMEOS)) | |
| 34 // Default text and shadow colors for STYLE_BUTTON. | |
| 35 const SkColor kStyleButtonTextColor = SK_ColorBLACK; | |
| 36 const SkColor kStyleButtonShadowColor = SK_ColorWHITE; | |
| 37 #endif | |
| 38 | |
| 39 const gfx::FontList& GetDefaultNormalFontList() { | 33 const gfx::FontList& GetDefaultNormalFontList() { |
| 40 static base::LazyInstance<gfx::FontList>::Leaky font_list = | 34 static base::LazyInstance<gfx::FontList>::Leaky font_list = |
| 41 LAZY_INSTANCE_INITIALIZER; | 35 LAZY_INSTANCE_INITIALIZER; |
| 42 return font_list.Get(); | 36 return font_list.Get(); |
| 43 } | 37 } |
| 44 | 38 |
| 45 const gfx::FontList& GetDefaultBoldFontList() { | 39 const gfx::FontList& GetDefaultBoldFontList() { |
| 40 if (!views::PlatformStyle::kDefaultLabelButtonHasBoldFont) |
| 41 return GetDefaultNormalFontList(); |
| 42 |
| 46 static base::LazyInstance<gfx::FontList>::Leaky font_list = | 43 static base::LazyInstance<gfx::FontList>::Leaky font_list = |
| 47 LAZY_INSTANCE_INITIALIZER; | 44 LAZY_INSTANCE_INITIALIZER; |
| 48 if ((font_list.Get().GetFontStyle() & gfx::Font::BOLD) == 0) { | 45 if ((font_list.Get().GetFontStyle() & gfx::Font::BOLD) == 0) { |
| 49 font_list.Get() = font_list.Get(). | 46 font_list.Get() = font_list.Get(). |
| 50 DeriveWithStyle(font_list.Get().GetFontStyle() | gfx::Font::BOLD); | 47 DeriveWithStyle(font_list.Get().GetFontStyle() | gfx::Font::BOLD); |
| 51 DCHECK_NE(font_list.Get().GetFontStyle() & gfx::Font::BOLD, 0); | 48 DCHECK_NE(font_list.Get().GetFontStyle() & gfx::Font::BOLD, 0); |
| 52 } | 49 } |
| 53 return font_list.Get(); | 50 return font_list.Get(); |
| 54 } | 51 } |
| 55 | 52 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { | 153 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { |
| 157 label_->SetSubpixelRenderingEnabled(enabled); | 154 label_->SetSubpixelRenderingEnabled(enabled); |
| 158 } | 155 } |
| 159 | 156 |
| 160 const gfx::FontList& LabelButton::GetFontList() const { | 157 const gfx::FontList& LabelButton::GetFontList() const { |
| 161 return label_->font_list(); | 158 return label_->font_list(); |
| 162 } | 159 } |
| 163 | 160 |
| 164 void LabelButton::SetFontList(const gfx::FontList& font_list) { | 161 void LabelButton::SetFontList(const gfx::FontList& font_list) { |
| 165 cached_normal_font_list_ = font_list; | 162 cached_normal_font_list_ = font_list; |
| 166 cached_bold_font_list_ = font_list.DeriveWithStyle( | 163 if (PlatformStyle::kDefaultLabelButtonHasBoldFont) { |
| 167 font_list.GetFontStyle() | gfx::Font::BOLD); | 164 cached_bold_font_list_ = |
| 168 label_->SetFontList(is_default_ ? | 165 font_list.DeriveWithStyle(font_list.GetFontStyle() | gfx::Font::BOLD); |
| 169 cached_bold_font_list_ : cached_normal_font_list_); | 166 if (is_default_) { |
| 167 label_->SetFontList(cached_bold_font_list_); |
| 168 return; |
| 169 } |
| 170 } |
| 171 label_->SetFontList(cached_normal_font_list_); |
| 170 } | 172 } |
| 171 | 173 |
| 172 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { | 174 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { |
| 173 label_->SetElideBehavior(elide_behavior); | 175 label_->SetElideBehavior(elide_behavior); |
| 174 } | 176 } |
| 175 | 177 |
| 176 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { | 178 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { |
| 177 DCHECK_NE(gfx::ALIGN_TO_HEAD, alignment); | 179 DCHECK_NE(gfx::ALIGN_TO_HEAD, alignment); |
| 178 horizontal_alignment_ = alignment; | 180 horizontal_alignment_ = alignment; |
| 179 InvalidateLayout(); | 181 InvalidateLayout(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 191 | 193 |
| 192 void LabelButton::SetIsDefault(bool is_default) { | 194 void LabelButton::SetIsDefault(bool is_default) { |
| 193 DCHECK_EQ(STYLE_BUTTON, style_); | 195 DCHECK_EQ(STYLE_BUTTON, style_); |
| 194 if (is_default == is_default_) | 196 if (is_default == is_default_) |
| 195 return; | 197 return; |
| 196 | 198 |
| 197 is_default_ = is_default; | 199 is_default_ = is_default; |
| 198 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); | 200 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); |
| 199 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); | 201 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); |
| 200 | 202 |
| 201 label_->SetFontList( | 203 const bool bold = PlatformStyle::kDefaultLabelButtonHasBoldFont && is_default; |
| 202 is_default ? cached_bold_font_list_ : cached_normal_font_list_); | 204 label_->SetFontList(bold ? cached_bold_font_list_ : cached_normal_font_list_); |
| 203 InvalidateLayout(); | 205 InvalidateLayout(); |
| 206 ResetLabelEnabledColor(); |
| 204 } | 207 } |
| 205 | 208 |
| 206 void LabelButton::SetStyle(ButtonStyle style) { | 209 void LabelButton::SetStyle(ButtonStyle style) { |
| 207 // All callers currently pass STYLE_BUTTON, and should only call this once, to | 210 // All callers currently pass STYLE_BUTTON, and should only call this once, to |
| 208 // change from the default style. | 211 // change from the default style. |
| 209 DCHECK_EQ(style, STYLE_BUTTON); | 212 DCHECK_EQ(style, STYLE_BUTTON); |
| 210 DCHECK_EQ(style_, STYLE_TEXTBUTTON); | 213 DCHECK_EQ(style_, STYLE_TEXTBUTTON); |
| 211 DCHECK(!GetWidget()) << "Can't change button style after adding to a Widget."; | 214 DCHECK(!GetWidget()) << "Can't change button style after adding to a Widget."; |
| 212 | 215 |
| 213 style_ = style; | 216 style_ = style; |
| 214 | 217 |
| 215 SetFocusPainter(nullptr); | 218 SetFocusPainter(nullptr); |
| 216 SetHorizontalAlignment(gfx::ALIGN_CENTER); | 219 SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 217 SetFocusable(true); | 220 SetFocusable(true); |
| 218 SetMinSize(gfx::Size(70, 33)); | 221 SetMinSize(gfx::Size(PlatformStyle::kMinLabelButtonWidth, |
| 222 PlatformStyle::kMinLabelButtonHeight)); |
| 219 | 223 |
| 220 // Themed borders will be set once the button is added to a Widget, since that | 224 // Themed borders will be set once the button is added to a Widget, since that |
| 221 // provides the value of GetNativeTheme(). | 225 // provides the value of GetNativeTheme(). |
| 222 } | 226 } |
| 223 | 227 |
| 224 void LabelButton::SetImageLabelSpacing(int spacing) { | 228 void LabelButton::SetImageLabelSpacing(int spacing) { |
| 225 if (spacing == image_label_spacing_) | 229 if (spacing == image_label_spacing_) |
| 226 return; | 230 return; |
| 227 image_label_spacing_ = spacing; | 231 image_label_spacing_ = spacing; |
| 228 ResetCachedPreferredSize(); | 232 ResetCachedPreferredSize(); |
| 229 InvalidateLayout(); | 233 InvalidateLayout(); |
| 230 } | 234 } |
| 231 | 235 |
| 232 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { | 236 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { |
| 233 focus_painter_ = std::move(focus_painter); | 237 focus_painter_ = std::move(focus_painter); |
| 234 } | 238 } |
| 235 | 239 |
| 236 gfx::Size LabelButton::GetPreferredSize() const { | 240 gfx::Size LabelButton::GetPreferredSize() const { |
| 237 if (cached_preferred_size_valid_) | 241 if (cached_preferred_size_valid_) |
| 238 return cached_preferred_size_; | 242 return cached_preferred_size_; |
| 239 | 243 |
| 240 // Use a temporary label copy for sizing to avoid calculation side-effects. | 244 // Use a temporary label copy for sizing to avoid calculation side-effects. |
| 241 Label label(GetText(), cached_normal_font_list_); | 245 Label label(GetText(), cached_normal_font_list_); |
| 242 label.SetShadows(label_->shadows()); | 246 label.SetShadows(label_->shadows()); |
| 243 | 247 |
| 244 if (style() == STYLE_BUTTON) { | 248 if (style_ == STYLE_BUTTON && PlatformStyle::kDefaultLabelButtonHasBoldFont) { |
| 245 // Some text appears wider when rendered normally than when rendered bold. | 249 // Some text appears wider when rendered normally than when rendered bold. |
| 246 // Accommodate the widest, as buttons may show bold and shouldn't resize. | 250 // Accommodate the widest, as buttons may show bold and shouldn't resize. |
| 247 const int current_width = label.GetPreferredSize().width(); | 251 const int current_width = label.GetPreferredSize().width(); |
| 248 label.SetFontList(cached_bold_font_list_); | 252 label.SetFontList(cached_bold_font_list_); |
| 249 if (label.GetPreferredSize().width() < current_width) | 253 if (label.GetPreferredSize().width() < current_width) |
| 250 label.SetFontList(cached_normal_font_list_); | 254 label.SetFontList(cached_normal_font_list_); |
| 251 } | 255 } |
| 252 | 256 |
| 253 // Calculate the required size. | 257 // Calculate the required size. |
| 254 const gfx::Size image_size(image_->GetPreferredSize()); | 258 const gfx::Size image_size(image_->GetPreferredSize()); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 | 393 |
| 390 void LabelButton::OnBlur() { | 394 void LabelButton::OnBlur() { |
| 391 CustomButton::OnBlur(); | 395 CustomButton::OnBlur(); |
| 392 // Typically the border renders differently when focused. | 396 // Typically the border renders differently when focused. |
| 393 SchedulePaint(); | 397 SchedulePaint(); |
| 394 } | 398 } |
| 395 | 399 |
| 396 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 400 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 397 ResetColorsFromNativeTheme(); | 401 ResetColorsFromNativeTheme(); |
| 398 UpdateThemedBorder(); | 402 UpdateThemedBorder(); |
| 403 ResetLabelEnabledColor(); |
| 399 // Invalidate the layout to pickup the new insets from the border. | 404 // Invalidate the layout to pickup the new insets from the border. |
| 400 InvalidateLayout(); | 405 InvalidateLayout(); |
| 401 } | 406 } |
| 402 | 407 |
| 403 void LabelButton::AddInkDropLayer(ui::Layer* ink_drop_layer) { | 408 void LabelButton::AddInkDropLayer(ui::Layer* ink_drop_layer) { |
| 404 image()->SetPaintToLayer(true); | 409 image()->SetPaintToLayer(true); |
| 405 image()->layer()->SetFillsBoundsOpaquely(false); | 410 image()->layer()->SetFillsBoundsOpaquely(false); |
| 406 ink_drop_container_->SetVisible(true); | 411 ink_drop_container_->SetVisible(true); |
| 407 ink_drop_container_->layer()->Add(ink_drop_layer); | 412 ink_drop_container_->layer()->Add(ink_drop_layer); |
| 408 } | 413 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 433 gfx::Point LabelButton::GetInkDropCenter() const { | 438 gfx::Point LabelButton::GetInkDropCenter() const { |
| 434 // TODO(bruthig): Make the flood fill ink drops centered on the LocatedEvent | 439 // TODO(bruthig): Make the flood fill ink drops centered on the LocatedEvent |
| 435 // that triggered them. | 440 // that triggered them. |
| 436 return GetText().empty() ? image()->GetMirroredBounds().CenterPoint() | 441 return GetText().empty() ? image()->GetMirroredBounds().CenterPoint() |
| 437 : CustomButton::GetInkDropCenter(); | 442 : CustomButton::GetInkDropCenter(); |
| 438 } | 443 } |
| 439 | 444 |
| 440 void LabelButton::StateChanged() { | 445 void LabelButton::StateChanged() { |
| 441 const gfx::Size previous_image_size(image_->GetPreferredSize()); | 446 const gfx::Size previous_image_size(image_->GetPreferredSize()); |
| 442 UpdateImage(); | 447 UpdateImage(); |
| 443 const SkColor color = button_state_colors_[state()]; | 448 ResetLabelEnabledColor(); |
| 444 if (state() != STATE_DISABLED && label_->enabled_color() != color) | |
| 445 label_->SetEnabledColor(color); | |
| 446 label_->SetEnabled(state() != STATE_DISABLED); | 449 label_->SetEnabled(state() != STATE_DISABLED); |
| 447 if (image_->GetPreferredSize() != previous_image_size) | 450 if (image_->GetPreferredSize() != previous_image_size) |
| 448 Layout(); | 451 Layout(); |
| 449 } | 452 } |
| 450 | 453 |
| 451 void LabelButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { | 454 void LabelButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { |
| 452 params->button.checked = false; | 455 params->button.checked = false; |
| 453 params->button.indeterminate = false; | 456 params->button.indeterminate = false; |
| 454 params->button.is_default = is_default_; | 457 params->button.is_default = is_default_; |
| 455 params->button.is_focused = HasFocus() && IsAccessibilityFocusable(); | 458 params->button.is_focused = HasFocus() && IsAccessibilityFocusable(); |
| 456 params->button.has_border = false; | 459 params->button.has_border = false; |
| 457 params->button.classic_state = 0; | 460 params->button.classic_state = 0; |
| 458 params->button.background_color = label_->background_color(); | 461 params->button.background_color = label_->background_color(); |
| 459 } | 462 } |
| 460 | 463 |
| 461 void LabelButton::ResetColorsFromNativeTheme() { | 464 void LabelButton::ResetColorsFromNativeTheme() { |
| 462 const ui::NativeTheme* theme = GetNativeTheme(); | 465 const ui::NativeTheme* theme = GetNativeTheme(); |
| 463 SkColor colors[STATE_COUNT] = { | 466 SkColor colors[STATE_COUNT] = { |
| 464 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonEnabledColor), | 467 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonEnabledColor), |
| 465 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor), | 468 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor), |
| 466 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor), | 469 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor), |
| 467 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor), | 470 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor), |
| 468 }; | 471 }; |
| 469 | 472 |
| 470 // Certain styles do not change text color when hovered or pressed. | |
| 471 bool constant_text_color = false; | |
| 472 // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON. | 473 // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON. |
| 473 if (color_utils::IsInvertedColorScheme()) { | 474 if (color_utils::IsInvertedColorScheme()) { |
| 474 constant_text_color = true; | 475 colors[STATE_NORMAL] = colors[STATE_HOVERED] = colors[STATE_PRESSED] = |
| 475 colors[STATE_NORMAL] = SK_ColorWHITE; | 476 SK_ColorWHITE; |
| 476 label_->SetBackgroundColor(SK_ColorBLACK); | 477 label_->SetBackgroundColor(SK_ColorBLACK); |
| 477 label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK)); | 478 label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK)); |
| 478 label_->SetAutoColorReadabilityEnabled(true); | 479 label_->SetAutoColorReadabilityEnabled(true); |
| 479 label_->SetShadows(gfx::ShadowValues()); | 480 label_->SetShadows(gfx::ShadowValues()); |
| 480 } else if (style() == STYLE_BUTTON) { | 481 } else if (style() == STYLE_BUTTON) { |
| 481 // TODO(erg): This is disabled on desktop linux because of the binary asset | 482 PlatformStyle::ApplyLabelButtonTextStyle(label_, &colors); |
| 482 // confusion. These details should either be pushed into ui::NativeThemeWin | 483 label_->set_background(nullptr); |
| 483 // or should be obsoleted by rendering buttons with paint calls instead of | |
| 484 // with static assets. http://crbug.com/350498 | |
| 485 #if !(defined(OS_LINUX) && !defined(OS_CHROMEOS)) | |
| 486 constant_text_color = true; | |
| 487 colors[STATE_NORMAL] = kStyleButtonTextColor; | |
| 488 label_->SetBackgroundColor(theme->GetSystemColor( | |
| 489 ui::NativeTheme::kColorId_ButtonBackgroundColor)); | |
| 490 label_->SetAutoColorReadabilityEnabled(false); | |
| 491 label_->SetShadows(gfx::ShadowValues( | |
| 492 1, gfx::ShadowValue(gfx::Vector2d(0, 1), 0, kStyleButtonShadowColor))); | |
| 493 #endif | |
| 494 label_->set_background(NULL); | |
| 495 } else { | 484 } else { |
| 496 label_->set_background(NULL); | 485 label_->set_background(nullptr); |
| 497 } | 486 } |
| 498 | 487 |
| 499 if (constant_text_color) | |
| 500 colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL]; | |
| 501 | |
| 502 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { | 488 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { |
| 503 if (!explicitly_set_colors_[state]) { | 489 if (!explicitly_set_colors_[state]) { |
| 504 SetTextColor(static_cast<ButtonState>(state), colors[state]); | 490 SetTextColor(static_cast<ButtonState>(state), colors[state]); |
| 505 explicitly_set_colors_[state] = false; | 491 explicitly_set_colors_[state] = false; |
| 506 } | 492 } |
| 507 } | 493 } |
| 508 } | 494 } |
| 509 | 495 |
| 510 void LabelButton::UpdateImage() { | 496 void LabelButton::UpdateImage() { |
| 511 image_->SetImage(GetImage(state())); | 497 image_->SetImage(GetImage(state())); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 ui::NativeTheme::ExtraParams* params) const { | 552 ui::NativeTheme::ExtraParams* params) const { |
| 567 GetExtraParams(params); | 553 GetExtraParams(params); |
| 568 return ui::NativeTheme::kHovered; | 554 return ui::NativeTheme::kHovered; |
| 569 } | 555 } |
| 570 | 556 |
| 571 void LabelButton::ResetCachedPreferredSize() { | 557 void LabelButton::ResetCachedPreferredSize() { |
| 572 cached_preferred_size_valid_ = false; | 558 cached_preferred_size_valid_ = false; |
| 573 cached_preferred_size_ = gfx::Size(); | 559 cached_preferred_size_ = gfx::Size(); |
| 574 } | 560 } |
| 575 | 561 |
| 562 void LabelButton::ResetLabelEnabledColor() { |
| 563 const SkColor color = |
| 564 explicitly_set_colors_[state()] |
| 565 ? button_state_colors_[state()] |
| 566 : PlatformStyle::TextColorForButton(button_state_colors_, *this); |
| 567 if (state() != STATE_DISABLED && label_->enabled_color() != color) |
| 568 label_->SetEnabledColor(color); |
| 569 } |
| 570 |
| 576 } // namespace views | 571 } // namespace views |
| OLD | NEW |