| 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/label.h" | 5 #include "ui/views/controls/label.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 void Label::SetShadowOffset(int x, int y) { | 114 void Label::SetShadowOffset(int x, int y) { |
| 115 shadow_offset_.SetPoint(x, y); | 115 shadow_offset_.SetPoint(x, y); |
| 116 } | 116 } |
| 117 | 117 |
| 118 void Label::ClearEmbellishing() { | 118 void Label::ClearEmbellishing() { |
| 119 has_shadow_ = false; | 119 has_shadow_ = false; |
| 120 } | 120 } |
| 121 | 121 |
| 122 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { | 122 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { |
| 123 // If the UI layout is right-to-left, flip the alignment direction. | 123 // If the View's UI layout is right-to-left and directionality_mode_ is |
| 124 if (base::i18n::IsRTL() && | 124 // USE_UI_DIRECTIONALITY, we need to flip the alignment so that the alignment |
| 125 (alignment == gfx::ALIGN_LEFT || alignment == gfx::ALIGN_RIGHT)) { | 125 // settings take into account the text directionality. |
| 126 if (base::i18n::IsRTL() && (directionality_mode_ == USE_UI_DIRECTIONALITY) && |
| 127 (alignment != gfx::ALIGN_CENTER)) { |
| 126 alignment = (alignment == gfx::ALIGN_LEFT) ? | 128 alignment = (alignment == gfx::ALIGN_LEFT) ? |
| 127 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; | 129 gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; |
| 128 } | 130 } |
| 129 if (horizontal_alignment_ != alignment) { | 131 if (horizontal_alignment_ != alignment) { |
| 130 horizontal_alignment_ = alignment; | 132 horizontal_alignment_ = alignment; |
| 131 SchedulePaint(); | 133 SchedulePaint(); |
| 132 } | 134 } |
| 133 } | 135 } |
| 134 | 136 |
| 135 gfx::HorizontalAlignment Label::GetHorizontalAlignment() const { | |
| 136 if (horizontal_alignment_ != gfx::ALIGN_TO_HEAD) | |
| 137 return horizontal_alignment_; | |
| 138 | |
| 139 const base::i18n::TextDirection dir = | |
| 140 base::i18n::GetFirstStrongCharacterDirection(layout_text()); | |
| 141 return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; | |
| 142 } | |
| 143 | |
| 144 void Label::SetLineHeight(int height) { | 137 void Label::SetLineHeight(int height) { |
| 145 if (height != line_height_) { | 138 if (height != line_height_) { |
| 146 line_height_ = height; | 139 line_height_ = height; |
| 147 ResetCachedSize(); | 140 ResetCachedSize(); |
| 148 PreferredSizeChanged(); | 141 PreferredSizeChanged(); |
| 149 SchedulePaint(); | 142 SchedulePaint(); |
| 150 } | 143 } |
| 151 } | 144 } |
| 152 | 145 |
| 153 void Label::SetMultiLine(bool multi_line) { | 146 void Label::SetMultiLine(bool multi_line) { |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false; | 398 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false; |
| 406 auto_color_readability_ = true; | 399 auto_color_readability_ = true; |
| 407 UpdateColorsFromTheme(ui::NativeTheme::instance()); | 400 UpdateColorsFromTheme(ui::NativeTheme::instance()); |
| 408 horizontal_alignment_ = gfx::ALIGN_CENTER; | 401 horizontal_alignment_ = gfx::ALIGN_CENTER; |
| 409 line_height_ = 0; | 402 line_height_ = 0; |
| 410 is_multi_line_ = false; | 403 is_multi_line_ = false; |
| 411 is_obscured_ = false; | 404 is_obscured_ = false; |
| 412 allow_character_break_ = false; | 405 allow_character_break_ = false; |
| 413 elide_behavior_ = gfx::ELIDE_TAIL; | 406 elide_behavior_ = gfx::ELIDE_TAIL; |
| 414 collapse_when_hidden_ = false; | 407 collapse_when_hidden_ = false; |
| 415 directionality_mode_ = gfx::DIRECTIONALITY_FROM_UI; | 408 directionality_mode_ = USE_UI_DIRECTIONALITY; |
| 416 enabled_shadow_color_ = 0; | 409 enabled_shadow_color_ = 0; |
| 417 disabled_shadow_color_ = 0; | 410 disabled_shadow_color_ = 0; |
| 418 shadow_offset_.SetPoint(1, 1); | 411 shadow_offset_.SetPoint(1, 1); |
| 419 has_shadow_ = false; | 412 has_shadow_ = false; |
| 420 shadow_blur_ = 0; | 413 shadow_blur_ = 0; |
| 421 halo_color_ = SK_ColorTRANSPARENT; | 414 halo_color_ = SK_ColorTRANSPARENT; |
| 422 cached_heights_.resize(kCachedSizeLimit); | 415 cached_heights_.resize(kCachedSizeLimit); |
| 423 ResetCachedSize(); | 416 ResetCachedSize(); |
| 424 | 417 |
| 425 SetText(text); | 418 SetText(text); |
| 426 } | 419 } |
| 427 | 420 |
| 428 void Label::RecalculateColors() { | 421 void Label::RecalculateColors() { |
| 429 actual_enabled_color_ = auto_color_readability_ ? | 422 actual_enabled_color_ = auto_color_readability_ ? |
| 430 color_utils::GetReadableColor(requested_enabled_color_, | 423 color_utils::GetReadableColor(requested_enabled_color_, |
| 431 background_color_) : | 424 background_color_) : |
| 432 requested_enabled_color_; | 425 requested_enabled_color_; |
| 433 actual_disabled_color_ = auto_color_readability_ ? | 426 actual_disabled_color_ = auto_color_readability_ ? |
| 434 color_utils::GetReadableColor(requested_disabled_color_, | 427 color_utils::GetReadableColor(requested_disabled_color_, |
| 435 background_color_) : | 428 background_color_) : |
| 436 requested_disabled_color_; | 429 requested_disabled_color_; |
| 437 } | 430 } |
| 438 | 431 |
| 439 gfx::Rect Label::GetTextBounds() const { | 432 gfx::Rect Label::GetTextBounds() const { |
| 440 gfx::Rect available(GetAvailableRect()); | 433 gfx::Rect available_rect(GetAvailableRect()); |
| 441 gfx::Size text_size(GetTextSize()); | 434 gfx::Size text_size(GetTextSize()); |
| 442 text_size.set_width(std::min(available.width(), text_size.width())); | 435 text_size.set_width(std::min(available_rect.width(), text_size.width())); |
| 443 gfx::Point origin(GetInsets().left(), GetInsets().top()); | 436 |
| 444 switch (GetHorizontalAlignment()) { | 437 gfx::Insets insets = GetInsets(); |
| 438 gfx::Point text_origin(insets.left(), insets.top()); |
| 439 switch (horizontal_alignment_) { |
| 445 case gfx::ALIGN_LEFT: | 440 case gfx::ALIGN_LEFT: |
| 446 break; | 441 break; |
| 447 case gfx::ALIGN_CENTER: | 442 case gfx::ALIGN_CENTER: |
| 448 // Put any extra margin pixel on the left to match the legacy behavior | 443 // We put any extra margin pixel on the left rather than the right. We |
| 449 // from the use of GetTextExtentPoint32() on Windows. | 444 // used to do this because measurement on Windows used |
| 450 origin.Offset((available.width() + 1 - text_size.width()) / 2, 0); | 445 // GetTextExtentPoint32(), which could report a value one too large on the |
| 446 // right; we now use DrawText(), and who knows if it can also do this. |
| 447 text_origin.Offset((available_rect.width() + 1 - text_size.width()) / 2, |
| 448 0); |
| 451 break; | 449 break; |
| 452 case gfx::ALIGN_RIGHT: | 450 case gfx::ALIGN_RIGHT: |
| 453 origin.set_x(available.right() - text_size.width()); | 451 text_origin.set_x(available_rect.right() - text_size.width()); |
| 454 break; | 452 break; |
| 455 default: | 453 default: |
| 456 NOTREACHED(); | 454 NOTREACHED(); |
| 457 break; | 455 break; |
| 458 } | 456 } |
| 459 origin.Offset(0, std::max(0, (available.height() - text_size.height())) / 2); | 457 text_origin.Offset(0, |
| 460 return gfx::Rect(origin, text_size); | 458 std::max(0, (available_rect.height() - text_size.height())) / 2); |
| 459 return gfx::Rect(text_origin, text_size); |
| 461 } | 460 } |
| 462 | 461 |
| 463 int Label::ComputeDrawStringFlags() const { | 462 int Label::ComputeDrawStringFlags() const { |
| 464 int flags = 0; | 463 int flags = 0; |
| 465 | 464 |
| 466 // We can't use subpixel rendering if the background is non-opaque. | 465 // We can't use subpixel rendering if the background is non-opaque. |
| 467 if (SkColorGetA(background_color_) != 0xFF) | 466 if (SkColorGetA(background_color_) != 0xFF) |
| 468 flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; | 467 flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; |
| 469 | 468 |
| 470 if (directionality_mode_ == gfx::DIRECTIONALITY_FORCE_LTR) { | 469 if (directionality_mode_ == AUTO_DETECT_DIRECTIONALITY) { |
| 471 flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY; | |
| 472 } else if (directionality_mode_ == gfx::DIRECTIONALITY_FORCE_RTL) { | |
| 473 flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY; | |
| 474 } else if (directionality_mode_ == gfx::DIRECTIONALITY_FROM_TEXT) { | |
| 475 base::i18n::TextDirection direction = | 470 base::i18n::TextDirection direction = |
| 476 base::i18n::GetFirstStrongCharacterDirection(layout_text()); | 471 base::i18n::GetFirstStrongCharacterDirection(layout_text()); |
| 477 if (direction == base::i18n::RIGHT_TO_LEFT) | 472 if (direction == base::i18n::RIGHT_TO_LEFT) |
| 478 flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY; | 473 flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY; |
| 479 else | 474 else |
| 480 flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY; | 475 flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY; |
| 481 } | 476 } |
| 482 | 477 |
| 483 switch (GetHorizontalAlignment()) { | 478 switch (horizontal_alignment_) { |
| 484 case gfx::ALIGN_LEFT: | 479 case gfx::ALIGN_LEFT: |
| 485 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; | 480 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; |
| 486 break; | 481 break; |
| 487 case gfx::ALIGN_CENTER: | 482 case gfx::ALIGN_CENTER: |
| 488 flags |= gfx::Canvas::TEXT_ALIGN_CENTER; | 483 flags |= gfx::Canvas::TEXT_ALIGN_CENTER; |
| 489 break; | 484 break; |
| 490 case gfx::ALIGN_RIGHT: | 485 case gfx::ALIGN_RIGHT: |
| 491 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; | 486 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; |
| 492 break; | 487 break; |
| 493 default: | |
| 494 NOTREACHED(); | |
| 495 break; | |
| 496 } | 488 } |
| 497 | 489 |
| 498 if (!is_multi_line_) | 490 if (!is_multi_line_) |
| 499 return flags; | 491 return flags; |
| 500 | 492 |
| 501 flags |= gfx::Canvas::MULTI_LINE; | 493 flags |= gfx::Canvas::MULTI_LINE; |
| 502 #if !defined(OS_WIN) | 494 #if !defined(OS_WIN) |
| 503 // Don't elide multiline labels on Linux. | 495 // Don't elide multiline labels on Linux. |
| 504 // Todo(davemoore): Do we depend on eliding multiline text? | 496 // Todo(davemoore): Do we depend on eliding multiline text? |
| 505 // Pango insists on limiting the number of lines to one if text is | 497 // Pango insists on limiting the number of lines to one if text is |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 cached_heights_[i] = gfx::Size(); | 555 cached_heights_[i] = gfx::Size(); |
| 564 } | 556 } |
| 565 | 557 |
| 566 bool Label::ShouldShowDefaultTooltip() const { | 558 bool Label::ShouldShowDefaultTooltip() const { |
| 567 return !is_multi_line_ && !is_obscured_ && | 559 return !is_multi_line_ && !is_obscured_ && |
| 568 gfx::GetStringWidth(layout_text(), font_list_) > | 560 gfx::GetStringWidth(layout_text(), font_list_) > |
| 569 GetAvailableRect().width(); | 561 GetAvailableRect().width(); |
| 570 } | 562 } |
| 571 | 563 |
| 572 } // namespace views | 564 } // namespace views |
| OLD | NEW |