| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { | 138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { |
| 139 return label_->GetHorizontalAlignment(); | 139 return label_->GetHorizontalAlignment(); |
| 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::SetMinSize(const gfx::Size& min_size) { |
| 148 min_size_ = min_size; |
| 149 ResetCachedPreferredSize(); |
| 150 } |
| 151 |
| 152 void LabelButton::SetMaxSize(const gfx::Size& max_size) { |
| 153 max_size_ = max_size; |
| 154 ResetCachedPreferredSize(); |
| 155 } |
| 156 |
| 147 void LabelButton::SetIsDefault(bool is_default) { | 157 void LabelButton::SetIsDefault(bool is_default) { |
| 148 if (is_default == is_default_) | 158 if (is_default == is_default_) |
| 149 return; | 159 return; |
| 150 is_default_ = is_default; | 160 is_default_ = is_default; |
| 151 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); | 161 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); |
| 152 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); | 162 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); |
| 153 | 163 |
| 154 // STYLE_BUTTON uses bold text to indicate default buttons. | 164 // STYLE_BUTTON uses bold text to indicate default buttons. |
| 155 if (style_ == STYLE_BUTTON) { | 165 if (style_ == STYLE_BUTTON) { |
| 156 label_->SetFontList( | 166 label_->SetFontList( |
| 157 is_default ? cached_bold_font_list_ : cached_normal_font_list_); | 167 is_default ? cached_bold_font_list_ : cached_normal_font_list_); |
| 158 } | 168 } |
| 159 } | 169 } |
| 160 | 170 |
| 161 void LabelButton::SetStyle(ButtonStyle style) { | 171 void LabelButton::SetStyle(ButtonStyle style) { |
| 162 style_ = style; | 172 style_ = style; |
| 163 // Inset the button focus rect from the actual border; roughly match Windows. | 173 // Inset the button focus rect from the actual border; roughly match Windows. |
| 164 if (style == STYLE_BUTTON) { | 174 if (style == STYLE_BUTTON) { |
| 165 SetFocusPainter(scoped_ptr<Painter>()); | 175 SetFocusPainter(scoped_ptr<Painter>()); |
| 166 } else { | 176 } else { |
| 167 SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( | 177 SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( |
| 168 gfx::Insets(3, 3, 3, 3))); | 178 gfx::Insets(3, 3, 3, 3))); |
| 169 } | 179 } |
| 170 if (style == STYLE_BUTTON) { | 180 if (style == STYLE_BUTTON) { |
| 171 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); | 181 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 172 SetFocusable(true); | 182 SetFocusable(true); |
| 173 } | 183 } |
| 174 if (style == STYLE_BUTTON) | 184 if (style == STYLE_BUTTON) |
| 175 set_min_size(gfx::Size(70, 33)); | 185 SetMinSize(gfx::Size(70, 33)); |
| 176 | |
| 177 OnNativeThemeChanged(GetNativeTheme()); | 186 OnNativeThemeChanged(GetNativeTheme()); |
| 187 ResetCachedPreferredSize(); |
| 178 } | 188 } |
| 179 | 189 |
| 180 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { | 190 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { |
| 181 focus_painter_ = focus_painter.Pass(); | 191 focus_painter_ = focus_painter.Pass(); |
| 182 } | 192 } |
| 183 | 193 |
| 184 gfx::Size LabelButton::GetPreferredSize() const { | 194 gfx::Size LabelButton::GetPreferredSize() const { |
| 195 if (cached_preferred_size_valid_) |
| 196 return cached_preferred_size_; |
| 197 |
| 185 // Use a temporary label copy for sizing to avoid calculation side-effects. | 198 // Use a temporary label copy for sizing to avoid calculation side-effects. |
| 186 Label label(GetText(), cached_normal_font_list_); | 199 Label label(GetText(), cached_normal_font_list_); |
| 187 label.SetShadows(label_->shadows()); | 200 label.SetShadows(label_->shadows()); |
| 188 label.SetMultiLine(GetTextMultiLine()); | 201 label.SetMultiLine(GetTextMultiLine()); |
| 189 | 202 |
| 190 if (style() == STYLE_BUTTON) { | 203 if (style() == STYLE_BUTTON) { |
| 191 // Some text appears wider when rendered normally than when rendered bold. | 204 // Some text appears wider when rendered normally than when rendered bold. |
| 192 // Accommodate the widest, as buttons may show bold and shouldn't resize. | 205 // Accommodate the widest, as buttons may show bold and shouldn't resize. |
| 193 const int current_width = label.GetPreferredSize().width(); | 206 const int current_width = label.GetPreferredSize().width(); |
| 194 label.SetFontList(cached_bold_font_list_); | 207 label.SetFontList(cached_bold_font_list_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 210 | 223 |
| 211 // Increase the minimum size monotonically with the preferred size. | 224 // Increase the minimum size monotonically with the preferred size. |
| 212 size.SetToMax(min_size_); | 225 size.SetToMax(min_size_); |
| 213 min_size_ = size; | 226 min_size_ = size; |
| 214 | 227 |
| 215 // Return the largest known size clamped to the maximum size (if valid). | 228 // Return the largest known size clamped to the maximum size (if valid). |
| 216 if (max_size_.width() > 0) | 229 if (max_size_.width() > 0) |
| 217 size.set_width(std::min(max_size_.width(), size.width())); | 230 size.set_width(std::min(max_size_.width(), size.width())); |
| 218 if (max_size_.height() > 0) | 231 if (max_size_.height() > 0) |
| 219 size.set_height(std::min(max_size_.height(), size.height())); | 232 size.set_height(std::min(max_size_.height(), size.height())); |
| 220 return size; | 233 |
| 234 // Cache this computed size, as recomputing it is an expensive operation. |
| 235 cached_preferred_size_valid_ = true; |
| 236 cached_preferred_size_ = size; |
| 237 return cached_preferred_size_; |
| 221 } | 238 } |
| 222 | 239 |
| 223 int LabelButton::GetHeightForWidth(int w) const { | 240 int LabelButton::GetHeightForWidth(int w) const { |
| 224 w -= GetInsets().width(); | 241 w -= GetInsets().width(); |
| 225 const gfx::Size image_size(image_->GetPreferredSize()); | 242 const gfx::Size image_size(image_->GetPreferredSize()); |
| 226 w -= image_size.width(); | 243 w -= image_size.width(); |
| 227 if (image_size.width() > 0 && !GetText().empty()) | 244 if (image_size.width() > 0 && !GetText().empty()) |
| 228 w -= kSpacing; | 245 w -= kSpacing; |
| 229 | 246 |
| 230 int height = std::max(image_size.height(), label_->GetHeightForWidth(w)); | 247 int height = std::max(image_size.height(), label_->GetHeightForWidth(w)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 return kViewClassName; | 302 return kViewClassName; |
| 286 } | 303 } |
| 287 | 304 |
| 288 scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const { | 305 scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const { |
| 289 return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_)); | 306 return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_)); |
| 290 } | 307 } |
| 291 | 308 |
| 292 void LabelButton::SetBorder(scoped_ptr<Border> border) { | 309 void LabelButton::SetBorder(scoped_ptr<Border> border) { |
| 293 border_is_themed_border_ = false; | 310 border_is_themed_border_ = false; |
| 294 View::SetBorder(border.Pass()); | 311 View::SetBorder(border.Pass()); |
| 312 ResetCachedPreferredSize(); |
| 295 } | 313 } |
| 296 | 314 |
| 297 gfx::Rect LabelButton::GetChildAreaBounds() { | 315 gfx::Rect LabelButton::GetChildAreaBounds() { |
| 298 return GetLocalBounds(); | 316 return GetLocalBounds(); |
| 299 } | 317 } |
| 300 | 318 |
| 301 void LabelButton::OnPaint(gfx::Canvas* canvas) { | 319 void LabelButton::OnPaint(gfx::Canvas* canvas) { |
| 302 View::OnPaint(canvas); | 320 View::OnPaint(canvas); |
| 303 Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); | 321 Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); |
| 304 } | 322 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { | 387 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { |
| 370 if (!explicitly_set_colors_[state]) { | 388 if (!explicitly_set_colors_[state]) { |
| 371 SetTextColor(static_cast<ButtonState>(state), colors[state]); | 389 SetTextColor(static_cast<ButtonState>(state), colors[state]); |
| 372 explicitly_set_colors_[state] = false; | 390 explicitly_set_colors_[state] = false; |
| 373 } | 391 } |
| 374 } | 392 } |
| 375 } | 393 } |
| 376 | 394 |
| 377 void LabelButton::UpdateImage() { | 395 void LabelButton::UpdateImage() { |
| 378 image_->SetImage(GetImage(state())); | 396 image_->SetImage(GetImage(state())); |
| 397 ResetCachedPreferredSize(); |
| 379 } | 398 } |
| 380 | 399 |
| 381 void LabelButton::UpdateThemedBorder() { | 400 void LabelButton::UpdateThemedBorder() { |
| 382 // Don't override borders set by others. | 401 // Don't override borders set by others. |
| 383 if (!border_is_themed_border_) | 402 if (!border_is_themed_border_) |
| 384 return; | 403 return; |
| 385 | 404 |
| 386 scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder(); | 405 scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder(); |
| 387 | 406 |
| 388 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 407 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 404 UpdateImage(); | 423 UpdateImage(); |
| 405 const SkColor color = button_state_colors_[state()]; | 424 const SkColor color = button_state_colors_[state()]; |
| 406 if (state() != STATE_DISABLED && label_->enabled_color() != color) | 425 if (state() != STATE_DISABLED && label_->enabled_color() != color) |
| 407 label_->SetEnabledColor(color); | 426 label_->SetEnabledColor(color); |
| 408 label_->SetEnabled(state() != STATE_DISABLED); | 427 label_->SetEnabled(state() != STATE_DISABLED); |
| 409 if (image_->GetPreferredSize() != previous_image_size) | 428 if (image_->GetPreferredSize() != previous_image_size) |
| 410 Layout(); | 429 Layout(); |
| 411 } | 430 } |
| 412 | 431 |
| 413 void LabelButton::ChildPreferredSizeChanged(View* child) { | 432 void LabelButton::ChildPreferredSizeChanged(View* child) { |
| 433 ResetCachedPreferredSize(); |
| 414 PreferredSizeChanged(); | 434 PreferredSizeChanged(); |
| 415 } | 435 } |
| 416 | 436 |
| 417 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 437 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 418 ResetColorsFromNativeTheme(); | 438 ResetColorsFromNativeTheme(); |
| 419 UpdateThemedBorder(); | 439 UpdateThemedBorder(); |
| 420 // Invalidate the layout to pickup the new insets from the border. | 440 // Invalidate the layout to pickup the new insets from the border. |
| 421 InvalidateLayout(); | 441 InvalidateLayout(); |
| 422 } | 442 } |
| 423 | 443 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 451 GetExtraParams(params); | 471 GetExtraParams(params); |
| 452 return ui::NativeTheme::kNormal; | 472 return ui::NativeTheme::kNormal; |
| 453 } | 473 } |
| 454 | 474 |
| 455 ui::NativeTheme::State LabelButton::GetForegroundThemeState( | 475 ui::NativeTheme::State LabelButton::GetForegroundThemeState( |
| 456 ui::NativeTheme::ExtraParams* params) const { | 476 ui::NativeTheme::ExtraParams* params) const { |
| 457 GetExtraParams(params); | 477 GetExtraParams(params); |
| 458 return ui::NativeTheme::kHovered; | 478 return ui::NativeTheme::kHovered; |
| 459 } | 479 } |
| 460 | 480 |
| 481 void LabelButton::ResetCachedPreferredSize() { |
| 482 cached_preferred_size_valid_ = false; |
| 483 cached_preferred_size_= gfx::Size(); |
| 484 } |
| 485 |
| 461 } // namespace views | 486 } // namespace views |
| OLD | NEW |