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.
5 #include "ui/views/examples/multiline_example.h"
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"
18 using base::ASCIIToUTF16
;
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
));
31 // A Label with a clamped preferred width to demonstrate wrapping.
32 class PreferredSizeLabel
: public Label
{
34 PreferredSizeLabel() : Label() {}
35 ~PreferredSizeLabel() override
{}
38 gfx::Size
GetPreferredSize() const override
{
39 return gfx::Size(50, Label::GetPreferredSize().height());
43 DISALLOW_COPY_AND_ASSIGN(PreferredSizeLabel
);
48 // A simple View that hosts a RenderText object.
49 class MultilineExample::RenderTextView
: public View
{
51 RenderTextView() : render_text_(gfx::RenderText::CreateInstanceForEditing()) {
52 render_text_
->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD
);
53 render_text_
->SetColor(SK_ColorBLACK
);
54 render_text_
->SetMultiline(true);
55 SetBorder(Border::CreateSolidBorder(2, SK_ColorGRAY
));
58 void OnPaint(gfx::Canvas
* canvas
) override
{
59 View::OnPaint(canvas
);
60 render_text_
->Draw(canvas
);
63 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);
74 int GetHeightForWidth(int w
) const override
{
75 // TODO(ckocagil): Why does this happen?
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
);
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
);
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
);
107 void OnBoundsChanged(const gfx::Rect
& previous_bounds
) override
{
108 gfx::Rect bounds
= GetLocalBounds();
109 bounds
.Inset(GetInsets());
110 render_text_
->SetDisplayRect(bounds
);
113 scoped_ptr
<gfx::RenderText
> render_text_
;
115 DISALLOW_COPY_AND_ASSIGN(RenderTextView
);
118 MultilineExample::MultilineExample()
119 : ExampleBase("Multiline RenderText"),
120 render_text_view_(NULL
),
123 label_checkbox_(NULL
) {
126 MultilineExample::~MultilineExample() {
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"
134 render_text_view_
= new RenderTextView();
135 render_text_view_
->SetText(kTestString
);
137 label_
= new PreferredSizeLabel();
138 label_
->SetText(kTestString
);
139 label_
->SetMultiLine(true);
140 label_
->SetBorder(Border::CreateSolidBorder(2, SK_ColorCYAN
));
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);
147 textfield_
= new Textfield();
148 textfield_
->set_controller(this);
149 textfield_
->SetText(kTestString
);
151 GridLayout
* layout
= new GridLayout(container
);
152 container
->SetLayoutManager(layout
);
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);
160 layout
->StartRow(0, 0);
161 layout
->AddView(new Label(ASCIIToUTF16("gfx::RenderText:")));
162 layout
->AddView(render_text_view_
);
164 layout
->StartRow(0, 0);
165 layout
->AddView(label_checkbox_
);
166 layout
->AddView(label_
);
168 layout
->StartRow(0, 0);
169 layout
->AddView(new Label(ASCIIToUTF16("Sample Text:")));
170 layout
->AddView(textfield_
);
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();
182 void MultilineExample::ButtonPressed(Button
* sender
, const ui::Event
& event
) {
183 DCHECK_EQ(sender
, label_checkbox_
);
184 label_
->SetText(label_checkbox_
->checked() ? textfield_
->text() :
186 container()->Layout();
187 container()->SchedulePaint();
190 } // namespace examples