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