1 // Copyright (c) 2012 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/examples_window.h" 6 7 #include <algorithm> 8 #include <string> 9 10 #include "base/memory/scoped_vector.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "ui/base/models/combobox_model.h" 13 #include "ui/base/ui_base_paths.h" 14 #include "ui/views/background.h" 15 #include "ui/views/controls/combobox/combobox.h" 16 #include "ui/views/controls/label.h" 17 #include "ui/views/examples/bubble_example.h" 18 #include "ui/views/examples/button_example.h" 19 #include "ui/views/examples/checkbox_example.h" 20 #include "ui/views/examples/combobox_example.h" 21 #include "ui/views/examples/double_split_view_example.h" 22 #include "ui/views/examples/label_example.h" 23 #include "ui/views/examples/link_example.h" 24 #include "ui/views/examples/menu_example.h" 25 #include "ui/views/examples/message_box_example.h" 26 #include "ui/views/examples/multiline_example.h" 27 #include "ui/views/examples/progress_bar_example.h" 28 #include "ui/views/examples/radio_button_example.h" 29 #include "ui/views/examples/scroll_view_example.h" 30 #include "ui/views/examples/single_split_view_example.h" 31 #include "ui/views/examples/slider_example.h" 32 #include "ui/views/examples/tabbed_pane_example.h" 33 #include "ui/views/examples/table_example.h" 34 #include "ui/views/examples/text_example.h" 35 #include "ui/views/examples/textfield_example.h" 36 #include "ui/views/examples/throbber_example.h" 37 #include "ui/views/examples/tree_view_example.h" 38 #include "ui/views/examples/widget_example.h" 39 #include "ui/views/layout/fill_layout.h" 40 #include "ui/views/layout/grid_layout.h" 41 #include "ui/views/widget/widget.h" 42 #include "ui/views/widget/widget_delegate.h" 43 44 namespace views { 45 namespace examples { 46 47 typedef scoped_ptr<ScopedVector<ExampleBase> > ScopedExamples; 48 49 namespace { 50 51 // Creates the default set of examples. Caller owns the result. 52 ScopedExamples CreateExamples() { 53 ScopedExamples examples(new ScopedVector<ExampleBase>); 54 examples->push_back(new BubbleExample); 55 examples->push_back(new ButtonExample); 56 examples->push_back(new CheckboxExample); 57 examples->push_back(new ComboboxExample); 58 examples->push_back(new DoubleSplitViewExample); 59 examples->push_back(new LabelExample); 60 examples->push_back(new LinkExample); 61 examples->push_back(new MenuExample); 62 examples->push_back(new MessageBoxExample); 63 examples->push_back(new MultilineExample); 64 examples->push_back(new ProgressBarExample); 65 examples->push_back(new RadioButtonExample); 66 examples->push_back(new ScrollViewExample); 67 examples->push_back(new SingleSplitViewExample); 68 examples->push_back(new SliderExample); 69 examples->push_back(new TabbedPaneExample); 70 examples->push_back(new TableExample); 71 examples->push_back(new TextExample); 72 examples->push_back(new TextfieldExample); 73 examples->push_back(new ThrobberExample); 74 examples->push_back(new TreeViewExample); 75 examples->push_back(new WidgetExample); 76 return examples.Pass(); 77 } 78 79 struct ExampleTitleCompare { 80 bool operator() (ExampleBase* a, ExampleBase* b) { 81 return a->example_title() < b->example_title(); 82 } 83 }; 84 85 ScopedExamples GetExamplesToShow(ScopedExamples extra) { 86 ScopedExamples examples(CreateExamples()); 87 if (extra.get()) { 88 examples->insert(examples->end(), extra->begin(), extra->end()); 89 extra->weak_clear(); 90 } 91 std::sort(examples->begin(), examples->end(), ExampleTitleCompare()); 92 return examples.Pass(); 93 } 94 95 } // namespace 96 97 // Model for the examples that are being added via AddExample(). 98 class ComboboxModelExampleList : public ui::ComboboxModel { 99 public: 100 ComboboxModelExampleList() {} 101 virtual ~ComboboxModelExampleList() {} 102 103 void SetExamples(ScopedExamples examples) { 104 example_list_.swap(*examples); 105 } 106 107 // ui::ComboboxModel: 108 virtual int GetItemCount() const OVERRIDE { return example_list_.size(); } 109 virtual base::string16 GetItemAt(int index) OVERRIDE { 110 return base::UTF8ToUTF16(example_list_[index]->example_title()); 111 } 112 113 View* GetItemViewAt(int index) { 114 return example_list_[index]->example_view(); 115 } 116 117 private: 118 ScopedVector<ExampleBase> example_list_; 119 120 DISALLOW_COPY_AND_ASSIGN(ComboboxModelExampleList); 121 }; 122 123 class ExamplesWindowContents : public WidgetDelegateView, 124 public ComboboxListener { 125 public: 126 ExamplesWindowContents(Operation operation, ScopedExamples examples) 127 : combobox_(new Combobox(&combobox_model_)), 128 example_shown_(new View), 129 status_label_(new Label), 130 operation_(operation) { 131 instance_ = this; 132 combobox_->set_listener(this); 133 combobox_model_.SetExamples(examples.Pass()); 134 combobox_->ModelChanged(); 135 136 set_background(Background::CreateStandardPanelBackground()); 137 GridLayout* layout = new GridLayout(this); 138 SetLayoutManager(layout); 139 ColumnSet* column_set = layout->AddColumnSet(0); 140 column_set->AddPaddingColumn(0, 5); 141 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, 142 GridLayout::USE_PREF, 0, 0); 143 column_set->AddPaddingColumn(0, 5); 144 layout->AddPaddingRow(0, 5); 145 layout->StartRow(0 /* no expand */, 0); 146 layout->AddView(combobox_); 147 148 if (combobox_model_.GetItemCount() > 0) { 149 layout->StartRow(1, 0); 150 example_shown_->SetLayoutManager(new FillLayout()); 151 example_shown_->AddChildView(combobox_model_.GetItemViewAt(0)); 152 layout->AddView(example_shown_); 153 } 154 155 layout->StartRow(0 /* no expand */, 0); 156 layout->AddView(status_label_); 157 layout->AddPaddingRow(0, 5); 158 } 159 160 virtual ~ExamplesWindowContents() { 161 // Delete |combobox_| first as it references |combobox_model_|. 162 delete combobox_; 163 combobox_ = NULL; 164 } 165 166 // Prints a message in the status area, at the bottom of the window. 167 void SetStatus(const std::string& status) { 168 status_label_->SetText(base::UTF8ToUTF16(status)); 169 } 170 171 static ExamplesWindowContents* instance() { return instance_; } 172 173 private: 174 // WidgetDelegateView: 175 virtual bool CanResize() const OVERRIDE { return true; } 176 virtual bool CanMaximize() const OVERRIDE { return true; } 177 virtual base::string16 GetWindowTitle() const OVERRIDE { 178 return base::ASCIIToUTF16("Views Examples"); 179 } 180 virtual View* GetContentsView() OVERRIDE { return this; } 181 virtual void WindowClosing() OVERRIDE { 182 instance_ = NULL; 183 if (operation_ == QUIT_ON_CLOSE) 184 base::MessageLoopForUI::current()->Quit(); 185 } 186 187 // ComboboxListener: 188 virtual void OnPerformAction(Combobox* combobox) OVERRIDE { 189 DCHECK_EQ(combobox, combobox_); 190 DCHECK(combobox->selected_index() < combobox_model_.GetItemCount()); 191 example_shown_->RemoveAllChildViews(false); 192 example_shown_->AddChildView(combobox_model_.GetItemViewAt( 193 combobox->selected_index())); 194 example_shown_->RequestFocus(); 195 SetStatus(std::string()); 196 Layout(); 197 } 198 199 static ExamplesWindowContents* instance_; 200 ComboboxModelExampleList combobox_model_; 201 Combobox* combobox_; 202 View* example_shown_; 203 Label* status_label_; 204 const Operation operation_; 205 206 DISALLOW_COPY_AND_ASSIGN(ExamplesWindowContents); 207 }; 208 209 // static 210 ExamplesWindowContents* ExamplesWindowContents::instance_ = NULL; 211 212 void ShowExamplesWindow(Operation operation, 213 gfx::NativeView window_context, 214 ScopedExamples extra_examples) { 215 if (ExamplesWindowContents::instance()) { 216 ExamplesWindowContents::instance()->GetWidget()->Activate(); 217 } else { 218 ScopedExamples examples(GetExamplesToShow(extra_examples.Pass())); 219 Widget* widget = new Widget; 220 Widget::InitParams params; 221 params.delegate = new ExamplesWindowContents(operation, examples.Pass()); 222 params.context = window_context; 223 params.bounds = gfx::Rect(0, 0, 850, 300); 224 params.remove_standard_frame = true; 225 widget->Init(params); 226 widget->Show(); 227 } 228 } 229 230 void LogStatus(const std::string& string) { 231 ExamplesWindowContents::instance()->SetStatus(string); 232 } 233 234 } // namespace examples 235 } // namespace views 236