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
19namespace views {
20namespace examples {
21
22namespace {
23
24// Number of columns in the view layout.
25const int kNumColumns = 10;
26
27const char kShortText[] = "Batman";
28const char kMediumText[] = "The quick brown fox jumps over the lazy dog.";
29const char kLongText[] =
30    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
31    "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
32    "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
33    "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
34    "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
35    "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
36    "mollit anim id est laborum.";
37const char kAmpersandText[] =
38    "The quick && &brown fo&x jumps over the lazy dog.";
39const char kNewlineText[] =
40    "The quick \nbrown fox jumps\n\n over the lazy dog.";
41
42const char* kTextExamples[] = {
43    "Short",
44    "Medium",
45    "Long",
46    "Ampersands",
47    "Newlines",
48};
49
50const char* kElidingBehaviors[] = {
51    "Ellipsis",
52    "None",
53    "Fade Tail",
54    "Fade Head",
55};
56
57const char* kPrefixOptions[] = {
58    "Default",
59    "Show",
60    "Hide",
61};
62
63const char* kHorizontalAligments[] = {
64    "Default",
65    "Left",
66    "Center",
67    "Right",
68};
69
70// Toggles bit |flag| on |flags| based on state of |checkbox|.
71void SetFlagFromCheckbox(Checkbox* checkbox, int* flags, int flag) {
72  if (checkbox->checked())
73    *flags |= flag;
74  else
75    *flags &= ~flag;
76}
77
78}  // namespace
79
80// TextExample's content view, which is responsible for drawing a string with
81// the specified style.
82class TextExample::TextExampleView : public View {
83 public:
84  TextExampleView()
85    : text_(ASCIIToUTF16(kShortText)),
86      text_flags_(0),
87      halo_(false),
88      fade_(false),
89      fade_mode_(gfx::Canvas::TruncateFadeTail) {
90  }
91
92  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
93    View::OnPaint(canvas);
94    const gfx::Rect bounds = GetContentsBounds();
95
96    if (fade_) {
97      canvas->DrawFadeTruncatingStringRect(text_, fade_mode_, font_list_,
98                                           SK_ColorDKGRAY, bounds);
99    } else if (halo_) {
100      canvas->DrawStringRectWithHalo(text_, font_list_, SK_ColorDKGRAY,
101                                     SK_ColorWHITE, bounds, text_flags_);
102    } else {
103      canvas->DrawStringRectWithFlags(text_, font_list_, SK_ColorDKGRAY, bounds,
104                                      text_flags_);
105    }
106  }
107
108  int text_flags() const { return text_flags_; }
109  void set_text_flags(int text_flags) { text_flags_ = text_flags; }
110
111  const string16& text() const { return text_; }
112  void set_text(const string16& text) { text_ = text; }
113
114  bool halo() const { return halo_; }
115  void set_halo(bool halo) { halo_ = halo; }
116
117  bool fade() const { return fade_; }
118  void set_fade(bool fade) { fade_ = fade; }
119
120  gfx::Canvas::TruncateFadeMode fade_mode() const { return fade_mode_; }
121  void set_fade_mode(gfx::Canvas::TruncateFadeMode mode) { fade_mode_ = mode; }
122
123  int GetFontStyle() const {
124    return font_list_.GetFontStyle();
125  }
126  void SetFontStyle(int style) {
127    font_list_ = font_list_.DeriveFontList(style);
128  }
129
130 private:
131  // The font used for drawing the text.
132  gfx::FontList font_list_;
133
134  // The text to draw.
135  string16 text_;
136
137  // Text flags for passing to |DrawStringInt()|.
138  int text_flags_;
139
140  // If |true|, specifies to call |DrawStringWithHalo()| instead of
141  // |DrawStringInt()|.
142  bool halo_;
143
144  // If |true|, specifies to call |DrawFadeTruncatingString()| instead of
145  // |DrawStringInt()|.
146  bool fade_;
147
148  // If |fade_| is |true|, fade mode parameter to |DrawFadeTruncatingString()|.
149  gfx::Canvas::TruncateFadeMode fade_mode_;
150
151  DISALLOW_COPY_AND_ASSIGN(TextExampleView);
152};
153
154TextExample::TextExample() : ExampleBase("Text Styles") {
155}
156
157TextExample::~TextExample() {
158  // Remove all the views first as some reference models in
159  // |example_combobox_model_|.
160  container()->RemoveAllChildViews(true);
161}
162
163Checkbox* TextExample::AddCheckbox(GridLayout* layout, const char* name) {
164  Checkbox* checkbox = new Checkbox(ASCIIToUTF16(name));
165  checkbox->set_listener(this);
166  layout->AddView(checkbox);
167  return checkbox;
168}
169
170Combobox* TextExample::AddCombobox(GridLayout* layout,
171                                   const char* name,
172                                   const char** strings,
173                                   int count) {
174  layout->StartRow(0, 0);
175  layout->AddView(new Label(ASCIIToUTF16(name)));
176  ExampleComboboxModel* combobox_model = new ExampleComboboxModel(strings,
177                                                                  count);
178  example_combobox_model_.push_back(combobox_model);
179  Combobox* combobox = new Combobox(combobox_model);
180  combobox->SetSelectedIndex(0);
181  combobox->set_listener(this);
182  layout->AddView(combobox, kNumColumns - 1, 1);
183  return combobox;
184}
185
186void TextExample::CreateExampleView(View* container) {
187  text_view_ = new TextExampleView;
188  text_view_->set_border(Border::CreateSolidBorder(1, SK_ColorGRAY));
189
190  GridLayout* layout = new GridLayout(container);
191  container->SetLayoutManager(layout);
192
193  layout->AddPaddingRow(0, 8);
194
195  ColumnSet* column_set = layout->AddColumnSet(0);
196  column_set->AddPaddingColumn(0, 8);
197  column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL,
198                        0.1f, GridLayout::USE_PREF, 0, 0);
199  for (int i = 0; i < kNumColumns - 1; i++)
200    column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
201                          0.1f, GridLayout::USE_PREF, 0, 0);
202  column_set->AddPaddingColumn(0, 8);
203
204  h_align_cb_ = AddCombobox(layout,
205                            "H-Align",
206                            kHorizontalAligments,
207                            arraysize(kHorizontalAligments));
208  eliding_cb_ = AddCombobox(layout,
209                            "Eliding",
210                            kElidingBehaviors,
211                            arraysize(kElidingBehaviors));
212  prefix_cb_ = AddCombobox(layout,
213                           "Prefix",
214                           kPrefixOptions,
215                           arraysize(kPrefixOptions));
216  text_cb_ = AddCombobox(layout,
217                         "Example Text",
218                         kTextExamples,
219                         arraysize(kTextExamples));
220
221  layout->StartRow(0, 0);
222  multiline_checkbox_ = AddCheckbox(layout, "Multiline");
223  break_checkbox_ = AddCheckbox(layout, "Character Break");
224  halo_checkbox_ = AddCheckbox(layout, "Text Halo");
225  bold_checkbox_ = AddCheckbox(layout, "Bold");
226  italic_checkbox_ = AddCheckbox(layout, "Italic");
227  underline_checkbox_ = AddCheckbox(layout, "Underline");
228
229  layout->AddPaddingRow(0, 32);
230
231  column_set = layout->AddColumnSet(1);
232  column_set->AddPaddingColumn(0, 16);
233  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
234                        1, GridLayout::USE_PREF, 0, 0);
235  column_set->AddPaddingColumn(0, 16);
236  layout->StartRow(1, 1);
237  layout->AddView(text_view_);
238
239  layout->AddPaddingRow(0, 8);
240}
241
242void TextExample::ButtonPressed(Button* button, const ui::Event& event) {
243  int flags = text_view_->text_flags();
244  int style = text_view_->GetFontStyle();
245  SetFlagFromCheckbox(multiline_checkbox_, &flags, gfx::Canvas::MULTI_LINE);
246  SetFlagFromCheckbox(break_checkbox_, &flags, gfx::Canvas::CHARACTER_BREAK);
247  SetFlagFromCheckbox(bold_checkbox_, &style, gfx::Font::BOLD);
248  SetFlagFromCheckbox(italic_checkbox_, &style, gfx::Font::ITALIC);
249  SetFlagFromCheckbox(underline_checkbox_, &style, gfx::Font::UNDERLINE);
250  text_view_->set_halo(halo_checkbox_->checked());
251  text_view_->set_text_flags(flags);
252  text_view_->SetFontStyle(style);
253  text_view_->SchedulePaint();
254}
255
256void TextExample::OnSelectedIndexChanged(Combobox* combobox) {
257  int text_flags = text_view_->text_flags();
258  if (combobox == h_align_cb_) {
259    text_flags &= ~(gfx::Canvas::TEXT_ALIGN_LEFT |
260                    gfx::Canvas::TEXT_ALIGN_CENTER |
261                    gfx::Canvas::TEXT_ALIGN_RIGHT);
262    switch (combobox->selected_index()) {
263      case 0:
264        break;
265      case 1:
266        text_flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
267        break;
268      case 2:
269        text_flags |= gfx::Canvas::TEXT_ALIGN_CENTER;
270        break;
271      case 3:
272        text_flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
273        break;
274    }
275  } else if (combobox == text_cb_) {
276    switch (combobox->selected_index()) {
277      case 0:
278        text_view_->set_text(ASCIIToUTF16(kShortText));
279        break;
280      case 1:
281        text_view_->set_text(ASCIIToUTF16(kMediumText));
282        break;
283      case 2:
284        text_view_->set_text(ASCIIToUTF16(kLongText));
285        break;
286      case 3:
287        text_view_->set_text(ASCIIToUTF16(kAmpersandText));
288        break;
289      case 4:
290        text_view_->set_text(ASCIIToUTF16(kNewlineText));
291        break;
292    }
293  } else if (combobox == eliding_cb_) {
294    switch (combobox->selected_index()) {
295      case 0:
296        text_flags &= ~gfx::Canvas::NO_ELLIPSIS;
297        text_view_->set_fade(false);
298        break;
299      case 1:
300        text_flags |= gfx::Canvas::NO_ELLIPSIS;
301        text_view_->set_fade(false);
302        break;
303      case 2:
304        text_view_->set_fade_mode(gfx::Canvas::TruncateFadeTail);
305        text_view_->set_fade(true);
306        break;
307      case 3:
308        text_view_->set_fade_mode(gfx::Canvas::TruncateFadeHead);
309        text_view_->set_fade(true);
310        break;
311    }
312  } else if (combobox == prefix_cb_) {
313    text_flags &= ~(gfx::Canvas::SHOW_PREFIX | gfx::Canvas::HIDE_PREFIX);
314    switch (combobox->selected_index()) {
315      case 0:
316        break;
317      case 1:
318        text_flags |= gfx::Canvas::SHOW_PREFIX;
319        break;
320      case 2:
321        text_flags |= gfx::Canvas::HIDE_PREFIX;
322        break;
323    }
324  }
325  text_view_->set_text_flags(text_flags);
326  text_view_->SchedulePaint();
327}
328
329}  // namespace examples
330}  // namespace views
331