Home | History | Annotate | Download | only in native
      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