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
18using views::Widget;
19
20namespace ash {
21namespace test {
22
23namespace {
24
25// Parent window size and position.
26const int kWindowLeft = 170;
27const int kWindowTop = 200;
28const int kWindowWidth = 400;
29const int kWindowHeight = 400;
30
31// Parent window layout.
32const int kButtonHeight = 35;
33const int kTextfieldHeight = 35;
34
35// Child window size.
36const int kChildWindowWidth = 330;
37const int kChildWindowHeight = 200;
38
39// Child window layout.
40const int kChildTextfieldLeft = 20;
41const int kChildTextfieldTop = 50;
42const int kChildTextfieldWidth = 290;
43const int kChildTextfieldHeight = 35;
44
45const SkColor kModalParentColor = SK_ColorWHITE;
46const SkColor kChildColor = SK_ColorWHITE;
47
48}  // namespace
49
50void CreateChildModalParent(gfx::NativeView context) {
51  Widget::CreateWindowWithContextAndBounds(
52      new ChildModalParent(context),
53      context,
54      gfx::Rect(kWindowLeft, kWindowTop, kWindowWidth, kWindowHeight))->Show();
55}
56
57
58class 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
77ChildModalWindow::ChildModalWindow() {
78  views::Textfield* textfield = new views::Textfield;
79  AddChildView(textfield);
80  textfield->SetBounds(
81      kChildTextfieldLeft, kChildTextfieldTop,
82      kChildTextfieldWidth, kChildTextfieldHeight);
83}
84
85ChildModalWindow::~ChildModalWindow() {
86}
87
88void ChildModalWindow::OnPaint(gfx::Canvas* canvas) {
89  canvas->FillRect(GetLocalBounds(), kChildColor);
90}
91
92gfx::Size ChildModalWindow::GetPreferredSize() const {
93  return gfx::Size(kChildWindowWidth, kChildWindowHeight);
94}
95
96views::View* ChildModalWindow::GetContentsView() {
97  return this;
98}
99
100base::string16 ChildModalWindow::GetWindowTitle() const {
101  return base::ASCIIToUTF16("Examples: Child Modal Window");
102}
103
104bool ChildModalWindow::CanResize() const {
105  return false;
106}
107
108ui::ModalType ChildModalWindow::GetModalType() const {
109  return ui::MODAL_TYPE_CHILD;
110}
111
112ChildModalParent::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
133ChildModalParent::~ChildModalParent() {
134}
135
136void ChildModalParent::ShowChild() {
137  if (!child_)
138    child_ = CreateChild();
139  child_->Show();
140}
141
142gfx::NativeWindow ChildModalParent::GetModalParent() const {
143  return modal_parent_;
144}
145
146gfx::NativeWindow ChildModalParent::GetChild() const {
147  if (child_)
148    return child_->GetNativeView();
149  return NULL;
150}
151
152Widget* 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
161views::View* ChildModalParent::GetContentsView() {
162  return this;
163}
164
165base::string16 ChildModalParent::GetWindowTitle() const {
166  return base::ASCIIToUTF16("Examples: Child Modal Parent");
167}
168
169bool ChildModalParent::CanResize() const {
170  return false;
171}
172
173void ChildModalParent::DeleteDelegate() {
174  if (child_) {
175    child_->RemoveObserver(this);
176    child_->Close();
177    child_ = NULL;
178  }
179
180  delete this;
181}
182
183void 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
192void 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
200void 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
212void 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