17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/examples/multiline_example.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/utf_string_conversions.h"
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gfx/render_text.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/background.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/border.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/controls/label.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/view.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace views {
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace examples {
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// A simple View that hosts a RenderText object.
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class MultilineExample::RenderTextView : public View {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderTextView() : render_text_(gfx::RenderText::CreateInstance()) {
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    render_text_->SetColor(SK_ColorBLACK);
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetMultiline(true);
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    set_border(Border::CreateSolidBorder(2, SK_ColorGRAY));
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    View::OnPaint(canvas);
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    render_text_->Draw(canvas);
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE {
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Turn off multiline mode to get the single-line text size, which is the
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // preferred size for this view.
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetMultiline(false);
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::Size size(render_text_->GetContentWidth(),
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                   render_text_->GetStringSize().height());
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    size.Enlarge(GetInsets().width(), GetInsets().height());
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetMultiline(true);
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return size;
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual int GetHeightForWidth(int w) OVERRIDE {
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(ckocagil): Why does this happen?
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (w == 0)
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return View::GetHeightForWidth(w);
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const gfx::Rect old_rect = render_text_->display_rect();
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Rect rect = old_rect;
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    rect.set_width(w - GetInsets().width());
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetDisplayRect(rect);
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int height = render_text_->GetStringSize().height() + GetInsets().height();
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    render_text_->SetDisplayRect(old_rect);
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return height;
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetText(const string16& new_contents) {
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Color and style the text inside |test_range| to test colors and styles.
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::Range test_range(1, 21);
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    test_range.set_start(std::min(test_range.start(), new_contents.length()));
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    test_range.set_end(std::min(test_range.end(), new_contents.length()));
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    render_text_->SetText(new_contents);
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetColor(SK_ColorBLACK);
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->ApplyColor(0xFFFF0000, test_range);
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetStyle(gfx::DIAGONAL_STRIKE, false);
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->ApplyStyle(gfx::DIAGONAL_STRIKE, true, test_range);
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->SetStyle(gfx::UNDERLINE, false);
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_text_->ApplyStyle(gfx::UNDERLINE, true, test_range);
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    InvalidateLayout();
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gfx::Rect bounds = GetLocalBounds();
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bounds.Inset(GetInsets());
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    render_text_->SetDisplayRect(bounds);
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<gfx::RenderText> render_text_;
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RenderTextView);
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)MultilineExample::MultilineExample()
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : ExampleBase("Multiline RenderText"),
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      render_text_view_(NULL),
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      label_(NULL),
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      textfield_(NULL),
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      label_checkbox_(NULL) {
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)MultilineExample::~MultilineExample() {
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MultilineExample::CreateExampleView(View* container) {
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const char kTestString[] = "test string asdf 1234 test string asdf 1234 "
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             "test string asdf 1234 test string asdf 1234";
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  render_text_view_ = new RenderTextView();
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  render_text_view_->SetText(ASCIIToUTF16(kTestString));
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  label_ = new Label();
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  label_->SetText(ASCIIToUTF16(kTestString));
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  label_->SetMultiLine(true);
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  label_->set_border(Border::CreateSolidBorder(2, SK_ColorCYAN));
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  label_checkbox_ = new Checkbox(ASCIIToUTF16("views::Label:"));
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  label_checkbox_->SetChecked(true);
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  label_checkbox_->set_listener(this);
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  label_checkbox_->set_request_focus_on_press(false);
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  textfield_ = new Textfield();
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  textfield_->SetController(this);
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  textfield_->SetText(ASCIIToUTF16(kTestString));
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GridLayout* layout = new GridLayout(container);
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  container->SetLayoutManager(layout);
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ColumnSet* column_set = layout->AddColumnSet(0);
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      0.0f, GridLayout::USE_PREF, 0, 0);
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      1.0f, GridLayout::FIXED, 0, 0);
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->StartRow(0, 0);
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->AddView(new Label(ASCIIToUTF16("gfx::RenderText:")));
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->AddView(render_text_view_);
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->StartRow(0, 0);
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  layout->AddView(label_checkbox_);
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->AddView(label_);
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->StartRow(0, 0);
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->AddView(new Label(ASCIIToUTF16("Sample Text:")));
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layout->AddView(textfield_);
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MultilineExample::ContentsChanged(Textfield* sender,
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       const string16& new_contents) {
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  render_text_view_->SetText(new_contents);
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (label_checkbox_->checked())
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    label_->SetText(new_contents);
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  container()->Layout();
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  container()->SchedulePaint();
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MultilineExample::HandleKeyEvent(Textfield* sender,
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      const ui::KeyEvent& key_event) {
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return false;
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MultilineExample::ButtonPressed(Button* sender, const ui::Event& event) {
156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_EQ(sender, label_checkbox_);
157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  label_->SetText(label_checkbox_->checked() ? textfield_->text() : string16());
158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  container()->Layout();
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  container()->SchedulePaint();
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace examples
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace views
164