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