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