1 // Copyright 2014 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 "ash/test/child_modal_window.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "ui/aura/window.h" 9 #include "ui/gfx/canvas.h" 10 #include "ui/views/background.h" 11 #include "ui/views/controls/button/label_button.h" 12 #include "ui/views/controls/native/native_view_host.h" 13 #include "ui/views/controls/textfield/textfield.h" 14 #include "ui/views/widget/widget.h" 15 #include "ui/views/widget/widget_delegate.h" 16 #include "ui/wm/core/window_modality_controller.h" 17 18 using views::Widget; 19 20 namespace ash { 21 namespace test { 22 23 namespace { 24 25 // Parent window size and position. 26 const int kWindowLeft = 170; 27 const int kWindowTop = 200; 28 const int kWindowWidth = 400; 29 const int kWindowHeight = 400; 30 31 // Parent window layout. 32 const int kButtonHeight = 35; 33 const int kTextfieldHeight = 35; 34 35 // Child window size. 36 const int kChildWindowWidth = 330; 37 const int kChildWindowHeight = 200; 38 39 // Child window layout. 40 const int kChildTextfieldLeft = 20; 41 const int kChildTextfieldTop = 50; 42 const int kChildTextfieldWidth = 290; 43 const int kChildTextfieldHeight = 35; 44 45 const SkColor kModalParentColor = SK_ColorWHITE; 46 const SkColor kChildColor = SK_ColorWHITE; 47 48 } // namespace 49 50 void CreateChildModalParent(gfx::NativeView context) { 51 Widget::CreateWindowWithContextAndBounds( 52 new ChildModalParent(context), 53 context, 54 gfx::Rect(kWindowLeft, kWindowTop, kWindowWidth, kWindowHeight))->Show(); 55 } 56 57 58 class ChildModalWindow : public views::WidgetDelegateView { 59 public: 60 ChildModalWindow(); 61 virtual ~ChildModalWindow(); 62 63 private: 64 // Overridden from View: 65 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 66 virtual gfx::Size GetPreferredSize() const OVERRIDE; 67 68 // Overridden from WidgetDelegate: 69 virtual View* GetContentsView() OVERRIDE; 70 virtual base::string16 GetWindowTitle() const OVERRIDE; 71 virtual bool CanResize() const OVERRIDE; 72 virtual ui::ModalType GetModalType() const OVERRIDE; 73 74 DISALLOW_COPY_AND_ASSIGN(ChildModalWindow); 75 }; 76 77 ChildModalWindow::ChildModalWindow() { 78 views::Textfield* textfield = new views::Textfield; 79 AddChildView(textfield); 80 textfield->SetBounds( 81 kChildTextfieldLeft, kChildTextfieldTop, 82 kChildTextfieldWidth, kChildTextfieldHeight); 83 } 84 85 ChildModalWindow::~ChildModalWindow() { 86 } 87 88 void ChildModalWindow::OnPaint(gfx::Canvas* canvas) { 89 canvas->FillRect(GetLocalBounds(), kChildColor); 90 } 91 92 gfx::Size ChildModalWindow::GetPreferredSize() const { 93 return gfx::Size(kChildWindowWidth, kChildWindowHeight); 94 } 95 96 views::View* ChildModalWindow::GetContentsView() { 97 return this; 98 } 99 100 base::string16 ChildModalWindow::GetWindowTitle() const { 101 return base::ASCIIToUTF16("Examples: Child Modal Window"); 102 } 103 104 bool ChildModalWindow::CanResize() const { 105 return false; 106 } 107 108 ui::ModalType ChildModalWindow::GetModalType() const { 109 return ui::MODAL_TYPE_CHILD; 110 } 111 112 ChildModalParent::ChildModalParent(gfx::NativeView context) 113 : button_(new views::LabelButton(this, 114 base::ASCIIToUTF16( 115 "Show/Hide Child Modal Window"))), 116 textfield_(new views::Textfield), 117 host_(new views::NativeViewHost), 118 modal_parent_(NULL), 119 child_(NULL) { 120 Widget* widget = new Widget; 121 Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); 122 params.context = context; 123 widget->Init(params); 124 widget->GetRootView()->set_background( 125 views::Background::CreateSolidBackground(kModalParentColor)); 126 modal_parent_ = widget->GetNativeView(); 127 widget->GetNativeView()->SetName("ModalParent"); 128 AddChildView(button_); 129 AddChildView(textfield_); 130 AddChildView(host_); 131 } 132 133 ChildModalParent::~ChildModalParent() { 134 } 135 136 void ChildModalParent::ShowChild() { 137 if (!child_) 138 child_ = CreateChild(); 139 child_->Show(); 140 } 141 142 gfx::NativeWindow ChildModalParent::GetModalParent() const { 143 return modal_parent_; 144 } 145 146 gfx::NativeWindow ChildModalParent::GetChild() const { 147 if (child_) 148 return child_->GetNativeView(); 149 return NULL; 150 } 151 152 Widget* ChildModalParent::CreateChild() { 153 Widget* child = Widget::CreateWindowWithParent( 154 new ChildModalWindow, GetWidget()->GetNativeView()); 155 wm::SetModalParent(child->GetNativeView(), GetModalParent()); 156 child->AddObserver(this); 157 child->GetNativeView()->SetName("ChildModalWindow"); 158 return child; 159 } 160 161 views::View* ChildModalParent::GetContentsView() { 162 return this; 163 } 164 165 base::string16 ChildModalParent::GetWindowTitle() const { 166 return base::ASCIIToUTF16("Examples: Child Modal Parent"); 167 } 168 169 bool ChildModalParent::CanResize() const { 170 return false; 171 } 172 173 void ChildModalParent::DeleteDelegate() { 174 if (child_) { 175 child_->RemoveObserver(this); 176 child_->Close(); 177 child_ = NULL; 178 } 179 180 delete this; 181 } 182 183 void ChildModalParent::Layout() { 184 int running_y = y(); 185 button_->SetBounds(x(), running_y, width(), kButtonHeight); 186 running_y += kButtonHeight; 187 textfield_->SetBounds(x(), running_y, width(), kTextfieldHeight); 188 running_y += kTextfieldHeight; 189 host_->SetBounds(x(), running_y, width(), height() - running_y); 190 } 191 192 void ChildModalParent::ViewHierarchyChanged( 193 const ViewHierarchyChangedDetails& details) { 194 if (details.is_add && details.child == this) { 195 host_->Attach(modal_parent_); 196 GetWidget()->GetNativeView()->SetName("Parent"); 197 } 198 } 199 200 void ChildModalParent::ButtonPressed(views::Button* sender, 201 const ui::Event& event) { 202 if (sender == button_) { 203 if (!child_) 204 child_ = CreateChild(); 205 if (child_->IsVisible()) 206 child_->Hide(); 207 else 208 child_->Show(); 209 } 210 } 211 212 void ChildModalParent::OnWidgetDestroying(Widget* widget) { 213 if (child_) { 214 DCHECK_EQ(child_, widget); 215 child_ = NULL; 216 } 217 } 218 219 } // namespace test 220 } // namespace ash 221