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 |