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

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: rebase 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/views/controls/button/label_button.h ('k') | ui/views/controls/button/label_button_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698