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/oak/oak_window.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "grit/ui_resources.h" 9 #include "ui/aura/root_window.h" 10 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/gfx/canvas.h" 12 #include "ui/gfx/image/image.h" 13 #include "ui/oak/oak.h" 14 #include "ui/oak/oak_aura_window_display.h" 15 #include "ui/views/controls/table/table_view.h" 16 #include "ui/views/controls/tree/tree_view.h" 17 #include "ui/views/layout/layout_constants.h" 18 #include "ui/views/widget/widget.h" 19 20 namespace oak { 21 namespace internal { 22 namespace { 23 const SkColor kBorderColor = SkColorSetRGB(0xCC, 0xCC, 0xCC); 24 } // namespace 25 26 // static 27 views::Widget* OakWindow::instance = NULL; 28 29 //////////////////////////////////////////////////////////////////////////////// 30 // OakWindow, public: 31 32 OakWindow::OakWindow() : tree_container_(NULL) {} 33 34 OakWindow::~OakWindow() { 35 // The tree/table need to be destroyed before the model. 36 tree_.reset(); 37 details_.reset(); 38 } 39 40 //////////////////////////////////////////////////////////////////////////////// 41 // OakWindow, views::WidgetDelegateView implementation: 42 43 bool OakWindow::CanResize() const { 44 return true; 45 } 46 47 bool OakWindow::CanMaximize() const { 48 return true; 49 } 50 51 base::string16 OakWindow::GetWindowTitle() const { 52 return ASCIIToUTF16("Oak"); 53 } 54 55 views::View* OakWindow::GetContentsView() { 56 return this; 57 } 58 59 gfx::ImageSkia OakWindow::GetWindowIcon() { 60 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 61 return *rb.GetImageNamed(IDR_OAK).ToImageSkia(); 62 } 63 64 bool OakWindow::ShouldShowWindowIcon() const { 65 return true; 66 } 67 68 void OakWindow::DeleteDelegate() { 69 instance = NULL; 70 delete this; 71 } 72 73 //////////////////////////////////////////////////////////////////////////////// 74 // OakWindow, views::View overrides: 75 76 void OakWindow::OnPaint(gfx::Canvas* canvas) { 77 canvas->DrawColor(SK_ColorWHITE); 78 canvas->FillRect(separator_rect_, kBorderColor); 79 } 80 81 void OakWindow::ViewHierarchyChanged( 82 const ViewHierarchyChangedDetails& details) { 83 if (details.is_add && details.child == this) 84 Init(); 85 } 86 87 void OakWindow::Layout() { 88 gfx::Rect content_bounds = GetLocalBounds(); 89 content_bounds.Inset(views::kPanelHorizMargin, views::kPanelVertMargin); 90 91 int tree_height = 92 (content_bounds.height() / 2) - views::kUnrelatedControlVerticalSpacing; 93 gfx::Rect tree_bounds = content_bounds; 94 tree_bounds.set_height(tree_height); 95 tree_container_->SetBoundsRect(tree_bounds); 96 97 separator_rect_ = content_bounds; 98 separator_rect_.set_y( 99 tree_bounds.bottom() + views::kRelatedControlVerticalSpacing); 100 separator_rect_.set_height(1); 101 102 gfx::Rect details_bounds = content_bounds; 103 details_bounds.set_y( 104 separator_rect_.bottom() + views::kRelatedControlVerticalSpacing); 105 details_bounds.set_height(content_bounds.bottom() - details_bounds.y()); 106 details_container_->SetBoundsRect(details_bounds); 107 } 108 109 //////////////////////////////////////////////////////////////////////////////// 110 // OakWindow, views::TreeViewController implementation: 111 112 void OakWindow::OnTreeViewSelectionChanged(views::TreeView* tree) { 113 details_model_->SetValue(tree_model_->AsNode(tree->GetSelectedNode())->value); 114 } 115 116 //////////////////////////////////////////////////////////////////////////////// 117 // OakWindow, private: 118 119 void OakWindow::Init() { 120 tree_model_.reset( 121 GenerateModel(GetWidget()->GetNativeView()->GetRootWindow())); 122 tree_.reset(new views::TreeView); 123 tree_->set_owned_by_client(); 124 tree_->SetController(this); 125 tree_->SetModel(tree_model_.get()); 126 tree_container_ = tree_->CreateParentIfNecessary(); 127 AddChildView(tree_container_); 128 129 details_model_.reset(new OakAuraWindowDisplay); 130 std::vector<ui::TableColumn> columns; 131 columns.push_back(ui::TableColumn()); 132 details_.reset(new views::TableView(details_model_.get(), 133 columns, 134 views::TEXT_ONLY, 135 true)); 136 details_->set_owned_by_client(); 137 details_container_ = details_->CreateParentIfNecessary(); 138 details_->SetModel(details_model_.get()); 139 AddChildView(details_container_); 140 141 OnTreeViewSelectionChanged(tree_.get()); 142 } 143 144 } // namespace internal 145 146 void ShowOakWindowWithContext(gfx::NativeView context) { 147 if (!internal::OakWindow::instance) { 148 // TODO(erg): Do we want to reuse this window in times with a different 149 // context? For now, this is OK, but if we ever use Oak outside of the ash 150 // shell, we run into crbug.com/165759. 151 internal::OakWindow::instance = 152 views::Widget::CreateWindowWithContextAndBounds( 153 new internal::OakWindow, context, gfx::Rect(10, 10, 500, 500)); 154 } 155 internal::OakWindow::instance->Show(); 156 } 157 158 } // namespace oak 159