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/tree_view_example.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "ui/views/controls/button/label_button.h" 9 #include "ui/views/controls/menu/menu_model_adapter.h" 10 #include "ui/views/controls/menu/menu_runner.h" 11 #include "ui/views/controls/tree/tree_view.h" 12 #include "ui/views/layout/grid_layout.h" 13 14 using base::ASCIIToUTF16; 15 16 namespace views { 17 namespace examples { 18 19 TreeViewExample::TreeViewExample() 20 : ExampleBase("Tree View"), 21 tree_view_(NULL), 22 model_(new NodeType(ASCIIToUTF16("root"), 1)) { 23 } 24 25 TreeViewExample::~TreeViewExample() { 26 // Delete the view before the model. 27 delete tree_view_; 28 tree_view_ = NULL; 29 } 30 31 void TreeViewExample::CreateExampleView(View* container) { 32 // Add some sample data. 33 NodeType* colors_node = new NodeType(ASCIIToUTF16("colors"), 1); 34 model_.GetRoot()->Add(colors_node, 0); 35 colors_node->Add(new NodeType(ASCIIToUTF16("red"), 1), 0); 36 colors_node->Add(new NodeType(ASCIIToUTF16("green"), 1), 1); 37 colors_node->Add(new NodeType(ASCIIToUTF16("blue"), 1), 2); 38 39 NodeType* sheep_node = new NodeType(ASCIIToUTF16("sheep"), 1); 40 model_.GetRoot()->Add(sheep_node, 0); 41 sheep_node->Add(new NodeType(ASCIIToUTF16("Sheep 1"), 1), 0); 42 sheep_node->Add(new NodeType(ASCIIToUTF16("Sheep 2"), 1), 1); 43 44 tree_view_ = new TreeView(); 45 tree_view_->set_context_menu_controller(this); 46 tree_view_->SetRootShown(false); 47 tree_view_->SetModel(&model_); 48 tree_view_->SetController(this); 49 add_ = new LabelButton(this, ASCIIToUTF16("Add")); 50 add_->SetFocusable(true); 51 remove_ = new LabelButton(this, ASCIIToUTF16("Remove")); 52 remove_->SetFocusable(true); 53 change_title_ = new LabelButton(this, ASCIIToUTF16("Change Title")); 54 change_title_->SetFocusable(true); 55 56 GridLayout* layout = new GridLayout(container); 57 container->SetLayoutManager(layout); 58 59 const int tree_view_column = 0; 60 ColumnSet* column_set = layout->AddColumnSet(tree_view_column); 61 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 62 1.0f, GridLayout::USE_PREF, 0, 0); 63 layout->StartRow(1 /* expand */, tree_view_column); 64 layout->AddView(tree_view_->CreateParentIfNecessary()); 65 66 // Add control buttons horizontally. 67 const int button_column = 1; 68 column_set = layout->AddColumnSet(button_column); 69 for (int i = 0; i < 3; i++) { 70 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 71 1.0f, GridLayout::USE_PREF, 0, 0); 72 } 73 74 layout->StartRow(0 /* no expand */, button_column); 75 layout->AddView(add_); 76 layout->AddView(remove_); 77 layout->AddView(change_title_); 78 } 79 80 void TreeViewExample::AddNewNode() { 81 NodeType* selected_node = 82 static_cast<NodeType*>(tree_view_->GetSelectedNode()); 83 if (!selected_node) 84 selected_node = model_.GetRoot(); 85 NodeType* new_node = new NodeType(selected_node->GetTitle(), 1); 86 model_.Add(selected_node, new_node, selected_node->child_count()); 87 tree_view_->SetSelectedNode(new_node); 88 } 89 90 bool TreeViewExample::IsCommandIdEnabled(int command_id) { 91 return command_id != ID_REMOVE || 92 tree_view_->GetSelectedNode() != model_.GetRoot(); 93 } 94 95 void TreeViewExample::ButtonPressed(Button* sender, const ui::Event& event) { 96 NodeType* selected_node = 97 static_cast<NodeType*>(tree_view_->GetSelectedNode()); 98 if (sender == add_) { 99 AddNewNode(); 100 } else if (sender == remove_) { 101 DCHECK(selected_node); 102 DCHECK_NE(model_.GetRoot(), selected_node); 103 model_.Remove(selected_node->parent(), selected_node); 104 } else if (sender == change_title_) { 105 DCHECK(selected_node); 106 model_.SetTitle(selected_node, 107 selected_node->GetTitle() + ASCIIToUTF16("new")); 108 } 109 } 110 111 void TreeViewExample::OnTreeViewSelectionChanged(TreeView* tree_view) { 112 ui::TreeModelNode* node = tree_view_->GetSelectedNode(); 113 if (node) { 114 change_title_->SetEnabled(true); 115 remove_->SetEnabled(node != model_.GetRoot()); 116 } else { 117 change_title_->SetEnabled(false); 118 remove_->SetEnabled(false); 119 } 120 } 121 122 bool TreeViewExample::CanEdit(TreeView* tree_view, 123 ui::TreeModelNode* node) { 124 return true; 125 } 126 127 void TreeViewExample::ShowContextMenuForView(View* source, 128 const gfx::Point& point, 129 ui::MenuSourceType source_type) { 130 ui::SimpleMenuModel context_menu_model(this); 131 context_menu_model.AddItem(ID_EDIT, ASCIIToUTF16("Edit")); 132 context_menu_model.AddItem(ID_REMOVE, ASCIIToUTF16("Remove")); 133 context_menu_model.AddItem(ID_ADD, ASCIIToUTF16("Add")); 134 context_menu_runner_.reset(new MenuRunner(&context_menu_model)); 135 if (context_menu_runner_->RunMenuAt(source->GetWidget(), 136 NULL, 137 gfx::Rect(point, gfx::Size()), 138 MENU_ANCHOR_TOPLEFT, 139 source_type, 140 0) == MenuRunner::MENU_DELETED) { 141 return; 142 } 143 } 144 145 bool TreeViewExample::IsCommandIdChecked(int command_id) const { 146 return false; 147 } 148 149 bool TreeViewExample::IsCommandIdEnabled(int command_id) const { 150 return const_cast<TreeViewExample*>(this)->IsCommandIdEnabled(command_id); 151 } 152 153 bool TreeViewExample::GetAcceleratorForCommandId( 154 int command_id, 155 ui::Accelerator* accelerator) { 156 return false; 157 } 158 159 void TreeViewExample::ExecuteCommand(int command_id, int event_flags) { 160 NodeType* selected_node = 161 static_cast<NodeType*>(tree_view_->GetSelectedNode()); 162 switch (command_id) { 163 case ID_EDIT: 164 tree_view_->StartEditing(selected_node); 165 break; 166 case ID_REMOVE: 167 model_.Remove(selected_node->parent(), selected_node); 168 break; 169 case ID_ADD: 170 AddNewNode(); 171 break; 172 default: 173 NOTREACHED(); 174 } 175 } 176 177 } // namespace examples 178 } // namespace views 179