| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/views/controls/native/native_view_host_mac.h" |
| |
| #import <Cocoa/Cocoa.h> |
| |
| #include "base/logging.h" |
| #include "base/mac/foundation_util.h" |
| #import "ui/views/cocoa/bridged_content_view.h" |
| #include "ui/views/controls/native/native_view_host.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace views { |
| namespace { |
| |
| // Reparents |native_view| to be a child of the native content view of |
| // |new_parent|. |
| void ReparentNSView(NSView* native_view, Widget* new_parent) { |
| DCHECK(native_view); |
| // Mac's NativeViewHost has no support for hosting its own child widgets. |
| // This check is probably overly restrictive, since the Widget containing the |
| // NativeViewHost _is_ allowed child Widgets. However, we don't know yet |
| // whether those child Widgets need to be distinguished from Widgets that code |
| // might want to associate with the hosted NSView instead. |
| { |
| Widget::Widgets child_widgets; |
| Widget::GetAllChildWidgets(native_view, &child_widgets); |
| CHECK_GE(1u, child_widgets.size()); // 1 (itself) or 0 if detached. |
| } |
| |
| if (!new_parent) { |
| [native_view removeFromSuperview]; |
| return; |
| } |
| |
| BridgedContentView* new_superview = |
| base::mac::ObjCCastStrict<BridgedContentView>( |
| new_parent->GetNativeView()); |
| DCHECK(new_superview); |
| [new_superview addSubview:native_view]; |
| } |
| |
| } // namespace |
| |
| NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) { |
| } |
| |
| NativeViewHostMac::~NativeViewHostMac() { |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // NativeViewHostMac, NativeViewHostWrapper implementation: |
| |
| void NativeViewHostMac::AttachNativeView() { |
| DCHECK(host_->native_view()); |
| ReparentNSView(host_->native_view(), host_->GetWidget()); |
| } |
| |
| void NativeViewHostMac::NativeViewDetaching(bool destroyed) { |
| // |destroyed| is only true if this class calls host_->NativeViewDestroyed(). |
| // TODO(tapted): See if that's needed on Mac, since views are hard to destroy |
| // by themselves. |
| DCHECK(!destroyed); |
| [host_->native_view() setHidden:YES]; |
| ReparentNSView(host_->native_view(), NULL); |
| } |
| |
| void NativeViewHostMac::AddedToWidget() { |
| if (!host_->native_view()) |
| return; |
| |
| AttachNativeView(); |
| host_->Layout(); |
| } |
| |
| void NativeViewHostMac::RemovedFromWidget() { |
| if (!host_->native_view()) |
| return; |
| |
| NativeViewDetaching(false); |
| } |
| |
| void NativeViewHostMac::InstallClip(int x, int y, int w, int h) { |
| NOTIMPLEMENTED(); |
| } |
| |
| bool NativeViewHostMac::HasInstalledClip() { |
| return false; |
| } |
| |
| void NativeViewHostMac::UninstallClip() { |
| NOTIMPLEMENTED(); |
| } |
| |
| void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) { |
| if (host_->fast_resize()) |
| NOTIMPLEMENTED(); |
| |
| // Coordinates will be from the top left of the parent Widget. The NativeView |
| // is already in the same NSWindow, so just flip to get Cooca coordinates and |
| // then convert to the containing view. |
| NSRect window_rect = NSMakeRect( |
| x, |
| host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h, |
| w, |
| h); |
| |
| // Convert window coordinates to the hosted view's superview, since that's how |
| // coordinates of the hosted view's frame is based. |
| NSRect container_rect = |
| [[host_->native_view() superview] convertRect:window_rect fromView:nil]; |
| [host_->native_view() setFrame:container_rect]; |
| [host_->native_view() setHidden:NO]; |
| } |
| |
| void NativeViewHostMac::HideWidget() { |
| [host_->native_view() setHidden:YES]; |
| } |
| |
| void NativeViewHostMac::SetFocus() { |
| if ([host_->native_view() acceptsFirstResponder]) |
| [[host_->native_view() window] makeFirstResponder:host_->native_view()]; |
| } |
| |
| gfx::NativeViewAccessible NativeViewHostMac::GetNativeViewAccessible() { |
| return NULL; |
| } |
| |
| gfx::NativeCursor NativeViewHostMac::GetCursor(int x, int y) { |
| NOTIMPLEMENTED(); |
| return gfx::kNullCursor; |
| } |
| |
| // static |
| NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( |
| NativeViewHost* host) { |
| return new NativeViewHostMac(host); |
| } |
| |
| } // namespace views |