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