| 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/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
| 10 #include "ui/gfx/animation/throb_animation.h" | 10 #include "ui/gfx/animation/throb_animation.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { | 94 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { |
| 95 button_state_colors_[for_state] = color; | 95 button_state_colors_[for_state] = color; |
| 96 if (for_state == STATE_DISABLED) | 96 if (for_state == STATE_DISABLED) |
| 97 label_->SetDisabledColor(color); | 97 label_->SetDisabledColor(color); |
| 98 else if (for_state == state()) | 98 else if (for_state == state()) |
| 99 label_->SetEnabledColor(color); | 99 label_->SetEnabledColor(color); |
| 100 explicitly_set_colors_[for_state] = true; | 100 explicitly_set_colors_[for_state] = true; |
| 101 } | 101 } |
| 102 | 102 |
| 103 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) { | 103 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) { |
| 104 label_->set_shadows(shadows); | 104 label_->SetShadows(shadows); |
| 105 } | 105 } |
| 106 | 106 |
| 107 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { | 107 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { |
| 108 label_->set_subpixel_rendering_enabled(enabled); | 108 label_->SetSubpixelRenderingEnabled(enabled); |
| 109 } | 109 } |
| 110 | 110 |
| 111 bool LabelButton::GetTextMultiLine() const { | 111 bool LabelButton::GetTextMultiLine() const { |
| 112 return label_->is_multi_line(); | 112 return label_->multi_line(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 void LabelButton::SetTextMultiLine(bool text_multi_line) { | 115 void LabelButton::SetTextMultiLine(bool text_multi_line) { |
| 116 label_->SetMultiLine(text_multi_line); | 116 label_->SetMultiLine(text_multi_line); |
| 117 } | 117 } |
| 118 | 118 |
| 119 const gfx::FontList& LabelButton::GetFontList() const { | 119 const gfx::FontList& LabelButton::GetFontList() const { |
| 120 return label_->font_list(); | 120 return label_->font_list(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 void LabelButton::SetFontList(const gfx::FontList& font_list) { | 123 void LabelButton::SetFontList(const gfx::FontList& font_list) { |
| 124 cached_normal_font_list_ = font_list; | 124 cached_normal_font_list_ = font_list; |
| 125 cached_bold_font_list_ = font_list.DeriveWithStyle( | 125 cached_bold_font_list_ = font_list.DeriveWithStyle( |
| 126 font_list.GetFontStyle() | gfx::Font::BOLD); | 126 font_list.GetFontStyle() | gfx::Font::BOLD); |
| 127 | 127 |
| 128 // STYLE_BUTTON uses bold text to indicate default buttons. | 128 // STYLE_BUTTON uses bold text to indicate default buttons. |
| 129 label_->SetFontList( | 129 label_->SetFontList( |
| 130 style_ == STYLE_BUTTON && is_default_ ? | 130 style_ == STYLE_BUTTON && is_default_ ? |
| 131 cached_bold_font_list_ : cached_normal_font_list_); | 131 cached_bold_font_list_ : cached_normal_font_list_); |
| 132 } | 132 } |
| 133 | 133 |
| 134 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { | 134 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { |
| 135 label_->SetElideBehavior(elide_behavior); | 135 label_->SetElideBehavior(elide_behavior); |
| 136 } | 136 } |
| 137 | 137 |
| 138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { | 138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { |
| 139 return label_->GetHorizontalAlignment(); | 139 return label_->horizontal_alignment(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { | 142 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { |
| 143 label_->SetHorizontalAlignment(alignment); | 143 label_->SetHorizontalAlignment(alignment); |
| 144 InvalidateLayout(); | 144 InvalidateLayout(); |
| 145 } | 145 } |
| 146 | 146 |
| 147 void LabelButton::SetDirectionalityMode(gfx::DirectionalityMode mode) { | |
| 148 label_->set_directionality_mode(mode); | |
| 149 } | |
| 150 | |
| 151 void LabelButton::SetIsDefault(bool is_default) { | 147 void LabelButton::SetIsDefault(bool is_default) { |
| 152 if (is_default == is_default_) | 148 if (is_default == is_default_) |
| 153 return; | 149 return; |
| 154 is_default_ = is_default; | 150 is_default_ = is_default; |
| 155 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); | 151 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); |
| 156 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); | 152 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); |
| 157 | 153 |
| 158 // STYLE_BUTTON uses bold text to indicate default buttons. | 154 // STYLE_BUTTON uses bold text to indicate default buttons. |
| 159 if (style_ == STYLE_BUTTON) { | 155 if (style_ == STYLE_BUTTON) { |
| 160 label_->SetFontList( | 156 label_->SetFontList( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 181 OnNativeThemeChanged(GetNativeTheme()); | 177 OnNativeThemeChanged(GetNativeTheme()); |
| 182 } | 178 } |
| 183 | 179 |
| 184 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { | 180 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { |
| 185 focus_painter_ = focus_painter.Pass(); | 181 focus_painter_ = focus_painter.Pass(); |
| 186 } | 182 } |
| 187 | 183 |
| 188 gfx::Size LabelButton::GetPreferredSize() const { | 184 gfx::Size LabelButton::GetPreferredSize() const { |
| 189 // Use a temporary label copy for sizing to avoid calculation side-effects. | 185 // Use a temporary label copy for sizing to avoid calculation side-effects. |
| 190 Label label(GetText(), cached_normal_font_list_); | 186 Label label(GetText(), cached_normal_font_list_); |
| 191 label.set_shadows(label_->shadows()); | 187 label.SetShadows(label_->shadows()); |
| 192 label.SetMultiLine(GetTextMultiLine()); | 188 label.SetMultiLine(GetTextMultiLine()); |
| 193 | 189 |
| 194 if (style() == STYLE_BUTTON) { | 190 if (style() == STYLE_BUTTON) { |
| 195 // Some text appears wider when rendered normally than when rendered bold. | 191 // Some text appears wider when rendered normally than when rendered bold. |
| 196 // Accommodate the widest, as buttons may show bold and shouldn't resize. | 192 // Accommodate the widest, as buttons may show bold and shouldn't resize. |
| 197 const int current_width = label.GetPreferredSize().width(); | 193 const int current_width = label.GetPreferredSize().width(); |
| 198 label.SetFontList(cached_bold_font_list_); | 194 label.SetFontList(cached_bold_font_list_); |
| 199 if (label.GetPreferredSize().width() < current_width) | 195 if (label.GetPreferredSize().width() < current_width) |
| 200 label.SetFontList(cached_normal_font_list_); | 196 label.SetFontList(cached_normal_font_list_); |
| 201 } | 197 } |
| 202 | 198 |
| 203 // Resize multi-line labels given the current limited available width. | 199 // Calculate the required size. |
| 204 const gfx::Size image_size(image_->GetPreferredSize()); | 200 const gfx::Size image_size(image_->GetPreferredSize()); |
| 205 const int image_width = image_size.width(); | |
| 206 if (GetTextMultiLine() && (width() > image_width + kSpacing)) | |
| 207 label.SizeToFit(width() - image_width - (image_width > 0 ? kSpacing : 0)); | |
| 208 | |
| 209 // Calculate the required size. | |
| 210 gfx::Size size(label.GetPreferredSize()); | 201 gfx::Size size(label.GetPreferredSize()); |
| 211 if (image_width > 0 && size.width() > 0) | 202 if (image_size.width() > 0 && size.width() > 0) |
| 212 size.Enlarge(kSpacing, 0); | 203 size.Enlarge(kSpacing, 0); |
| 213 size.SetToMax(gfx::Size(0, image_size.height())); | 204 size.SetToMax(gfx::Size(0, image_size.height())); |
| 214 const gfx::Insets insets(GetInsets()); | 205 const gfx::Insets insets(GetInsets()); |
| 215 size.Enlarge(image_size.width() + insets.width(), insets.height()); | 206 size.Enlarge(image_size.width() + insets.width(), insets.height()); |
| 216 | 207 |
| 217 // Make the size at least as large as the minimum size needed by the border. | 208 // Make the size at least as large as the minimum size needed by the border. |
| 218 size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size()); | 209 size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size()); |
| 219 | 210 |
| 220 // Increase the minimum size monotonically with the preferred size. | 211 // Increase the minimum size monotonically with the preferred size. |
| 221 size.SetToMax(min_size_); | 212 size.SetToMax(min_size_); |
| 222 min_size_ = size; | 213 min_size_ = size; |
| 223 | 214 |
| 224 // Return the largest known size clamped to the maximum size (if valid). | 215 // Return the largest known size clamped to the maximum size (if valid). |
| 225 if (max_size_.width() > 0) | 216 if (max_size_.width() > 0) |
| 226 size.set_width(std::min(max_size_.width(), size.width())); | 217 size.set_width(std::min(max_size_.width(), size.width())); |
| 227 if (max_size_.height() > 0) | 218 if (max_size_.height() > 0) |
| 228 size.set_height(std::min(max_size_.height(), size.height())); | 219 size.set_height(std::min(max_size_.height(), size.height())); |
| 229 return size; | 220 return size; |
| 230 } | 221 } |
| 231 | 222 |
| 223 int LabelButton::GetHeightForWidth(int w) const { |
| 224 w -= GetInsets().width(); |
| 225 const gfx::Size image_size(image_->GetPreferredSize()); |
| 226 w -= image_size.width(); |
| 227 if (image_size.width() > 0 && !GetText().empty()) |
| 228 w -= kSpacing; |
| 229 |
| 230 int height = std::max(image_size.height(), label_->GetHeightForWidth(w)); |
| 231 if (border()) |
| 232 height = std::max(height, border()->GetMinimumSize().height()); |
| 233 |
| 234 height = std::max(height, min_size_.height()); |
| 235 if (max_size_.height() > 0) |
| 236 height = std::min(height, max_size_.height()); |
| 237 return height; |
| 238 } |
| 239 |
| 232 void LabelButton::Layout() { | 240 void LabelButton::Layout() { |
| 233 gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment(); | 241 gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment(); |
| 234 if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER) | 242 if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER) |
| 235 adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ? | 243 adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ? |
| 236 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; | 244 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; |
| 237 | 245 |
| 238 gfx::Rect child_area(GetChildAreaBounds()); | 246 gfx::Rect child_area(GetChildAreaBounds()); |
| 239 child_area.Inset(GetInsets()); | 247 child_area.Inset(GetInsets()); |
| 240 | 248 |
| 241 gfx::Size image_size(image_->GetPreferredSize()); | 249 gfx::Size image_size(image_->GetPreferredSize()); |
| 242 image_size.SetToMin(child_area.size()); | 250 image_size.SetToMin(child_area.size()); |
| 243 | 251 |
| 244 // The label takes any remaining width after sizing the image, unless both | 252 // The label takes any remaining width after sizing the image, unless both |
| 245 // views are centered. In that case, using the tighter preferred label width | 253 // views are centered. In that case, using the tighter preferred label width |
| 246 // avoids wasted space within the label that would look like awkward padding. | 254 // avoids wasted space within the label that would look like awkward padding. |
| 247 gfx::Size label_size(child_area.size()); | 255 gfx::Size label_size(child_area.size()); |
| 248 if (!image_size.IsEmpty() && !label_size.IsEmpty()) { | 256 if (!image_size.IsEmpty() && !label_size.IsEmpty()) { |
| 249 label_size.set_width( | 257 label_size.set_width( |
| 250 std::max(child_area.width() - image_size.width() - kSpacing, 0)); | 258 std::max(child_area.width() - image_size.width() - kSpacing, 0)); |
| 251 if (adjusted_alignment == gfx::ALIGN_CENTER) { | 259 if (adjusted_alignment == gfx::ALIGN_CENTER) { |
| 252 // Ensure multi-line labels paired with images use their available width. | 260 // Ensure multi-line labels paired with images use their available width. |
| 253 if (GetTextMultiLine()) | |
| 254 label_->SizeToFit(label_size.width()); | |
| 255 label_size.set_width( | 261 label_size.set_width( |
| 256 std::min(label_size.width(), label_->GetPreferredSize().width())); | 262 std::min(label_size.width(), label_->GetPreferredSize().width())); |
| 257 } | 263 } |
| 258 } | 264 } |
| 259 | 265 |
| 260 gfx::Point image_origin(child_area.origin()); | 266 gfx::Point image_origin(child_area.origin()); |
| 261 image_origin.Offset(0, (child_area.height() - image_size.height()) / 2); | 267 image_origin.Offset(0, (child_area.height() - image_size.height()) / 2); |
| 262 if (adjusted_alignment == gfx::ALIGN_CENTER) { | 268 if (adjusted_alignment == gfx::ALIGN_CENTER) { |
| 263 const int total_width = image_size.width() + label_size.width() + | 269 const int total_width = image_size.width() + label_size.width() + |
| 264 ((image_size.width() > 0 && label_size.width() > 0) ? kSpacing : 0); | 270 ((image_size.width() > 0 && label_size.width() > 0) ? kSpacing : 0); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 336 |
| 331 // Certain styles do not change text color when hovered or pressed. | 337 // Certain styles do not change text color when hovered or pressed. |
| 332 bool constant_text_color = false; | 338 bool constant_text_color = false; |
| 333 // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON. | 339 // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON. |
| 334 if (gfx::IsInvertedColorScheme()) { | 340 if (gfx::IsInvertedColorScheme()) { |
| 335 constant_text_color = true; | 341 constant_text_color = true; |
| 336 colors[STATE_NORMAL] = SK_ColorWHITE; | 342 colors[STATE_NORMAL] = SK_ColorWHITE; |
| 337 label_->SetBackgroundColor(SK_ColorBLACK); | 343 label_->SetBackgroundColor(SK_ColorBLACK); |
| 338 label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK)); | 344 label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK)); |
| 339 label_->SetAutoColorReadabilityEnabled(true); | 345 label_->SetAutoColorReadabilityEnabled(true); |
| 340 label_->set_shadows(gfx::ShadowValues()); | 346 label_->SetShadows(gfx::ShadowValues()); |
| 341 } else if (style() == STYLE_BUTTON) { | 347 } else if (style() == STYLE_BUTTON) { |
| 342 // TODO(erg): This is disabled on desktop linux because of the binary asset | 348 // TODO(erg): This is disabled on desktop linux because of the binary asset |
| 343 // confusion. These details should either be pushed into ui::NativeThemeWin | 349 // confusion. These details should either be pushed into ui::NativeThemeWin |
| 344 // or should be obsoleted by rendering buttons with paint calls instead of | 350 // or should be obsoleted by rendering buttons with paint calls instead of |
| 345 // with static assets. http://crbug.com/350498 | 351 // with static assets. http://crbug.com/350498 |
| 346 #if !(defined(OS_LINUX) && !defined(OS_CHROMEOS)) | 352 #if !(defined(OS_LINUX) && !defined(OS_CHROMEOS)) |
| 347 constant_text_color = true; | 353 constant_text_color = true; |
| 348 colors[STATE_NORMAL] = kStyleButtonTextColor; | 354 colors[STATE_NORMAL] = kStyleButtonTextColor; |
| 349 label_->SetBackgroundColor(theme->GetSystemColor( | 355 label_->SetBackgroundColor(theme->GetSystemColor( |
| 350 ui::NativeTheme::kColorId_ButtonBackgroundColor)); | 356 ui::NativeTheme::kColorId_ButtonBackgroundColor)); |
| 351 label_->SetAutoColorReadabilityEnabled(false); | 357 label_->SetAutoColorReadabilityEnabled(false); |
| 352 label_->set_shadows(gfx::ShadowValues(1, | 358 label_->SetShadows(gfx::ShadowValues( |
| 353 gfx::ShadowValue(gfx::Point(0, 1), 0, kStyleButtonShadowColor))); | 359 1, gfx::ShadowValue(gfx::Point(0, 1), 0, kStyleButtonShadowColor))); |
| 354 #endif | 360 #endif |
| 355 label_->set_background(NULL); | 361 label_->set_background(NULL); |
| 356 } else { | 362 } else { |
| 357 label_->set_background(NULL); | 363 label_->set_background(NULL); |
| 358 } | 364 } |
| 359 | 365 |
| 360 if (constant_text_color) | 366 if (constant_text_color) |
| 361 colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL]; | 367 colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL]; |
| 362 | 368 |
| 363 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { | 369 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 return ui::NativeTheme::kNormal; | 452 return ui::NativeTheme::kNormal; |
| 447 } | 453 } |
| 448 | 454 |
| 449 ui::NativeTheme::State LabelButton::GetForegroundThemeState( | 455 ui::NativeTheme::State LabelButton::GetForegroundThemeState( |
| 450 ui::NativeTheme::ExtraParams* params) const { | 456 ui::NativeTheme::ExtraParams* params) const { |
| 451 GetExtraParams(params); | 457 GetExtraParams(params); |
| 452 return ui::NativeTheme::kHovered; | 458 return ui::NativeTheme::kHovered; |
| 453 } | 459 } |
| 454 | 460 |
| 455 } // namespace views | 461 } // namespace views |
| OLD | NEW |