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

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
« no previous file with comments | « ui/views/controls/button/label_button.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) { 74 const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) {
75 if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull()) 75 if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull())
76 return button_state_images_[STATE_NORMAL]; 76 return button_state_images_[STATE_NORMAL];
77 return button_state_images_[for_state]; 77 return button_state_images_[for_state];
78 } 78 }
79 79
80 void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) { 80 void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) {
81 button_state_images_[for_state] = image; 81 button_state_images_[for_state] = image;
82 UpdateImage(); 82 UpdateImage();
83 ResetCachedSize();
83 } 84 }
84 85
85 const base::string16& LabelButton::GetText() const { 86 const base::string16& LabelButton::GetText() const {
86 return label_->text(); 87 return label_->text();
87 } 88 }
88 89
89 void LabelButton::SetText(const base::string16& text) { 90 void LabelButton::SetText(const base::string16& text) {
90 SetAccessibleName(text); 91 SetAccessibleName(text);
91 label_->SetText(text); 92 label_->SetText(text);
93 ResetCachedSize();
92 } 94 }
93 95
94 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { 96 void LabelButton::SetTextColor(ButtonState for_state, SkColor color) {
95 button_state_colors_[for_state] = color; 97 button_state_colors_[for_state] = color;
96 if (for_state == STATE_DISABLED) 98 if (for_state == STATE_DISABLED)
97 label_->SetDisabledColor(color); 99 label_->SetDisabledColor(color);
98 else if (for_state == state()) 100 else if (for_state == state())
99 label_->SetEnabledColor(color); 101 label_->SetEnabledColor(color);
100 explicitly_set_colors_[for_state] = true; 102 explicitly_set_colors_[for_state] = true;
101 } 103 }
102 104
103 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) { 105 void LabelButton::SetTextShadows(const gfx::ShadowValues& shadows) {
104 label_->set_shadows(shadows); 106 label_->set_shadows(shadows);
107 ResetCachedSize();
105 } 108 }
106 109
107 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) { 110 void LabelButton::SetTextSubpixelRenderingEnabled(bool enabled) {
108 label_->set_subpixel_rendering_enabled(enabled); 111 label_->set_subpixel_rendering_enabled(enabled);
109 } 112 }
110 113
111 bool LabelButton::GetTextMultiLine() const { 114 bool LabelButton::GetTextMultiLine() const {
112 return label_->is_multi_line(); 115 return label_->is_multi_line();
113 } 116 }
114 117
115 void LabelButton::SetTextMultiLine(bool text_multi_line) { 118 void LabelButton::SetTextMultiLine(bool text_multi_line) {
116 label_->SetMultiLine(text_multi_line); 119 label_->SetMultiLine(text_multi_line);
120 ResetCachedSize();
117 } 121 }
118 122
119 const gfx::FontList& LabelButton::GetFontList() const { 123 const gfx::FontList& LabelButton::GetFontList() const {
120 return label_->font_list(); 124 return label_->font_list();
121 } 125 }
122 126
123 void LabelButton::SetFontList(const gfx::FontList& font_list) { 127 void LabelButton::SetFontList(const gfx::FontList& font_list) {
124 cached_normal_font_list_ = font_list; 128 cached_normal_font_list_ = font_list;
125 cached_bold_font_list_ = font_list.DeriveWithStyle( 129 cached_bold_font_list_ = font_list.DeriveWithStyle(
126 font_list.GetFontStyle() | gfx::Font::BOLD); 130 font_list.GetFontStyle() | gfx::Font::BOLD);
127 131
128 // STYLE_BUTTON uses bold text to indicate default buttons. 132 // STYLE_BUTTON uses bold text to indicate default buttons.
129 label_->SetFontList( 133 label_->SetFontList(
130 style_ == STYLE_BUTTON && is_default_ ? 134 style_ == STYLE_BUTTON && is_default_ ?
131 cached_bold_font_list_ : cached_normal_font_list_); 135 cached_bold_font_list_ : cached_normal_font_list_);
136 ResetCachedSize();
132 } 137 }
133 138
134 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) { 139 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
135 label_->SetElideBehavior(elide_behavior); 140 label_->SetElideBehavior(elide_behavior);
141 ResetCachedSize();
136 } 142 }
137 143
138 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const { 144 gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const {
139 return label_->GetHorizontalAlignment(); 145 return label_->GetHorizontalAlignment();
140 } 146 }
141 147
142 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { 148 void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
143 label_->SetHorizontalAlignment(alignment); 149 label_->SetHorizontalAlignment(alignment);
144 InvalidateLayout(); 150 InvalidateLayout();
145 } 151 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 set_min_size(gfx::Size(70, 33)); 185 set_min_size(gfx::Size(70, 33));
180 186
181 OnNativeThemeChanged(GetNativeTheme()); 187 OnNativeThemeChanged(GetNativeTheme());
182 } 188 }
183 189
184 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { 190 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
185 focus_painter_ = focus_painter.Pass(); 191 focus_painter_ = focus_painter.Pass();
186 } 192 }
187 193
188 gfx::Size LabelButton::GetPreferredSize() const { 194 gfx::Size LabelButton::GetPreferredSize() const {
189 // Use a temporary label copy for sizing to avoid calculation side-effects. 195 if (!button_size_valid_) {
190 Label label(GetText(), cached_normal_font_list_); 196 // Use a temporary label copy for sizing to avoid calculation side-effects.
191 label.set_shadows(label_->shadows()); 197 Label label(GetText(), cached_normal_font_list_);
192 label.SetMultiLine(GetTextMultiLine()); 198 label.set_shadows(label_->shadows());
199 label.SetMultiLine(GetTextMultiLine());
193 200
194 if (style() == STYLE_BUTTON) { 201 if (style() == STYLE_BUTTON) {
195 // Some text appears wider when rendered normally than when rendered bold. 202 // Some text appears wider when rendered normally than when rendered bold.
196 // Accommodate the widest, as buttons may show bold and shouldn't resize. 203 // Accommodate the widest, as buttons may show bold and shouldn't resize.
197 const int current_width = label.GetPreferredSize().width(); 204 const int current_width = label.GetPreferredSize().width();
198 label.SetFontList(cached_bold_font_list_); 205 label.SetFontList(cached_bold_font_list_);
199 if (label.GetPreferredSize().width() < current_width) 206 if (label.GetPreferredSize().width() < current_width)
200 label.SetFontList(cached_normal_font_list_); 207 label.SetFontList(cached_normal_font_list_);
208 }
209
210 // Resize multi-line labels given the current limited available width.
Evan Stade 2014/07/15 19:10:06 by the way, I don't think the code should be resiz
msw 2014/07/15 22:51:43 This is addressed in my WIP https://codereview.chr
noms (inactive) 2014/07/21 15:40:43 Done.
211 const gfx::Size image_size(image_->GetPreferredSize());
212 const int image_width = image_size.width();
213 if (GetTextMultiLine() && (width() > image_width + kSpacing))
214 label.SizeToFit(width() - image_width - (image_width > 0 ? kSpacing : 0));
215
216 // Calculate the required size.
217 gfx::Size size(label.GetPreferredSize());
218 if (image_width > 0 && size.width() > 0)
219 size.Enlarge(kSpacing, 0);
220 size.SetToMax(gfx::Size(0, image_size.height()));
221 const gfx::Insets insets(GetInsets());
222 size.Enlarge(image_size.width() + insets.width(), insets.height());
223
224 // Make the size at least as large as the minimum size needed by the border.
225 size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size());
226
227 // Increase the minimum size monotonically with the preferred size.
228 size.SetToMax(min_size_);
229 min_size_ = size;
230
231 // Return the largest known size clamped to the maximum size (if valid).
232 if (max_size_.width() > 0)
233 size.set_width(std::min(max_size_.width(), size.width()));
234 if (max_size_.height() > 0)
235 size.set_height(std::min(max_size_.height(), size.height()));
236
237 // Cache this computed size, as recomputing it is an expensive operation.
238 button_size_valid_ = true;
239 button_size_ = size;
201 } 240 }
202 241 return button_size_;
203 // Resize multi-line labels given the current limited available width.
204 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());
211 if (image_width > 0 && size.width() > 0)
212 size.Enlarge(kSpacing, 0);
213 size.SetToMax(gfx::Size(0, image_size.height()));
214 const gfx::Insets insets(GetInsets());
215 size.Enlarge(image_size.width() + insets.width(), insets.height());
216
217 // Make the size at least as large as the minimum size needed by the border.
218 size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size());
219
220 // Increase the minimum size monotonically with the preferred size.
221 size.SetToMax(min_size_);
222 min_size_ = size;
223
224 // Return the largest known size clamped to the maximum size (if valid).
225 if (max_size_.width() > 0)
226 size.set_width(std::min(max_size_.width(), size.width()));
227 if (max_size_.height() > 0)
228 size.set_height(std::min(max_size_.height(), size.height()));
229 return size;
230 } 242 }
231 243
232 void LabelButton::Layout() { 244 void LabelButton::Layout() {
233 gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment(); 245 gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment();
234 if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER) 246 if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER)
235 adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ? 247 adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ?
236 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; 248 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
237 249
238 gfx::Rect child_area(GetChildAreaBounds()); 250 gfx::Rect child_area(GetChildAreaBounds());
239 child_area.Inset(GetInsets()); 251 child_area.Inset(GetInsets());
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 GetExtraParams(params); 457 GetExtraParams(params);
446 return ui::NativeTheme::kNormal; 458 return ui::NativeTheme::kNormal;
447 } 459 }
448 460
449 ui::NativeTheme::State LabelButton::GetForegroundThemeState( 461 ui::NativeTheme::State LabelButton::GetForegroundThemeState(
450 ui::NativeTheme::ExtraParams* params) const { 462 ui::NativeTheme::ExtraParams* params) const {
451 GetExtraParams(params); 463 GetExtraParams(params);
452 return ui::NativeTheme::kHovered; 464 return ui::NativeTheme::kHovered;
453 } 465 }
454 466
467 void LabelButton::ResetCachedSize() {
468 button_size_valid_ = false;
469 button_size_= gfx::Size();
470 }
471
455 } // namespace views 472 } // namespace views
OLDNEW
« no previous file with comments | « 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