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 3 // found in the LICENSE file. 4 5 #include "ui/views/examples/text_example.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "ui/gfx/canvas.h" 9 #include "ui/gfx/font_list.h" 10 #include "ui/views/border.h" 11 #include "ui/views/controls/button/checkbox.h" 12 #include "ui/views/controls/combobox/combobox.h" 13 #include "ui/views/controls/label.h" 14 #include "ui/views/examples/example_combobox_model.h" 15 #include "ui/views/layout/grid_layout.h" 16 #include "ui/views/view.h" 17 18 namespace views { 19 namespace examples { 20 21 namespace { 22 23 // Number of columns in the view layout. 24 const int kNumColumns = 10; 25 26 const char kShortText[] = "The quick brown fox jumps over the lazy dog."; 27 const char kLongText[] = 28 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod " 29 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " 30 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " 31 "commodo consequat.\nDuis aute irure dolor in reprehenderit in voluptate " 32 "velit esse cillum dolore eu fugiat nulla pariatur.\n\nExcepteur sint " 33 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt " 34 "mollit anim id est laborum."; 35 const char kAmpersandText[] = 36 "The quick && &brown fo&x jumps over the lazy dog."; 37 const wchar_t kRightToLeftText[] = 38 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 39 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 40 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 41 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 42 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 43 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 44 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd! " 45 L"\x5e9\x5dc\x5d5\x5dd \x5d4\x5e2\x5d5\x5dc\x5dd!"; 46 47 const char* kTextExamples[] = { "Short", "Long", "Ampersands", "RTL Hebrew", }; 48 const char* kElideBehaviors[] = { "Elide", "No Elide", "Fade", }; 49 const char* kPrefixOptions[] = { "Default", "Show", "Hide", }; 50 const char* kHorizontalAligments[] = { "Default", "Left", "Center", "Right", }; 51 52 // Toggles bit |flag| on |flags| based on state of |checkbox|. 53 void SetFlagFromCheckbox(Checkbox* checkbox, int* flags, int flag) { 54 if (checkbox->checked()) 55 *flags |= flag; 56 else 57 *flags &= ~flag; 58 } 59 60 } // namespace 61 62 // TextExample's content view, which draws stylized string. 63 class TextExample::TextExampleView : public View { 64 public: 65 TextExampleView() 66 : text_(base::ASCIIToUTF16(kShortText)), 67 flags_(0), 68 halo_(false), 69 elide_(gfx::NO_ELIDE) { 70 } 71 72 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 73 View::OnPaint(canvas); 74 const gfx::Rect bounds = GetContentsBounds(); 75 const SkColor color = SK_ColorDKGRAY; 76 if (elide_ == gfx::FADE_TAIL) { 77 canvas->DrawFadedString(text_, font_list_, color, bounds, flags_); 78 } else if (halo_) { 79 canvas->DrawStringRectWithHalo(text_, font_list_, color, SK_ColorYELLOW, 80 bounds, flags_); 81 } else { 82 canvas->DrawStringRectWithFlags(text_, font_list_, color, bounds, flags_); 83 } 84 } 85 86 int flags() const { return flags_; } 87 void set_flags(int flags) { flags_ = flags; } 88 void set_text(const base::string16& text) { text_ = text; } 89 void set_halo(bool halo) { halo_ = halo; } 90 void set_elide(gfx::ElideBehavior elide) { elide_ = elide; } 91 92 int GetStyle() const { return font_list_.GetFontStyle(); } 93 void SetStyle(int style) { font_list_ = font_list_.DeriveWithStyle(style); } 94 95 private: 96 // The font used for drawing the text. 97 gfx::FontList font_list_; 98 99 // The text to draw. 100 base::string16 text_; 101 102 // Text flags for passing to |DrawStringRect()|. 103 int flags_; 104 105 // A flag to draw a halo around the text. 106 bool halo_; 107 108 // The eliding, fading, or truncating behavior. 109 gfx::ElideBehavior elide_; 110 111 DISALLOW_COPY_AND_ASSIGN(TextExampleView); 112 }; 113 114 TextExample::TextExample() : ExampleBase("Text Styles") {} 115 116 TextExample::~TextExample() { 117 // Remove the views first as some reference combobox models. 118 container()->RemoveAllChildViews(true); 119 } 120 121 Checkbox* TextExample::AddCheckbox(GridLayout* layout, const char* name) { 122 Checkbox* checkbox = new Checkbox(base::ASCIIToUTF16(name)); 123 checkbox->set_listener(this); 124 layout->AddView(checkbox); 125 return checkbox; 126 } 127 128 Combobox* TextExample::AddCombobox(GridLayout* layout, 129 const char* name, 130 const char** strings, 131 int count) { 132 layout->StartRow(0, 0); 133 layout->AddView(new Label(base::ASCIIToUTF16(name))); 134 ExampleComboboxModel* model = new ExampleComboboxModel(strings, count); 135 example_combobox_model_.push_back(model); 136 Combobox* combobox = new Combobox(model); 137 combobox->SetSelectedIndex(0); 138 combobox->set_listener(this); 139 layout->AddView(combobox, kNumColumns - 1, 1); 140 return combobox; 141 } 142 143 void TextExample::CreateExampleView(View* container) { 144 text_view_ = new TextExampleView; 145 text_view_->SetBorder(Border::CreateSolidBorder(1, SK_ColorGRAY)); 146 GridLayout* layout = new GridLayout(container); 147 container->SetLayoutManager(layout); 148 layout->AddPaddingRow(0, 8); 149 150 ColumnSet* column_set = layout->AddColumnSet(0); 151 column_set->AddPaddingColumn(0, 8); 152 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 153 0.1f, GridLayout::USE_PREF, 0, 0); 154 for (int i = 0; i < kNumColumns - 1; i++) 155 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 156 0.1f, GridLayout::USE_PREF, 0, 0); 157 column_set->AddPaddingColumn(0, 8); 158 159 h_align_cb_ = AddCombobox(layout, "H-Align", kHorizontalAligments, 160 arraysize(kHorizontalAligments)); 161 eliding_cb_ = AddCombobox(layout, "Eliding", kElideBehaviors, 162 arraysize(kElideBehaviors)); 163 prefix_cb_ = AddCombobox(layout, "Prefix", kPrefixOptions, 164 arraysize(kPrefixOptions)); 165 text_cb_ = AddCombobox(layout, "Example Text", kTextExamples, 166 arraysize(kTextExamples)); 167 168 layout->StartRow(0, 0); 169 multiline_checkbox_ = AddCheckbox(layout, "Multiline"); 170 break_checkbox_ = AddCheckbox(layout, "Character Break"); 171 halo_checkbox_ = AddCheckbox(layout, "Halo"); 172 bold_checkbox_ = AddCheckbox(layout, "Bold"); 173 italic_checkbox_ = AddCheckbox(layout, "Italic"); 174 underline_checkbox_ = AddCheckbox(layout, "Underline"); 175 176 layout->AddPaddingRow(0, 20); 177 column_set = layout->AddColumnSet(1); 178 column_set->AddPaddingColumn(0, 16); 179 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 180 1, GridLayout::USE_PREF, 0, 0); 181 column_set->AddPaddingColumn(0, 16); 182 layout->StartRow(1, 1); 183 layout->AddView(text_view_); 184 layout->AddPaddingRow(0, 8); 185 } 186 187 void TextExample::ButtonPressed(Button* button, const ui::Event& event) { 188 int flags = text_view_->flags(); 189 int style = text_view_->GetStyle(); 190 SetFlagFromCheckbox(multiline_checkbox_, &flags, gfx::Canvas::MULTI_LINE); 191 SetFlagFromCheckbox(break_checkbox_, &flags, gfx::Canvas::CHARACTER_BREAK); 192 SetFlagFromCheckbox(bold_checkbox_, &style, gfx::Font::BOLD); 193 SetFlagFromCheckbox(italic_checkbox_, &style, gfx::Font::ITALIC); 194 SetFlagFromCheckbox(underline_checkbox_, &style, gfx::Font::UNDERLINE); 195 text_view_->set_halo(halo_checkbox_->checked()); 196 text_view_->set_flags(flags); 197 text_view_->SetStyle(style); 198 text_view_->SchedulePaint(); 199 } 200 201 void TextExample::OnPerformAction(Combobox* combobox) { 202 int flags = text_view_->flags(); 203 if (combobox == h_align_cb_) { 204 flags &= ~(gfx::Canvas::TEXT_ALIGN_LEFT | 205 gfx::Canvas::TEXT_ALIGN_CENTER | 206 gfx::Canvas::TEXT_ALIGN_RIGHT); 207 switch (combobox->selected_index()) { 208 case 0: 209 break; 210 case 1: 211 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; 212 break; 213 case 2: 214 flags |= gfx::Canvas::TEXT_ALIGN_CENTER; 215 break; 216 case 3: 217 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; 218 break; 219 } 220 } else if (combobox == text_cb_) { 221 switch (combobox->selected_index()) { 222 case 0: 223 text_view_->set_text(base::ASCIIToUTF16(kShortText)); 224 break; 225 case 1: 226 text_view_->set_text(base::ASCIIToUTF16(kLongText)); 227 break; 228 case 2: 229 text_view_->set_text(base::ASCIIToUTF16(kAmpersandText)); 230 break; 231 case 3: 232 text_view_->set_text(base::WideToUTF16(kRightToLeftText)); 233 break; 234 } 235 } else if (combobox == eliding_cb_) { 236 switch (combobox->selected_index()) { 237 case 0: 238 text_view_->set_elide(gfx::ELIDE_TAIL); 239 break; 240 case 1: 241 text_view_->set_elide(gfx::NO_ELIDE); 242 break; 243 case 2: 244 text_view_->set_elide(gfx::FADE_TAIL); 245 break; 246 } 247 } else if (combobox == prefix_cb_) { 248 flags &= ~(gfx::Canvas::SHOW_PREFIX | gfx::Canvas::HIDE_PREFIX); 249 switch (combobox->selected_index()) { 250 case 0: 251 break; 252 case 1: 253 flags |= gfx::Canvas::SHOW_PREFIX; 254 break; 255 case 2: 256 flags |= gfx::Canvas::HIDE_PREFIX; 257 break; 258 } 259 } 260 text_view_->set_flags(flags); 261 text_view_->SchedulePaint(); 262 } 263 264 } // namespace examples 265 } // namespace views 266