Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / native / native_view_host_aura.cc
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/controls/native/native_view_host_aura.h"
6
7 #include "base/logging.h"
8 #include "ui/aura/client/aura_constants.h"
9 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/aura/window_delegate.h"
12 #include "ui/base/cursor/cursor.h"
13 #include "ui/base/hit_test.h"
14 #include "ui/views/controls/native/native_view_host.h"
15 #include "ui/views/view_constants_aura.h"
16 #include "ui/views/widget/widget.h"
17
18 namespace views {
19
20 class NativeViewHostAura::ClippingWindowDelegate : public aura::WindowDelegate {
21  public:
22   ClippingWindowDelegate() : native_view_(NULL) {}
23   virtual ~ClippingWindowDelegate() {}
24
25   void set_native_view(aura::Window* native_view) {
26     native_view_ = native_view;
27   }
28
29   virtual gfx::Size GetMinimumSize() const OVERRIDE { return gfx::Size(); }
30   virtual gfx::Size GetMaximumSize() const OVERRIDE { return gfx::Size(); }
31   virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
32                                const gfx::Rect& new_bounds) OVERRIDE {}
33   virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
34     return gfx::kNullCursor;
35   }
36   virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
37     return HTCLIENT;
38   }
39   virtual bool ShouldDescendIntoChildForEventHandling(
40       aura::Window* child,
41       const gfx::Point& location) OVERRIDE { return true; }
42   virtual bool CanFocus() OVERRIDE {
43     // Ask the hosted native view's delegate because directly calling
44     // aura::Window::CanFocus() will call back into this when checking whether
45     // parents can focus.
46     return native_view_ && native_view_->delegate()
47         ? native_view_->delegate()->CanFocus()
48         : true;
49   }
50   virtual void OnCaptureLost() OVERRIDE {}
51   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {}
52   virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {}
53   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {}
54   virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {}
55   virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {}
56   virtual bool HasHitTestMask() const OVERRIDE { return false; }
57   virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
58
59  private:
60   aura::Window* native_view_;
61 };
62
63 NativeViewHostAura::NativeViewHostAura(NativeViewHost* host)
64     : host_(host),
65       clipping_window_delegate_(new ClippingWindowDelegate()),
66       clipping_window_(clipping_window_delegate_.get()) {
67   // Set the type so descendant views (including popups) get positioned
68   // appropriately.
69   clipping_window_.SetType(ui::wm::WINDOW_TYPE_CONTROL);
70   clipping_window_.Init(aura::WINDOW_LAYER_NOT_DRAWN);
71   clipping_window_.set_owned_by_parent(false);
72   clipping_window_.SetName("NativeViewHostAuraClip");
73   clipping_window_.layer()->SetMasksToBounds(true);
74   clipping_window_.SetProperty(views::kHostViewKey, static_cast<View*>(host_));
75 }
76
77 NativeViewHostAura::~NativeViewHostAura() {
78   if (host_->native_view()) {
79     host_->native_view()->RemoveObserver(this);
80     host_->native_view()->ClearProperty(views::kHostViewKey);
81     host_->native_view()->ClearProperty(aura::client::kHostWindowKey);
82     clipping_window_.ClearProperty(views::kHostViewKey);
83     if (host_->native_view()->parent() == &clipping_window_)
84       clipping_window_.RemoveChild(host_->native_view());
85   }
86 }
87
88 ////////////////////////////////////////////////////////////////////////////////
89 // NativeViewHostAura, NativeViewHostWrapper implementation:
90 void NativeViewHostAura::AttachNativeView() {
91   clipping_window_delegate_->set_native_view(host_->native_view());
92   host_->native_view()->AddObserver(this);
93   host_->native_view()->SetProperty(views::kHostViewKey,
94       static_cast<View*>(host_));
95   AddClippingWindow();
96 }
97
98 void NativeViewHostAura::NativeViewDetaching(bool destroyed) {
99   clipping_window_delegate_->set_native_view(NULL);
100   RemoveClippingWindow();
101   if (!destroyed) {
102     host_->native_view()->RemoveObserver(this);
103     host_->native_view()->ClearProperty(views::kHostViewKey);
104     host_->native_view()->ClearProperty(aura::client::kHostWindowKey);
105     host_->native_view()->Hide();
106     if (host_->native_view()->parent())
107       Widget::ReparentNativeView(host_->native_view(), NULL);
108   }
109 }
110
111 void NativeViewHostAura::AddedToWidget() {
112   if (!host_->native_view())
113     return;
114
115   AddClippingWindow();
116   if (host_->IsDrawn())
117     host_->native_view()->Show();
118   else
119     host_->native_view()->Hide();
120   host_->Layout();
121 }
122
123 void NativeViewHostAura::RemovedFromWidget() {
124   if (host_->native_view()) {
125     host_->native_view()->Hide();
126     host_->native_view()->ClearProperty(aura::client::kHostWindowKey);
127     if (host_->native_view()->parent())
128       host_->native_view()->parent()->RemoveChild(host_->native_view());
129     RemoveClippingWindow();
130   }
131 }
132
133 void NativeViewHostAura::InstallClip(int x, int y, int w, int h) {
134   clip_rect_.reset(
135       new gfx::Rect(host_->ConvertRectToWidget(gfx::Rect(x, y, w, h))));
136 }
137
138 bool NativeViewHostAura::HasInstalledClip() {
139   return clip_rect_;
140 }
141
142 void NativeViewHostAura::UninstallClip() {
143   clip_rect_.reset();
144 }
145
146 void NativeViewHostAura::ShowWidget(int x, int y, int w, int h) {
147   int width = w;
148   int height = h;
149   if (host_->fast_resize()) {
150     gfx::Point origin(x, y);
151     views::View::ConvertPointFromWidget(host_, &origin);
152     InstallClip(origin.x(), origin.y(), w, h);
153     width = host_->native_view()->bounds().width();
154     height = host_->native_view()->bounds().height();
155   }
156   clipping_window_.SetBounds(clip_rect_ ? *clip_rect_
157                                         : gfx::Rect(x, y, w, h));
158
159   gfx::Point clip_offset = clipping_window_.bounds().origin();
160   host_->native_view()->SetBounds(
161       gfx::Rect(x - clip_offset.x(), y - clip_offset.y(), width, height));
162   host_->native_view()->Show();
163   clipping_window_.Show();
164 }
165
166 void NativeViewHostAura::HideWidget() {
167   host_->native_view()->Hide();
168   clipping_window_.Hide();
169 }
170
171 void NativeViewHostAura::SetFocus() {
172   aura::Window* window = host_->native_view();
173   aura::client::FocusClient* client = aura::client::GetFocusClient(window);
174   if (client)
175     client->FocusWindow(window);
176 }
177
178 gfx::NativeViewAccessible NativeViewHostAura::GetNativeViewAccessible() {
179   return NULL;
180 }
181
182 gfx::NativeCursor NativeViewHostAura::GetCursor(int x, int y) {
183   if (host_->native_view())
184     return host_->native_view()->GetCursor(gfx::Point(x, y));
185   return gfx::kNullCursor;
186 }
187
188 void NativeViewHostAura::OnWindowDestroying(aura::Window* window) {
189   DCHECK(window == host_->native_view());
190   clipping_window_delegate_->set_native_view(NULL);
191 }
192
193 void NativeViewHostAura::OnWindowDestroyed(aura::Window* window) {
194   DCHECK(window == host_->native_view());
195   host_->NativeViewDestroyed();
196 }
197
198 // static
199 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
200     NativeViewHost* host) {
201   return new NativeViewHostAura(host);
202 }
203
204 void NativeViewHostAura::AddClippingWindow() {
205   RemoveClippingWindow();
206
207   host_->native_view()->SetProperty(aura::client::kHostWindowKey,
208                                     host_->GetWidget()->GetNativeView());
209   Widget::ReparentNativeView(host_->native_view(),
210                              &clipping_window_);
211   if (host_->GetWidget()->GetNativeView()) {
212     Widget::ReparentNativeView(&clipping_window_,
213                                host_->GetWidget()->GetNativeView());
214   }
215 }
216
217 void NativeViewHostAura::RemoveClippingWindow() {
218   clipping_window_.Hide();
219   if (host_->native_view())
220     host_->native_view()->ClearProperty(aura::client::kHostWindowKey);
221
222   if (host_->native_view()->parent() == &clipping_window_) {
223     if (host_->GetWidget() && host_->GetWidget()->GetNativeView()) {
224       Widget::ReparentNativeView(host_->native_view(),
225                                  host_->GetWidget()->GetNativeView());
226     } else {
227       clipping_window_.RemoveChild(host_->native_view());
228     }
229     host_->native_view()->SetBounds(clipping_window_.bounds());
230   }
231   if (clipping_window_.parent())
232     clipping_window_.parent()->RemoveChild(&clipping_window_);
233 }
234
235 }  // namespace views