Chromium Code Reviews| 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
| 9 #include "ui/base/animation/throb_animation.h" | 9 #include "ui/base/animation/throb_animation.h" |
| 10 #include "ui/base/resource/resource_bundle.h" | 10 #include "ui/base/resource/resource_bundle.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 | 60 |
| 61 LabelButton::~LabelButton() {} | 61 LabelButton::~LabelButton() {} |
| 62 | 62 |
| 63 const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) { | 63 const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) { |
| 64 if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull()) | 64 if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull()) |
| 65 return button_state_images_[STATE_NORMAL]; | 65 return button_state_images_[STATE_NORMAL]; |
| 66 return button_state_images_[for_state]; | 66 return button_state_images_[for_state]; |
| 67 } | 67 } |
| 68 | 68 |
| 69 void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) { | 69 void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) { |
| 70 cached_size_.SetSize(0, 0); | |
| 70 button_state_images_[for_state] = image; | 71 button_state_images_[for_state] = image; |
| 71 image_->SetImage(GetImage(state())); | 72 image_->SetImage(GetImage(state())); |
| 72 } | 73 } |
| 73 | 74 |
| 74 const string16& LabelButton::GetText() const { | 75 const string16& LabelButton::GetText() const { |
| 75 return label_->text(); | 76 return label_->text(); |
| 76 } | 77 } |
| 77 | 78 |
| 78 void LabelButton::SetText(const string16& text) { | 79 void LabelButton::SetText(const string16& text) { |
| 80 cached_size_.SetSize(0, 0); | |
| 79 SetAccessibleName(text); | 81 SetAccessibleName(text); |
| 80 label_->SetText(text); | 82 label_->SetText(text); |
| 81 SetAccessibleName(text); | |
| 82 } | 83 } |
| 83 | 84 |
| 84 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { | 85 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { |
| 85 button_state_colors_[for_state] = color; | 86 button_state_colors_[for_state] = color; |
| 86 if (for_state == STATE_DISABLED) | 87 if (for_state == STATE_DISABLED) |
| 87 label_->SetDisabledColor(color); | 88 label_->SetDisabledColor(color); |
| 88 else if (for_state == state()) | 89 else if (for_state == state()) |
| 89 label_->SetEnabledColor(color); | 90 label_->SetEnabledColor(color); |
| 90 explicitly_set_colors_[for_state] = true; | 91 explicitly_set_colors_[for_state] = true; |
| 91 } | 92 } |
| 92 | 93 |
| 93 bool LabelButton::GetTextMultiLine() const { | 94 bool LabelButton::GetTextMultiLine() const { |
| 94 return label_->is_multi_line(); | 95 return label_->is_multi_line(); |
| 95 } | 96 } |
| 96 | 97 |
| 97 void LabelButton::SetTextMultiLine(bool text_multi_line) { | 98 void LabelButton::SetTextMultiLine(bool text_multi_line) { |
| 99 cached_size_.SetSize(0, 0); | |
| 98 label_->SetMultiLine(text_multi_line); | 100 label_->SetMultiLine(text_multi_line); |
| 99 } | 101 } |
| 100 | 102 |
| 101 const gfx::Font& LabelButton::GetFont() const { | 103 const gfx::Font& LabelButton::GetFont() const { |
| 102 return label_->font(); | 104 return label_->font(); |
| 103 } | 105 } |
| 104 | 106 |
| 105 void LabelButton::SetFont(const gfx::Font& font) { | 107 void LabelButton::SetFont(const gfx::Font& font) { |
| 108 cached_size_.SetSize(0, 0); | |
| 106 label_->SetFont(font); | 109 label_->SetFont(font); |
| 107 } | 110 } |
| 108 | 111 |
| 109 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { | 112 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { |
| 110 return label_->horizontal_alignment(); | 113 return label_->horizontal_alignment(); |
| 111 } | 114 } |
| 112 | 115 |
| 113 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { | 116 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { |
| 117 cached_size_.SetSize(0, 0); | |
| 114 label_->SetHorizontalAlignment(alignment); | 118 label_->SetHorizontalAlignment(alignment); |
| 115 InvalidateLayout(); | 119 InvalidateLayout(); |
| 116 } | 120 } |
| 117 | 121 |
| 118 void LabelButton::SetIsDefault(bool is_default) { | 122 void LabelButton::SetIsDefault(bool is_default) { |
| 119 if (is_default == is_default_) | 123 if (is_default == is_default_) |
| 120 return; | 124 return; |
| 121 is_default_ = is_default; | 125 is_default_ = is_default; |
| 122 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); | 126 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); |
| 123 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); | 127 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); |
| 124 | 128 |
| 125 // STYLE_BUTTON uses bold text to indicate default buttons. | 129 // STYLE_BUTTON uses bold text to indicate default buttons. |
| 126 if (style_ == STYLE_BUTTON) { | 130 if (style_ == STYLE_BUTTON) { |
| 127 int style = label_->font().GetStyle(); | 131 int style = label_->font().GetStyle(); |
| 128 style = is_default ? style | gfx::Font::BOLD : style & !gfx::Font::BOLD; | 132 style = is_default ? style | gfx::Font::BOLD : style & !gfx::Font::BOLD; |
| 129 label_->SetFont(label_->font().DeriveFont(0, style)); | 133 label_->SetFont(label_->font().DeriveFont(0, style)); |
| 130 } | 134 } |
| 131 } | 135 } |
| 132 | 136 |
| 133 void LabelButton::SetStyle(ButtonStyle style) { | 137 void LabelButton::SetStyle(ButtonStyle style) { |
| 138 cached_size_.SetSize(0, 0); | |
| 139 | |
| 134 // Use the new button style instead of the native button style. | 140 // Use the new button style instead of the native button style. |
| 135 // TODO(msw): Officialy deprecate and remove STYLE_NATIVE_TEXTBUTTON. | 141 // TODO(msw): Officialy deprecate and remove STYLE_NATIVE_TEXTBUTTON. |
| 136 if (DialogDelegate::UseNewStyle() && style == STYLE_NATIVE_TEXTBUTTON) | 142 if (DialogDelegate::UseNewStyle() && style == STYLE_NATIVE_TEXTBUTTON) |
| 137 style = STYLE_BUTTON; | 143 style = STYLE_BUTTON; |
| 138 | 144 |
| 139 style_ = style; | 145 style_ = style; |
| 140 set_border(new LabelButtonBorder(style)); | 146 set_border(new LabelButtonBorder(style)); |
| 141 // Inset the button focus rect from the actual border; roughly match Windows. | 147 // Inset the button focus rect from the actual border; roughly match Windows. |
| 142 set_focus_border(style == STYLE_BUTTON ? | 148 set_focus_border(style == STYLE_BUTTON ? |
| 143 NULL : FocusBorder::CreateDashedFocusBorder(3, 3, 3, 3)); | 149 NULL : FocusBorder::CreateDashedFocusBorder(3, 3, 3, 3)); |
| 144 if (style == STYLE_BUTTON || style == STYLE_NATIVE_TEXTBUTTON) { | 150 if (style == STYLE_BUTTON || style == STYLE_NATIVE_TEXTBUTTON) { |
| 145 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); | 151 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 146 set_focusable(true); | 152 set_focusable(true); |
| 147 } | 153 } |
| 148 if (style == STYLE_BUTTON) { | 154 if (style == STYLE_BUTTON) { |
| 149 set_min_size(gfx::Size(70, 31)); | 155 set_min_size(gfx::Size(70, 31)); |
| 150 const SkColor color = GetNativeTheme()->GetSystemColor( | 156 const SkColor color = GetNativeTheme()->GetSystemColor( |
| 151 ui::NativeTheme::kColorId_WindowBackground); | 157 ui::NativeTheme::kColorId_WindowBackground); |
| 152 label_->SetShadowColors(color, color); | 158 label_->SetShadowColors(color, color); |
| 153 label_->SetShadowOffset(0, 1); | 159 label_->SetShadowOffset(0, 1); |
| 154 } | 160 } |
| 155 // Invalidate the layout to pickup the new insets from the border. | 161 // Invalidate the layout to pickup the new insets from the border. |
| 156 InvalidateLayout(); | 162 InvalidateLayout(); |
| 157 ResetColorsFromNativeTheme(); | 163 ResetColorsFromNativeTheme(); |
| 158 } | 164 } |
| 159 | 165 |
| 160 gfx::Size LabelButton::GetPreferredSize() { | 166 gfx::Size LabelButton::GetPreferredSize() { |
| 161 // Accommodate bold text in case this STYLE_BUTTON button is made default. | 167 if (cached_size_.IsEmpty()) { |
| 162 const gfx::Font font = label_->font(); | 168 gfx::Font font = label_->font(); |
| 163 if (style_ == STYLE_BUTTON) | 169 // Accommodate bold text in case this STYLE_BUTTON button is made default. |
| 164 label_->SetFont(font.DeriveFont(0, font.GetStyle() | gfx::Font::BOLD)); | 170 if (style_ == STYLE_BUTTON) |
| 171 font = font.DeriveFont(0, font.GetStyle() | gfx::Font::BOLD); | |
| 172 // Use a temporary label copy for sizing to avoid calculation side-effects. | |
| 173 Label label(label_->text(), font); | |
| 165 | 174 |
| 166 // Resize multi-line labels paired with images to use their available width. | 175 // Resize multi-line labels paired with images to use their available width. |
| 167 const gfx::Size image_size(image_->GetPreferredSize()); | 176 const gfx::Size image_size(image_->GetPreferredSize()); |
| 168 if (GetTextMultiLine() && !image_size.IsEmpty() && !GetText().empty() && | 177 if (GetTextMultiLine() && !image_size.IsEmpty() && !GetText().empty() && |
| 169 GetHorizontalAlignment() == gfx::ALIGN_CENTER) { | 178 GetHorizontalAlignment() == gfx::ALIGN_CENTER) { |
| 170 label_->SizeToFit(GetLocalBounds().width() - image_size.width() - kSpacing); | 179 label.SizeToFit(GetLocalBounds().width() - image_size.width() - kSpacing); |
| 180 } | |
| 181 | |
| 182 // Calculate the required size. | |
| 183 cached_size_ = label.GetPreferredSize(); | |
| 184 if (image_size.width() > 0 && cached_size_.width() > 0) | |
| 185 cached_size_.Enlarge(kSpacing, 0); | |
| 186 cached_size_.ClampToMin(gfx::Size(0, image_size.height())); | |
| 187 cached_size_.Enlarge(image_size.width(), 0); | |
| 188 cached_size_.Enlarge(GetInsets().width(), GetInsets().height()); | |
| 171 } | 189 } |
| 172 | 190 |
| 173 // Calculate the required size. | |
| 174 gfx::Size size(label_->GetPreferredSize()); | |
| 175 if (image_size.width() > 0 && size.width() > 0) | |
| 176 size.Enlarge(kSpacing, 0); | |
| 177 size.set_height(std::max(size.height(), image_size.height())); | |
| 178 size.Enlarge(image_size.width() + GetInsets().width(), GetInsets().height()); | |
| 179 | |
| 180 // Restore the label's original font without the temporary bold style. | |
| 181 if (style_ == STYLE_BUTTON) | |
| 182 label_->SetFont(font); | |
| 183 | |
| 184 // Increase the minimum size monotonically with the preferred size. | 191 // Increase the minimum size monotonically with the preferred size. |
| 185 size.SetSize(std::max(min_size_.width(), size.width()), | 192 gfx::Size size(cached_size_); |
| 186 std::max(min_size_.height(), size.height())); | 193 size.ClampToMin(min_size_); |
|
Mike Wittman
2013/05/11 04:35:58
Should this be ClampToMax?
msw
2013/05/11 04:40:26
No, I think it's correct as-is (this will ensure t
| |
| 187 min_size_ = size; | 194 min_size_ = size; |
| 188 | 195 |
| 189 // Return the largest known size clamped to the maximum size (if valid). | 196 // Return the largest known size clamped to the maximum size (if valid). |
| 190 if (max_size_.width() > 0) | 197 if (max_size_.width() > 0) |
| 191 size.set_width(std::min(max_size_.width(), size.width())); | 198 size.set_width(std::min(max_size_.width(), size.width())); |
| 192 if (max_size_.height() > 0) | 199 if (max_size_.height() > 0) |
| 193 size.set_height(std::min(max_size_.height(), size.height())); | 200 size.set_height(std::min(max_size_.height(), size.height())); |
| 194 return size; | 201 return size; |
| 195 } | 202 } |
| 196 | 203 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 | 278 |
| 272 gfx::Point label_origin(child_area.origin()); | 279 gfx::Point label_origin(child_area.origin()); |
| 273 if (!image_size.IsEmpty() && GetHorizontalAlignment() != gfx::ALIGN_RIGHT) | 280 if (!image_size.IsEmpty() && GetHorizontalAlignment() != gfx::ALIGN_RIGHT) |
| 274 label_origin.set_x(image_origin.x() + image_size.width() + kSpacing); | 281 label_origin.set_x(image_origin.x() + image_size.width() + kSpacing); |
| 275 | 282 |
| 276 image_->SetBoundsRect(gfx::Rect(image_origin, image_size)); | 283 image_->SetBoundsRect(gfx::Rect(image_origin, image_size)); |
| 277 label_->SetBoundsRect(gfx::Rect(label_origin, label_size)); | 284 label_->SetBoundsRect(gfx::Rect(label_origin, label_size)); |
| 278 } | 285 } |
| 279 | 286 |
| 280 void LabelButton::ChildPreferredSizeChanged(View* child) { | 287 void LabelButton::ChildPreferredSizeChanged(View* child) { |
| 288 cached_size_.SetSize(0, 0); | |
| 281 PreferredSizeChanged(); | 289 PreferredSizeChanged(); |
| 282 } | 290 } |
| 283 | 291 |
| 284 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 292 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 285 ResetColorsFromNativeTheme(); | 293 ResetColorsFromNativeTheme(); |
| 286 } | 294 } |
| 287 | 295 |
| 288 ui::NativeTheme::Part LabelButton::GetThemePart() const { | 296 ui::NativeTheme::Part LabelButton::GetThemePart() const { |
| 289 return ui::NativeTheme::kPushButton; | 297 return ui::NativeTheme::kPushButton; |
| 290 } | 298 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 params->button.indeterminate = false; | 342 params->button.indeterminate = false; |
| 335 params->button.is_default = is_default_; | 343 params->button.is_default = is_default_; |
| 336 params->button.is_focused = HasFocus() && IsAccessibilityFocusable(); | 344 params->button.is_focused = HasFocus() && IsAccessibilityFocusable(); |
| 337 params->button.has_border = style() == STYLE_NATIVE_TEXTBUTTON; | 345 params->button.has_border = style() == STYLE_NATIVE_TEXTBUTTON; |
| 338 params->button.classic_state = 0; | 346 params->button.classic_state = 0; |
| 339 params->button.background_color = GetNativeTheme()->GetSystemColor( | 347 params->button.background_color = GetNativeTheme()->GetSystemColor( |
| 340 ui::NativeTheme::kColorId_TextButtonBackgroundColor); | 348 ui::NativeTheme::kColorId_TextButtonBackgroundColor); |
| 341 } | 349 } |
| 342 | 350 |
| 343 } // namespace views | 351 } // namespace views |
| OLD | NEW |