diff options
Diffstat (limited to 'chrome/views')
-rw-r--r-- | chrome/views/label.cc | 28 | ||||
-rw-r--r-- | chrome/views/label.h | 41 | ||||
-rw-r--r-- | chrome/views/label_unittest.cc | 21 | ||||
-rw-r--r-- | chrome/views/message_box_view.cc | 19 | ||||
-rw-r--r-- | chrome/views/message_box_view.h | 16 |
5 files changed, 113 insertions, 12 deletions
diff --git a/chrome/views/label.cc b/chrome/views/label.cc index f0c38d8..0489479 100644 --- a/chrome/views/label.cc +++ b/chrome/views/label.cc @@ -45,6 +45,7 @@ void Label::Init(const std::wstring& text, const ChromeFont& font) { horiz_alignment_ = ALIGN_CENTER; is_multi_line_ = false; collapse_when_hidden_ = false; + rtl_alignment_mode_ = USE_UI_ALIGNMENT; } Label::~Label() { @@ -238,17 +239,16 @@ const SkColor Label::GetColor() const { } void Label::SetHorizontalAlignment(Alignment a) { + // If the View's UI layout is right-to-left and rtl_alignment_mode_ is + // USE_UI_ALIGNMENT, we need to flip the alignment so that the alignment + // settings take into account the text directionality. + if (UILayoutIsRightToLeft() && rtl_alignment_mode_ == USE_UI_ALIGNMENT) { + if (a == ALIGN_LEFT) + a = ALIGN_RIGHT; + else if (a == ALIGN_RIGHT) + a = ALIGN_LEFT; + } if (horiz_alignment_ != a) { - - // If the View's UI layout is right-to-left, we need to flip the alignment - // so that the alignment settings take into account the text - // directionality. - if (UILayoutIsRightToLeft()) { - if (a == ALIGN_LEFT) - a = ALIGN_RIGHT; - else if (a == ALIGN_RIGHT) - a = ALIGN_LEFT; - } horiz_alignment_ = a; SchedulePaint(); } @@ -258,6 +258,14 @@ Label::Alignment Label::GetHorizontalAlignment() const { return horiz_alignment_; } +void Label::SetRTLAlignmentMode(RTLAlignmentMode mode) { + rtl_alignment_mode_ = mode; +} + +Label::RTLAlignmentMode Label::GetRTLAlignmentMode() const { + return rtl_alignment_mode_; +} + void Label::SetMultiLine(bool f) { if (f != is_multi_line_) { is_multi_line_ = f; diff --git a/chrome/views/label.h b/chrome/views/label.h index 84e685c..d70ff3a 100644 --- a/chrome/views/label.h +++ b/chrome/views/label.h @@ -26,6 +26,22 @@ class Label : public View { ALIGN_CENTER, ALIGN_RIGHT }; + // The following enum is used to indicate whether using the Chrome UI's + // alignment as the label's alignment, or autodetecting the label's + // alignment. + // + // If the label text originates from the Chrome UI, we should use the Chrome + // UI's alignment as the label's alignment. + // + // If the text originates from a web page, the text's alignment is determined + // based on the first character with strong directionality, disregarding what + // directionality the Chrome UI is. And its alignment will not be flipped + // around in RTL locales. + enum RTLAlignmentMode { + USE_UI_ALIGNMENT = 0, + AUTO_DETECT_ALIGNMENT + }; + // The view class name. static const char kViewClassName[]; @@ -81,10 +97,29 @@ class Label : public View { // Return a reference to the currently used color virtual const SkColor GetColor() const; - // Alignment + // Set horizontal alignment. If the locale is RTL, and the RTL alignment + // setting is set as USE_UI_ALIGNMENT, the alignment is flipped around. + // + // Caveat: for labels originating from a web page, the RTL alignment mode + // should be reset to AUTO_DETECT_ALIGNMENT before the horizontal alignment + // is set. Otherwise, the label's alignment specified as a parameter will be + // flipped in RTL locales. Please see the comments in SetRTLAlignmentMode for + // more information. void SetHorizontalAlignment(Alignment a); + Alignment GetHorizontalAlignment() const; + // Set the RTL alignment mode. The RTL alignment mode is initialized to + // USE_UI_ALIGNMENT when the label is constructed. USE_UI_ALIGNMENT applies + // to every label that originates from the Chrome UI. However, if the label + // originates from a web page, its alignment should not be flipped around for + // RTL locales. For such labels, we need to set the RTL alignment mode to + // AUTO_DETECT_ALIGNMENT so that subsequent SetHorizontalAlignment() calls + // will not flip the label's alignment around. + void SetRTLAlignmentMode(RTLAlignmentMode mode); + + RTLAlignmentMode GetRTLAlignmentMode() const; + // Set whether the label text can wrap on multiple lines. // Default is false void SetMultiLine(bool f); @@ -192,6 +227,10 @@ class Label : public View { scoped_ptr<Background> mouse_over_background_; // Whether to collapse the label when it's not visible. bool collapse_when_hidden_; + // The following member variable is used to control whether the alignment + // needs to be flipped around for RTL locales. Please refer to the definition + // of RTLAlignmentMode for more information. + RTLAlignmentMode rtl_alignment_mode_; DISALLOW_COPY_AND_ASSIGN(Label); }; diff --git a/chrome/views/label_unittest.cc b/chrome/views/label_unittest.cc index e1f80bb0..96b4d63 100644 --- a/chrome/views/label_unittest.cc +++ b/chrome/views/label_unittest.cc @@ -61,6 +61,27 @@ TEST(LabelTest, AlignmentProperty) { label.GetHorizontalAlignment()); label.SetHorizontalAlignment(Label::ALIGN_CENTER); EXPECT_EQ(Label::ALIGN_CENTER, label.GetHorizontalAlignment()); + + // The label's alignment should not be flipped if the RTL alignment mode + // is AUTO_DETECT_ALIGNMENT. + label.SetRTLAlignmentMode(Label::AUTO_DETECT_ALIGNMENT); + label.SetHorizontalAlignment(Label::ALIGN_RIGHT); + EXPECT_EQ(Label::ALIGN_RIGHT, label.GetHorizontalAlignment()); + label.SetHorizontalAlignment(Label::ALIGN_LEFT); + EXPECT_EQ(Label::ALIGN_LEFT, label.GetHorizontalAlignment()); + label.SetHorizontalAlignment(Label::ALIGN_CENTER); + EXPECT_EQ(Label::ALIGN_CENTER, label.GetHorizontalAlignment()); +} + +TEST(LabelTest, RTLAlignmentModeProperty) { + Label label; + EXPECT_EQ(Label::USE_UI_ALIGNMENT, label.GetRTLAlignmentMode()); + + label.SetRTLAlignmentMode(Label::AUTO_DETECT_ALIGNMENT); + EXPECT_EQ(Label::AUTO_DETECT_ALIGNMENT, label.GetRTLAlignmentMode()); + + label.SetRTLAlignmentMode(Label::USE_UI_ALIGNMENT); + EXPECT_EQ(Label::USE_UI_ALIGNMENT, label.GetRTLAlignmentMode()); } TEST(LabelTest, MultiLineProperty) { diff --git a/chrome/views/message_box_view.cc b/chrome/views/message_box_view.cc index 818cf50..26fd1c2 100644 --- a/chrome/views/message_box_view.cc +++ b/chrome/views/message_box_view.cc @@ -94,7 +94,24 @@ void MessageBoxView::ViewHierarchyChanged(bool is_add, void MessageBoxView::Init(int dialog_flags, const std::wstring& default_prompt) { message_label_->SetMultiLine(true); - message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + if (dialog_flags & kAutoDetectAlignment) { + // Determine the alignment and directionality based on the first character + // with strong directionality. + l10n_util::TextDirection direction = + l10n_util::GetFirstStrongCharacterDirection(message_label_->GetText()); + views::Label::Alignment alignment; + if (direction == l10n_util::RIGHT_TO_LEFT) + alignment = views::Label::ALIGN_RIGHT; + else + alignment = views::Label::ALIGN_LEFT; + // In addition, we should set the RTL alignment mode as + // AUTO_DETECT_ALIGNMENT so that the alignment will not be flipped around + // in RTL locales. + message_label_->SetRTLAlignmentMode(views::Label::AUTO_DETECT_ALIGNMENT); + message_label_->SetHorizontalAlignment(alignment); + } else { + message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + } if (dialog_flags & kFlagHasPromptField) { prompt_field_ = new views::TextField; diff --git a/chrome/views/message_box_view.h b/chrome/views/message_box_view.h index a8f0dca..e71db2c 100644 --- a/chrome/views/message_box_view.h +++ b/chrome/views/message_box_view.h @@ -25,6 +25,22 @@ class MessageBoxView : public views::View { static const int kFlagHasPromptField = 0x4; static const int kFlagHasMessage = 0x8; + // The following flag is used to indicate whether the message's alignment + // should be autodetected or inherited from Chrome UI. Callers should pass + // the correct flag based on the origin of the message. If the message is + // from a web page (such as the JavaScript alert message), its alignment and + // directionality are based on the first character with strong directionality + // in the message. Chrome UI strings are localized string and therefore they + // should have the same alignment and directionality as those of the Chrome + // UI. For example, in RTL locales, even though some strings might begin with + // an English character, they should still be right aligned and be displayed + // Right-To-Left. + // + // TODO(xji): If the message is from a web page, then the message + // directionality should be determined based on the directionality of the web + // page. Please refer to http://crbug.com/7166 for more information. + static const int kAutoDetectAlignment = 0x10; + static const int kIsConfirmMessageBox = kFlagHasMessage | kFlagHasOKButton | kFlagHasCancelButton; |