| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/continue_window.h" | 5 #include "remoting/host/continue_window.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/scoped_nsautorelease_pool.h" | 11 #include "base/mac/scoped_nsautorelease_pool.h" |
| 12 #include "base/memory/scoped_nsobject.h" | 12 #include "base/memory/scoped_nsobject.h" |
| 13 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" |
| 14 #include "remoting/host/chromoting_host.h" | 14 #include "remoting/host/chromoting_host.h" |
| 15 | 15 |
| 16 // As this is a plugin, there needs to be a way to find its bundle | 16 // Handles the ContinueWindow. |
| 17 // so that resources are able to be found. This class exists solely so that | 17 @interface ContinueWindowMacController : NSObject { |
| 18 // there is a way to get the bundle that this code file is in using | 18 @private |
| 19 // [NSBundle bundleForClass:[ContinueWindowMacClassToLocateMyBundle class]] | 19 scoped_nsobject<NSMutableArray> shades_; |
| 20 // It is really only a name. | 20 scoped_nsobject<NSAlert> continue_alert_; |
| 21 @interface ContinueWindowMacClassToLocateMyBundle : NSObject | 21 remoting::ChromotingHost* host_; |
| 22 @end | 22 } |
| 23 | 23 |
| 24 @implementation ContinueWindowMacClassToLocateMyBundle | 24 - (id)initWithHost:(remoting::ChromotingHost*)host; |
| 25 - (void)show; |
| 26 - (void)hide; |
| 27 - (void)onCancel:(id)sender; |
| 28 - (void)onContinue:(id)sender; |
| 25 @end | 29 @end |
| 26 | 30 |
| 27 namespace remoting { | 31 namespace remoting { |
| 28 | 32 |
| 33 // A bridge between C++ and ObjC implementations of ContinueWindow. |
| 34 // Everything important occurs in ContinueWindowMacController. |
| 29 class ContinueWindowMac : public remoting::ContinueWindow { | 35 class ContinueWindowMac : public remoting::ContinueWindow { |
| 30 public: | 36 public: |
| 31 ContinueWindowMac() : modal_session_(NULL) {} | 37 ContinueWindowMac() {} |
| 32 virtual ~ContinueWindowMac() {} | 38 virtual ~ContinueWindowMac() {} |
| 33 | 39 |
| 34 virtual void Show(remoting::ChromotingHost* host) OVERRIDE; | 40 virtual void Show(remoting::ChromotingHost* host) OVERRIDE; |
| 35 virtual void Hide() OVERRIDE; | 41 virtual void Hide() OVERRIDE; |
| 36 | 42 |
| 37 private: | 43 private: |
| 38 NSModalSession modal_session_; | 44 scoped_nsobject<ContinueWindowMacController> controller_; |
| 39 | 45 |
| 40 DISALLOW_COPY_AND_ASSIGN(ContinueWindowMac); | 46 DISALLOW_COPY_AND_ASSIGN(ContinueWindowMac); |
| 41 }; | 47 }; |
| 42 | 48 |
| 43 void ContinueWindowMac::Show(remoting::ChromotingHost* host) { | 49 void ContinueWindowMac::Show(remoting::ChromotingHost* host) { |
| 44 base::mac::ScopedNSAutoreleasePool pool; | 50 base::mac::ScopedNSAutoreleasePool pool; |
| 51 controller_.reset([[ContinueWindowMacController alloc] initWithHost:host]); |
| 52 [controller_ show]; |
| 45 | 53 |
| 46 // Generate window shade | |
| 47 NSArray* screens = [NSScreen screens]; | |
| 48 NSMutableArray* windows = [NSMutableArray arrayWithCapacity:[screens count]]; | |
| 49 for (NSScreen *screen in screens) { | |
| 50 NSWindow* window = | |
| 51 [[[NSWindow alloc] initWithContentRect:[screen frame] | |
| 52 styleMask:NSBorderlessWindowMask | |
| 53 backing:NSBackingStoreBuffered | |
| 54 defer:NO | |
| 55 screen:screen] autorelease]; | |
| 56 [window setReleasedWhenClosed:NO]; | |
| 57 [window setAlphaValue:0.8]; | |
| 58 [window setOpaque:NO]; | |
| 59 [window setBackgroundColor:[NSColor blackColor]]; | |
| 60 // Raise the window shade above just about everything else. | |
| 61 // Leave the dock and menu bar exposed so the user has some basic level | |
| 62 // of control (like they can quit Chromium). | |
| 63 [window setLevel:NSModalPanelWindowLevel - 1]; | |
| 64 [window orderFront:nil]; | |
| 65 [windows addObject:window]; | |
| 66 } | |
| 67 | |
| 68 // Put up alert | |
| 69 const UiStrings& strings = host->ui_strings(); | |
| 70 NSString* message = base::SysUTF16ToNSString(strings.continue_prompt); | |
| 71 NSString* continue_button = base::SysUTF16ToNSString( | |
| 72 strings.continue_button_text); | |
| 73 NSString* cancel_button = base::SysUTF16ToNSString( | |
| 74 strings.stop_sharing_button_text); | |
| 75 scoped_nsobject<NSAlert> continue_alert([[NSAlert alloc] init]); | |
| 76 [continue_alert setMessageText:message]; | |
| 77 [continue_alert addButtonWithTitle:continue_button]; | |
| 78 [continue_alert addButtonWithTitle:cancel_button]; | |
| 79 | |
| 80 // See ContinueWindowMacClassToLocateMyBundle class above for details | |
| 81 // on this. | |
| 82 NSBundle *bundle = | |
| 83 [NSBundle bundleForClass:[ContinueWindowMacClassToLocateMyBundle class]]; | |
| 84 NSString *imagePath = [bundle pathForResource:@"chromoting128" ofType:@"png"]; | |
| 85 scoped_nsobject<NSImage> image( | |
| 86 [[NSImage alloc] initByReferencingFile:imagePath]); | |
| 87 [continue_alert setIcon:image]; | |
| 88 [continue_alert layout]; | |
| 89 | |
| 90 NSWindow* continue_window = [continue_alert window]; | |
| 91 [continue_window center]; | |
| 92 [continue_window orderWindow:NSWindowAbove | |
| 93 relativeTo:[[windows lastObject] windowNumber]]; | |
| 94 [continue_window makeKeyWindow]; | |
| 95 NSApplication* application = [NSApplication sharedApplication]; | |
| 96 modal_session_ = [application beginModalSessionForWindow:continue_window]; | |
| 97 NSInteger answer = 0; | |
| 98 do { | |
| 99 answer = [application runModalSession:modal_session_]; | |
| 100 } while (answer == NSRunContinuesResponse); | |
| 101 [application endModalSession:modal_session_]; | |
| 102 modal_session_ = NULL; | |
| 103 | |
| 104 [continue_window close]; | |
| 105 | |
| 106 // Remove window shade. | |
| 107 for (NSWindow* window in windows) { | |
| 108 [window close]; | |
| 109 } | |
| 110 | |
| 111 if (answer == NSAlertFirstButtonReturn) { | |
| 112 host->PauseSession(false); | |
| 113 } else { | |
| 114 host->Shutdown(NULL); | |
| 115 } | |
| 116 } | 54 } |
| 117 | 55 |
| 118 void ContinueWindowMac::Hide() { | 56 void ContinueWindowMac::Hide() { |
| 119 if (modal_session_) { | 57 base::mac::ScopedNSAutoreleasePool pool; |
| 120 NSApplication* application = [NSApplication sharedApplication]; | 58 [controller_ hide]; |
| 121 [application stopModalWithCode:NSAlertFirstButtonReturn]; | |
| 122 } | |
| 123 } | 59 } |
| 124 | 60 |
| 125 ContinueWindow* ContinueWindow::Create() { | 61 ContinueWindow* ContinueWindow::Create() { |
| 126 return new ContinueWindowMac(); | 62 return new ContinueWindowMac(); |
| 127 } | 63 } |
| 128 | 64 |
| 129 } // namespace remoting | 65 } // namespace remoting |
| 66 |
| 67 @implementation ContinueWindowMacController |
| 68 |
| 69 - (id)initWithHost:(remoting::ChromotingHost*)host { |
| 70 if ((self = [super init])) { |
| 71 host_ = host; |
| 72 } |
| 73 return self; |
| 74 } |
| 75 |
| 76 - (void)show { |
| 77 // Generate window shade |
| 78 NSArray* screens = [NSScreen screens]; |
| 79 shades_.reset([[NSMutableArray alloc] initWithCapacity:[screens count]]); |
| 80 for (NSScreen *screen in screens) { |
| 81 NSWindow* shade = |
| 82 [[[NSWindow alloc] initWithContentRect:[screen frame] |
| 83 styleMask:NSBorderlessWindowMask |
| 84 backing:NSBackingStoreBuffered |
| 85 defer:NO |
| 86 screen:screen] autorelease]; |
| 87 [shade setReleasedWhenClosed:NO]; |
| 88 [shade setAlphaValue:0.8]; |
| 89 [shade setOpaque:NO]; |
| 90 [shade setBackgroundColor:[NSColor blackColor]]; |
| 91 // Raise the window shade above just about everything else. |
| 92 // Leave the dock and menu bar exposed so the user has some basic level |
| 93 // of control (like they can quit Chromium). |
| 94 [shade setLevel:NSModalPanelWindowLevel - 1]; |
| 95 [shade orderFront:nil]; |
| 96 [shades_ addObject:shade]; |
| 97 } |
| 98 |
| 99 // Create alert. |
| 100 const remoting::UiStrings& strings = host_->ui_strings(); |
| 101 NSString* message = base::SysUTF16ToNSString(strings.continue_prompt); |
| 102 NSString* continue_button_string = base::SysUTF16ToNSString( |
| 103 strings.continue_button_text); |
| 104 NSString* cancel_button_string = base::SysUTF16ToNSString( |
| 105 strings.stop_sharing_button_text); |
| 106 continue_alert_.reset([[NSAlert alloc] init]); |
| 107 [continue_alert_ setMessageText:message]; |
| 108 |
| 109 NSButton* continue_button = |
| 110 [continue_alert_ addButtonWithTitle:continue_button_string]; |
| 111 [continue_button setAction:@selector(onContinue:)]; |
| 112 [continue_button setTarget:self]; |
| 113 |
| 114 NSButton* cancel_button = |
| 115 [continue_alert_ addButtonWithTitle:cancel_button_string]; |
| 116 [cancel_button setAction:@selector(onCancel:)]; |
| 117 [cancel_button setTarget:self]; |
| 118 |
| 119 NSBundle *bundle = [NSBundle bundleForClass:[self class]]; |
| 120 NSString *imagePath = [bundle pathForResource:@"chromoting128" ofType:@"png"]; |
| 121 scoped_nsobject<NSImage> image( |
| 122 [[NSImage alloc] initByReferencingFile:imagePath]); |
| 123 [continue_alert_ setIcon:image]; |
| 124 [continue_alert_ layout]; |
| 125 |
| 126 // Force alert to be at the proper level and location. |
| 127 NSWindow* continue_window = [continue_alert_ window]; |
| 128 [continue_window center]; |
| 129 [continue_window setLevel:NSModalPanelWindowLevel]; |
| 130 [continue_window orderWindow:NSWindowAbove |
| 131 relativeTo:[[shades_ lastObject] windowNumber]]; |
| 132 [continue_window makeKeyWindow]; |
| 133 } |
| 134 |
| 135 - (void)hide { |
| 136 // Remove window shade. |
| 137 for (NSWindow* window in shades_.get()) { |
| 138 [window close]; |
| 139 } |
| 140 shades_.reset(); |
| 141 continue_alert_.reset(); |
| 142 } |
| 143 |
| 144 - (void)onCancel:(id)sender { |
| 145 [self hide]; |
| 146 host_->Shutdown(NULL); |
| 147 host_ = nil; |
| 148 } |
| 149 |
| 150 - (void)onContinue:(id)sender { |
| 151 [self hide]; |
| 152 host_->PauseSession(false); |
| 153 host_ = nil; |
| 154 } |
| 155 |
| 156 @end |
| OLD | NEW |