Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: ui/views/controls/button/label_button.cc

Issue 371633002: LabelButton: cache the last computed preferred size (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: msw comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 UpdateImage(); 82 UpdateImage();
83 } 83 }
84 84
85 const base::string16& LabelButton::GetText() const { 85 const base::string16& LabelButton::GetText() const {
86 return label_->text(); 86 return label_->text();
87 } 87 }
88 88
89 void LabelButton::SetText(const base::string16& text) { 89 void LabelButton::SetText(const base::string16& text) {
90 SetAccessibleName(text); 90 SetAccessibleName(text);
91 label_->SetText(text); 91 label_->SetText(text);
92 ResetCachedSize();
92 } 93 }
93 94
94 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { 95 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) {
95 button_state_colors_[for_state] = color; 96 button_state_colors_[for_state] = color;
96 if (for_state == STATE_DISABLED) 97 if (for_state == STATE_DISABLED)
97 label_->SetDisabledColor(color); 98 label_->SetDisabledColor(color);
98 else if (for_state == state()) 99 else if (for_state == state())
99 label_->SetEnabledColor(color); 100 label_->SetEnabledColor(color);
100 explicitly_set_colors_[for_state] = true; 101 explicitly_set_colors_[for_state] = true;
101 } 102 }
102 103
103 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) { 104 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) {
104 label_->SetShadows(shadows); 105 label_->SetShadows(shadows);
105 } 106 }
106 107
107 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { 108 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) {
108 label_->SetSubpixelRenderingEnabled(enabled); 109 label_->SetSubpixelRenderingEnabled(enabled);
109 } 110 }
110 111
111 bool LabelButton::GetTextMultiLine() const { 112 bool LabelButton::GetTextMultiLine() const {
112 return label_->multi_line(); 113 return label_->multi_line();
113 } 114 }
114 115
115 void LabelButton::SetTextMultiLine(bool text_multi_line) { 116 void LabelButton::SetTextMultiLine(bool text_multi_line) {
116 label_->SetMultiLine(text_multi_line); 117 label_->SetMultiLine(text_multi_line);
118 ResetCachedSize();
117 } 119 }
118 120
119 const gfx::FontList& LabelButton::GetFontList() const { 121 const gfx::FontList& LabelButton::GetFontList() const {
120 return label_->font_list(); 122 return label_->font_list();
121 } 123 }
122 124
123 void LabelButton::SetFontList(const gfx::FontList& font_list) { 125 void LabelButton::SetFontList(const gfx::FontList& font_list) {
124 cached_normal_font_list_ = font_list; 126 cached_normal_font_list_ = font_list;
125 cached_bold_font_list_ = font_list.DeriveWithStyle( 127 cached_bold_font_list_ = font_list.DeriveWithStyle(
126 font_list.GetFontStyle() | gfx::Font::BOLD); 128 font_list.GetFontStyle() | gfx::Font::BOLD);
127 129
128 // STYLE_BUTTON uses bold text to indicate default buttons. 130 // STYLE_BUTTON uses bold text to indicate default buttons.
129 label_->SetFontList( 131 label_->SetFontList(
130 style_ == STYLE_BUTTON && is_default_ ? 132 style_ == STYLE_BUTTON && is_default_ ?
131 cached_bold_font_list_ : cached_normal_font_list_); 133 cached_bold_font_list_ : cached_normal_font_list_);
134 ResetCachedSize();
132 } 135 }
133 136
134 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { 137 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
135 label_->SetElideBehavior(elide_behavior); 138 label_->SetElideBehavior(elide_behavior);
139 ResetCachedSize();
136 } 140 }
137 141
138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { 142 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const {
139 return label_->GetHorizontalAlignment(); 143 return label_->GetHorizontalAlignment();
140 } 144 }
141 145
142 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { 146 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
143 label_->SetHorizontalAlignment(alignment); 147 label_->SetHorizontalAlignment(alignment);
148 ResetCachedSize();
144 InvalidateLayout(); 149 InvalidateLayout();
145 } 150 }
146 151
147 void LabelButton::SetIsDefault(bool is_default) { 152 void LabelButton::SetIsDefault(bool is_default) {
148 if (is_default == is_default_) 153 if (is_default == is_default_)
149 return; 154 return;
150 is_default_ = is_default; 155 is_default_ = is_default;
151 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE); 156 ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE);
152 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel); 157 is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel);
153 158
(...skipping 12 matching lines...) Expand all
166 } else { 171 } else {
167 SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( 172 SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets(
168 gfx::Insets(3, 3, 3, 3))); 173 gfx::Insets(3, 3, 3, 3)));
169 } 174 }
170 if (style == STYLE_BUTTON) { 175 if (style == STYLE_BUTTON) {
171 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); 176 label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
172 SetFocusable(true); 177 SetFocusable(true);
173 } 178 }
174 if (style == STYLE_BUTTON) 179 if (style == STYLE_BUTTON)
175 set_min_size(gfx::Size(70, 33)); 180 set_min_size(gfx::Size(70, 33));
176 181 ResetCachedSize();
msw 2014/07/21 16:28:26 Call this after OnNativeThemeChanged.
noms (inactive) 2014/07/21 17:18:51 Done.
177 OnNativeThemeChanged(GetNativeTheme()); 182 OnNativeThemeChanged(GetNativeTheme());
178 } 183 }
179 184
180 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { 185 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
181 focus_painter_ = focus_painter.Pass(); 186 focus_painter_ = focus_painter.Pass();
182 } 187 }
183 188
184 gfx::Size LabelButton::GetPreferredSize() const { 189 gfx::Size LabelButton::GetPreferredSize() const {
190 if (button_size_valid_)
191 return button_size_;
192
185 // Use a temporary label copy for sizing to avoid calculation side-effects. 193 // Use a temporary label copy for sizing to avoid calculation side-effects.
186 Label label(GetText(), cached_normal_font_list_); 194 Label label(GetText(), cached_normal_font_list_);
187 label.SetShadows(label_->shadows()); 195 label.SetShadows(label_->shadows());
188 label.SetMultiLine(GetTextMultiLine()); 196 label.SetMultiLine(GetTextMultiLine());
189 197
190 if (style() == STYLE_BUTTON) { 198 if (style() == STYLE_BUTTON) {
191 // Some text appears wider when rendered normally than when rendered bold. 199 // Some text appears wider when rendered normally than when rendered bold.
192 // Accommodate the widest, as buttons may show bold and shouldn't resize. 200 // Accommodate the widest, as buttons may show bold and shouldn't resize.
193 const int current_width = label.GetPreferredSize().width(); 201 const int current_width = label.GetPreferredSize().width();
194 label.SetFontList(cached_bold_font_list_); 202 label.SetFontList(cached_bold_font_list_);
(...skipping 15 matching lines...) Expand all
210 218
211 // Increase the minimum size monotonically with the preferred size. 219 // Increase the minimum size monotonically with the preferred size.
212 size.SetToMax(min_size_); 220 size.SetToMax(min_size_);
213 min_size_ = size; 221 min_size_ = size;
214 222
215 // Return the largest known size clamped to the maximum size (if valid). 223 // Return the largest known size clamped to the maximum size (if valid).
216 if (max_size_.width() > 0) 224 if (max_size_.width() > 0)
217 size.set_width(std::min(max_size_.width(), size.width())); 225 size.set_width(std::min(max_size_.width(), size.width()));
218 if (max_size_.height() > 0) 226 if (max_size_.height() > 0)
219 size.set_height(std::min(max_size_.height(), size.height())); 227 size.set_height(std::min(max_size_.height(), size.height()));
220 return size; 228
229 // Cache this computed size, as recomputing it is an expensive operation.
230 button_size_valid_ = true;
231 button_size_ = size;
232 return button_size_;
221 } 233 }
222 234
223 int LabelButton::GetHeightForWidth(int w) const { 235 int LabelButton::GetHeightForWidth(int w) const {
224 w -= GetInsets().width(); 236 w -= GetInsets().width();
225 const gfx::Size image_size(image_->GetPreferredSize()); 237 const gfx::Size image_size(image_->GetPreferredSize());
226 w -= image_size.width(); 238 w -= image_size.width();
227 if (image_size.width() > 0 && !GetText().empty()) 239 if (image_size.width() > 0 && !GetText().empty())
228 w -= kSpacing; 240 w -= kSpacing;
229 241
230 int height = std::max(image_size.height(), label_->GetHeightForWidth(w)); 242 int height = std::max(image_size.height(), label_->GetHeightForWidth(w));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 return kViewClassName; 297 return kViewClassName;
286 } 298 }
287 299
288 scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const { 300 scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const {
289 return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_)); 301 return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_));
290 } 302 }
291 303
292 void LabelButton::SetBorder(scoped_ptr<Border> border) { 304 void LabelButton::SetBorder(scoped_ptr<Border> border) {
293 border_is_themed_border_ = false; 305 border_is_themed_border_ = false;
294 View::SetBorder(border.Pass()); 306 View::SetBorder(border.Pass());
307 ResetCachedSize();
295 } 308 }
296 309
297 gfx::Rect LabelButton::GetChildAreaBounds() { 310 gfx::Rect LabelButton::GetChildAreaBounds() {
298 return GetLocalBounds(); 311 return GetLocalBounds();
299 } 312 }
300 313
301 void LabelButton::OnPaint(gfx::Canvas* canvas) { 314 void LabelButton::OnPaint(gfx::Canvas* canvas) {
302 View::OnPaint(canvas); 315 View::OnPaint(canvas);
303 Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); 316 Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
304 } 317 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL]; 380 colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL];
368 381
369 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) { 382 for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) {
370 if (!explicitly_set_colors_[state]) { 383 if (!explicitly_set_colors_[state]) {
371 SetTextColor(static_cast<ButtonState>(state), colors[state]); 384 SetTextColor(static_cast<ButtonState>(state), colors[state]);
372 explicitly_set_colors_[state] = false; 385 explicitly_set_colors_[state] = false;
373 } 386 }
374 } 387 }
375 } 388 }
376 389
377 void LabelButton::UpdateImage() { 390 void LabelButton::UpdateImage() {
msw 2014/07/21 16:28:26 Contrary to my earlier comment, ResetCachedSize()
noms (inactive) 2014/07/21 17:18:51 Done.
378 image_->SetImage(GetImage(state())); 391 image_->SetImage(GetImage(state()));
379 } 392 }
380 393
381 void LabelButton::UpdateThemedBorder() { 394 void LabelButton::UpdateThemedBorder() {
382 // Don't override borders set by others. 395 // Don't override borders set by others.
383 if (!border_is_themed_border_) 396 if (!border_is_themed_border_)
384 return; 397 return;
385 398
386 scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder(); 399 scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder();
387 400
(...skipping 16 matching lines...) Expand all
404 UpdateImage(); 417 UpdateImage();
405 const SkColor color = button_state_colors_[state()]; 418 const SkColor color = button_state_colors_[state()];
406 if (state() != STATE_DISABLED && label_->enabled_color() != color) 419 if (state() != STATE_DISABLED && label_->enabled_color() != color)
407 label_->SetEnabledColor(color); 420 label_->SetEnabledColor(color);
408 label_->SetEnabled(state() != STATE_DISABLED); 421 label_->SetEnabled(state() != STATE_DISABLED);
409 if (image_->GetPreferredSize() != previous_image_size) 422 if (image_->GetPreferredSize() != previous_image_size)
410 Layout(); 423 Layout();
411 } 424 }
412 425
413 void LabelButton::ChildPreferredSizeChanged(View* child) { 426 void LabelButton::ChildPreferredSizeChanged(View* child) {
427 ResetCachedSize();
414 PreferredSizeChanged(); 428 PreferredSizeChanged();
415 } 429 }
416 430
417 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { 431 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
418 ResetColorsFromNativeTheme(); 432 ResetColorsFromNativeTheme();
419 UpdateThemedBorder(); 433 UpdateThemedBorder();
420 // Invalidate the layout to pickup the new insets from the border. 434 // Invalidate the layout to pickup the new insets from the border.
421 InvalidateLayout(); 435 InvalidateLayout();
422 } 436 }
423 437
(...skipping 27 matching lines...) Expand all
451 GetExtraParams(params); 465 GetExtraParams(params);
452 return ui::NativeTheme::kNormal; 466 return ui::NativeTheme::kNormal;
453 } 467 }
454 468
455 ui::NativeTheme::State LabelButton::GetForegroundThemeState( 469 ui::NativeTheme::State LabelButton::GetForegroundThemeState(
456 ui::NativeTheme::ExtraParams* params) const { 470 ui::NativeTheme::ExtraParams* params) const {
457 GetExtraParams(params); 471 GetExtraParams(params);
458 return ui::NativeTheme::kHovered; 472 return ui::NativeTheme::kHovered;
459 } 473 }
460 474
475 void LabelButton::ResetCachedSize() {
476 button_size_valid_ = false;
477 button_size_= gfx::Size();
478 }
479
461 } // namespace views 480 } // namespace views
OLDNEW
« ui/views/controls/button/label_button.h ('K') | « ui/views/controls/button/label_button.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698