• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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/multiline_example.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/events/event.h"
9 #include "ui/gfx/render_text.h"
10 #include "ui/views/background.h"
11 #include "ui/views/border.h"
12 #include "ui/views/controls/button/checkbox.h"
13 #include "ui/views/controls/label.h"
14 #include "ui/views/controls/textfield/textfield.h"
15 #include "ui/views/layout/grid_layout.h"
16 #include "ui/views/view.h"
17 
18 using base::ASCIIToUTF16;
19 
20 namespace views {
21 namespace examples {
22 
23 namespace {
24 
ClampRange(gfx::Range range,size_t max)25 gfx::Range ClampRange(gfx::Range range, size_t max) {
26   range.set_start(std::min(range.start(), max));
27   range.set_end(std::min(range.end(), max));
28   return range;
29 }
30 
31 // A Label with a clamped preferred width to demonstrate wrapping.
32 class PreferredSizeLabel : public Label {
33  public:
PreferredSizeLabel()34   PreferredSizeLabel() : Label() {}
~PreferredSizeLabel()35   virtual ~PreferredSizeLabel() {}
36 
37   // Label:
GetPreferredSize() const38   virtual gfx::Size GetPreferredSize() const OVERRIDE {
39     return gfx::Size(50, Label::GetPreferredSize().height());
40   }
41 
42  private:
43   DISALLOW_COPY_AND_ASSIGN(PreferredSizeLabel);
44 };
45 
46 }  // namespace
47 
48 // A simple View that hosts a RenderText object.
49 class MultilineExample::RenderTextView : public View {
50  public:
RenderTextView()51   RenderTextView() : render_text_(gfx::RenderText::CreateInstance()) {
52     render_text_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
53     render_text_->SetColor(SK_ColorBLACK);
54     render_text_->SetMultiline(true);
55     SetBorder(Border::CreateSolidBorder(2, SK_ColorGRAY));
56   }
57 
OnPaint(gfx::Canvas * canvas)58   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
59     View::OnPaint(canvas);
60     render_text_->Draw(canvas);
61   }
62 
GetPreferredSize() const63   virtual gfx::Size GetPreferredSize() const OVERRIDE {
64     // Turn off multiline mode to get the single-line text size, which is the
65     // preferred size for this view.
66     render_text_->SetMultiline(false);
67     gfx::Size size(render_text_->GetContentWidth(),
68                    render_text_->GetStringSize().height());
69     size.Enlarge(GetInsets().width(), GetInsets().height());
70     render_text_->SetMultiline(true);
71     return size;
72   }
73 
GetHeightForWidth(int w) const74   virtual int GetHeightForWidth(int w) const OVERRIDE {
75     // TODO(ckocagil): Why does this happen?
76     if (w == 0)
77       return View::GetHeightForWidth(w);
78     const gfx::Rect old_rect = render_text_->display_rect();
79     gfx::Rect rect = old_rect;
80     rect.set_width(w - GetInsets().width());
81     render_text_->SetDisplayRect(rect);
82     int height = render_text_->GetStringSize().height() + GetInsets().height();
83     render_text_->SetDisplayRect(old_rect);
84     return height;
85   }
86 
SetText(const base::string16 & new_contents)87   void SetText(const base::string16& new_contents) {
88     // Color and style the text inside |test_range| to test colors and styles.
89     const size_t range_max = new_contents.length();
90     gfx::Range color_range = ClampRange(gfx::Range(1, 21), range_max);
91     gfx::Range bold_range = ClampRange(gfx::Range(4, 10), range_max);
92     gfx::Range italic_range = ClampRange(gfx::Range(7, 13), range_max);
93 
94     render_text_->SetText(new_contents);
95     render_text_->SetColor(SK_ColorBLACK);
96     render_text_->ApplyColor(0xFFFF0000, color_range);
97     render_text_->SetStyle(gfx::DIAGONAL_STRIKE, false);
98     render_text_->ApplyStyle(gfx::DIAGONAL_STRIKE, true, color_range);
99     render_text_->SetStyle(gfx::UNDERLINE, false);
100     render_text_->ApplyStyle(gfx::UNDERLINE, true, color_range);
101     render_text_->ApplyStyle(gfx::BOLD, true, bold_range);
102     render_text_->ApplyStyle(gfx::ITALIC, true, italic_range);
103     InvalidateLayout();
104   }
105 
106  private:
OnBoundsChanged(const gfx::Rect & previous_bounds)107   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
108     gfx::Rect bounds = GetLocalBounds();
109     bounds.Inset(GetInsets());
110     render_text_->SetDisplayRect(bounds);
111   }
112 
113   scoped_ptr<gfx::RenderText> render_text_;
114 
115   DISALLOW_COPY_AND_ASSIGN(RenderTextView);
116 };
117 
MultilineExample()118 MultilineExample::MultilineExample()
119     : ExampleBase("Multiline RenderText"),
120       render_text_view_(NULL),
121       label_(NULL),
122       textfield_(NULL),
123       label_checkbox_(NULL) {
124 }
125 
~MultilineExample()126 MultilineExample::~MultilineExample() {
127 }
128 
CreateExampleView(View * container)129 void MultilineExample::CreateExampleView(View* container) {
130   const base::string16 kTestString = base::WideToUTF16(L"qwerty"
131       L"\x627\x644\x631\x626\x64A\x633\x64A\x629"
132       L"asdfgh");
133 
134   render_text_view_ = new RenderTextView();
135   render_text_view_->SetText(kTestString);
136 
137   label_ = new PreferredSizeLabel();
138   label_->SetText(kTestString);
139   label_->SetMultiLine(true);
140   label_->SetBorder(Border::CreateSolidBorder(2, SK_ColorCYAN));
141 
142   label_checkbox_ = new Checkbox(ASCIIToUTF16("views::Label:"));
143   label_checkbox_->SetChecked(true);
144   label_checkbox_->set_listener(this);
145   label_checkbox_->set_request_focus_on_press(false);
146 
147   textfield_ = new Textfield();
148   textfield_->set_controller(this);
149   textfield_->SetText(kTestString);
150 
151   GridLayout* layout = new GridLayout(container);
152   container->SetLayoutManager(layout);
153 
154   ColumnSet* column_set = layout->AddColumnSet(0);
155   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
156       0.0f, GridLayout::USE_PREF, 0, 0);
157   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
158       1.0f, GridLayout::FIXED, 0, 0);
159 
160   layout->StartRow(0, 0);
161   layout->AddView(new Label(ASCIIToUTF16("gfx::RenderText:")));
162   layout->AddView(render_text_view_);
163 
164   layout->StartRow(0, 0);
165   layout->AddView(label_checkbox_);
166   layout->AddView(label_);
167 
168   layout->StartRow(0, 0);
169   layout->AddView(new Label(ASCIIToUTF16("Sample Text:")));
170   layout->AddView(textfield_);
171 }
172 
ContentsChanged(Textfield * sender,const base::string16 & new_contents)173 void MultilineExample::ContentsChanged(Textfield* sender,
174                                        const base::string16& new_contents) {
175   render_text_view_->SetText(new_contents);
176   if (label_checkbox_->checked())
177     label_->SetText(new_contents);
178   container()->Layout();
179   container()->SchedulePaint();
180 }
181 
ButtonPressed(Button * sender,const ui::Event & event)182 void MultilineExample::ButtonPressed(Button* sender, const ui::Event& event) {
183   DCHECK_EQ(sender, label_checkbox_);
184   label_->SetText(label_checkbox_->checked() ? textfield_->text() :
185                                                base::string16());
186   container()->Layout();
187   container()->SchedulePaint();
188 }
189 
190 }  // namespace examples
191 }  // namespace views
192