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