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