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