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 |