Home | History | Annotate | Download | only in host
      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 #import <Cocoa/Cocoa.h>
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/logging.h"
      9 #include "base/mac/scoped_nsautorelease_pool.h"
     10 #include "base/mac/scoped_nsobject.h"
     11 #include "base/strings/sys_string_conversions.h"
     12 #include "remoting/base/string_resources.h"
     13 #include "remoting/host/continue_window.h"
     14 #include "ui/base/l10n/l10n_util_mac.h"
     15 
     16 // Handles the ContinueWindow.
     17 @interface ContinueWindowMacController : NSObject {
     18  @private
     19   base::scoped_nsobject<NSMutableArray> shades_;
     20   base::scoped_nsobject<NSAlert> continue_alert_;
     21   remoting::ContinueWindow* continue_window_;
     22 }
     23 
     24 - (id)initWithWindow:(remoting::ContinueWindow*)continue_window;
     25 - (void)show;
     26 - (void)hide;
     27 - (void)onCancel:(id)sender;
     28 - (void)onContinue:(id)sender;
     29 @end
     30 
     31 namespace remoting {
     32 
     33 // A bridge between C++ and ObjC implementations of ContinueWindow.
     34 // Everything important occurs in ContinueWindowMacController.
     35 class ContinueWindowMac : public ContinueWindow {
     36  public:
     37   ContinueWindowMac();
     38   virtual ~ContinueWindowMac();
     39 
     40  protected:
     41   // ContinueWindow overrides.
     42   virtual void ShowUi() OVERRIDE;
     43   virtual void HideUi() OVERRIDE;
     44 
     45  private:
     46   base::scoped_nsobject<ContinueWindowMacController> controller_;
     47 
     48   DISALLOW_COPY_AND_ASSIGN(ContinueWindowMac);
     49 };
     50 
     51 ContinueWindowMac::ContinueWindowMac() {
     52 }
     53 
     54 ContinueWindowMac::~ContinueWindowMac() {
     55   DCHECK(CalledOnValidThread());
     56 }
     57 
     58 void ContinueWindowMac::ShowUi() {
     59   DCHECK(CalledOnValidThread());
     60 
     61   base::mac::ScopedNSAutoreleasePool pool;
     62   controller_.reset(
     63       [[ContinueWindowMacController alloc] initWithWindow:this]);
     64   [controller_ show];
     65 }
     66 
     67 void ContinueWindowMac::HideUi() {
     68   DCHECK(CalledOnValidThread());
     69 
     70   base::mac::ScopedNSAutoreleasePool pool;
     71   [controller_ hide];
     72 }
     73 
     74 // static
     75 scoped_ptr<HostWindow> HostWindow::CreateContinueWindow() {
     76   return scoped_ptr<HostWindow>(new ContinueWindowMac());
     77 }
     78 
     79 }  // namespace remoting
     80 
     81 @implementation ContinueWindowMacController
     82 
     83 - (id)initWithWindow:(remoting::ContinueWindow*)continue_window {
     84   if ((self = [super init])) {
     85     continue_window_ = continue_window;
     86   }
     87   return self;
     88 }
     89 
     90 - (void)show {
     91   // Generate window shade
     92   NSArray* screens = [NSScreen screens];
     93   shades_.reset([[NSMutableArray alloc] initWithCapacity:[screens count]]);
     94   for (NSScreen *screen in screens) {
     95     NSWindow* shade =
     96       [[[NSWindow alloc] initWithContentRect:[screen frame]
     97                                    styleMask:NSBorderlessWindowMask
     98                                      backing:NSBackingStoreBuffered
     99                                        defer:NO
    100                                       screen:screen] autorelease];
    101     [shade setReleasedWhenClosed:NO];
    102     [shade setAlphaValue:0.8];
    103     [shade setOpaque:NO];
    104     [shade setBackgroundColor:[NSColor blackColor]];
    105     // Raise the window shade above just about everything else.
    106     // Leave the dock and menu bar exposed so the user has some basic level
    107     // of control (like they can quit Chromium).
    108     [shade setLevel:NSModalPanelWindowLevel - 1];
    109     [shade orderFront:nil];
    110     [shades_ addObject:shade];
    111   }
    112 
    113   // Create alert.
    114   continue_alert_.reset([[NSAlert alloc] init]);
    115   [continue_alert_ setMessageText:l10n_util::GetNSString(IDS_CONTINUE_PROMPT)];
    116 
    117   NSButton* continue_button =
    118       [continue_alert_ addButtonWithTitle:l10n_util::GetNSString(
    119           IDS_CONTINUE_BUTTON)];
    120   [continue_button setAction:@selector(onContinue:)];
    121   [continue_button setTarget:self];
    122 
    123   NSButton* cancel_button =
    124       [continue_alert_ addButtonWithTitle:l10n_util::GetNSString(
    125           IDS_STOP_SHARING_BUTTON)];
    126   [cancel_button setAction:@selector(onCancel:)];
    127   [cancel_button setTarget:self];
    128 
    129   NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    130   NSString *imagePath = [bundle pathForResource:@"chromoting128" ofType:@"png"];
    131   base::scoped_nsobject<NSImage> image(
    132       [[NSImage alloc] initByReferencingFile:imagePath]);
    133   [continue_alert_ setIcon:image];
    134   [continue_alert_ layout];
    135 
    136   // Force alert to be at the proper level and location.
    137   NSWindow* continue_window = [continue_alert_ window];
    138   [continue_window center];
    139   [continue_window setLevel:NSModalPanelWindowLevel];
    140   [continue_window orderWindow:NSWindowAbove
    141                     relativeTo:[[shades_ lastObject] windowNumber]];
    142   [continue_window makeKeyWindow];
    143 }
    144 
    145 - (void)hide {
    146   // Remove window shade.
    147   for (NSWindow* window in shades_.get()) {
    148     [window close];
    149   }
    150   shades_.reset();
    151   continue_alert_.reset();
    152 }
    153 
    154 - (void)onCancel:(id)sender {
    155   [self hide];
    156   continue_window_->DisconnectSession();
    157 }
    158 
    159 - (void)onContinue:(id)sender {
    160   [self hide];
    161   continue_window_->ContinueSession();
    162 }
    163 
    164 @end
    165