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