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 "ui/views/controls/native/native_view_host_mac.h" 6 7 #import <Cocoa/Cocoa.h> 8 9 #include "base/logging.h" 10 #include "base/mac/foundation_util.h" 11 #import "ui/views/cocoa/bridged_content_view.h" 12 #include "ui/views/controls/native/native_view_host.h" 13 #include "ui/views/widget/widget.h" 14 15 namespace views { 16 namespace { 17 18 // Reparents |native_view| to be a child of the native content view of 19 // |new_parent|. 20 void ReparentNSView(NSView* native_view, Widget* new_parent) { 21 DCHECK(native_view); 22 // Mac's NativeViewHost has no support for hosting its own child widgets. 23 // This check is probably overly restrictive, since the Widget containing the 24 // NativeViewHost _is_ allowed child Widgets. However, we don't know yet 25 // whether those child Widgets need to be distinguished from Widgets that code 26 // might want to associate with the hosted NSView instead. 27 { 28 Widget::Widgets child_widgets; 29 Widget::GetAllChildWidgets(native_view, &child_widgets); 30 CHECK_GE(1u, child_widgets.size()); // 1 (itself) or 0 if detached. 31 } 32 33 if (!new_parent) { 34 [native_view removeFromSuperview]; 35 return; 36 } 37 38 BridgedContentView* new_superview = 39 base::mac::ObjCCastStrict<BridgedContentView>( 40 new_parent->GetNativeView()); 41 DCHECK(new_superview); 42 [new_superview addSubview:native_view]; 43 } 44 45 } // namespace 46 47 NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) { 48 } 49 50 NativeViewHostMac::~NativeViewHostMac() { 51 } 52 53 //////////////////////////////////////////////////////////////////////////////// 54 // NativeViewHostMac, NativeViewHostWrapper implementation: 55 56 void NativeViewHostMac::AttachNativeView() { 57 DCHECK(host_->native_view()); 58 ReparentNSView(host_->native_view(), host_->GetWidget()); 59 } 60 61 void NativeViewHostMac::NativeViewDetaching(bool destroyed) { 62 // |destroyed| is only true if this class calls host_->NativeViewDestroyed(). 63 // TODO(tapted): See if that's needed on Mac, since views are hard to destroy 64 // by themselves. 65 DCHECK(!destroyed); 66 [host_->native_view() setHidden:YES]; 67 ReparentNSView(host_->native_view(), NULL); 68 } 69 70 void NativeViewHostMac::AddedToWidget() { 71 if (!host_->native_view()) 72 return; 73 74 AttachNativeView(); 75 host_->Layout(); 76 } 77 78 void NativeViewHostMac::RemovedFromWidget() { 79 if (!host_->native_view()) 80 return; 81 82 NativeViewDetaching(false); 83 } 84 85 void NativeViewHostMac::InstallClip(int x, int y, int w, int h) { 86 NOTIMPLEMENTED(); 87 } 88 89 bool NativeViewHostMac::HasInstalledClip() { 90 return false; 91 } 92 93 void NativeViewHostMac::UninstallClip() { 94 NOTIMPLEMENTED(); 95 } 96 97 void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) { 98 if (host_->fast_resize()) 99 NOTIMPLEMENTED(); 100 101 // Coordinates will be from the top left of the parent Widget. The NativeView 102 // is already in the same NSWindow, so just flip to get Cooca coordinates and 103 // then convert to the containing view. 104 NSRect window_rect = NSMakeRect( 105 x, 106 host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h, 107 w, 108 h); 109 110 // Convert window coordinates to the hosted view's superview, since that's how 111 // coordinates of the hosted view's frame is based. 112 NSRect container_rect = 113 [[host_->native_view() superview] convertRect:window_rect fromView:nil]; 114 [host_->native_view() setFrame:container_rect]; 115 [host_->native_view() setHidden:NO]; 116 } 117 118 void NativeViewHostMac::HideWidget() { 119 [host_->native_view() setHidden:YES]; 120 } 121 122 void NativeViewHostMac::SetFocus() { 123 if ([host_->native_view() acceptsFirstResponder]) 124 [[host_->native_view() window] makeFirstResponder:host_->native_view()]; 125 } 126 127 gfx::NativeViewAccessible NativeViewHostMac::GetNativeViewAccessible() { 128 return NULL; 129 } 130 131 gfx::NativeCursor NativeViewHostMac::GetCursor(int x, int y) { 132 NOTIMPLEMENTED(); 133 return gfx::kNullCursor; 134 } 135 136 // static 137 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( 138 NativeViewHost* host) { 139 return new NativeViewHostMac(host); 140 } 141 142 } // namespace views 143