| 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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #import "remoting/host/disconnect_window_mac.h" | 7 #import "remoting/host/disconnect_window_mac.h" |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 DisconnectWindowMac::~DisconnectWindowMac() { | 36 DisconnectWindowMac::~DisconnectWindowMac() { |
| 37 [window_controller_ close]; | 37 [window_controller_ close]; |
| 38 } | 38 } |
| 39 | 39 |
| 40 void DisconnectWindowMac::Show(remoting::ChromotingHost* host, | 40 void DisconnectWindowMac::Show(remoting::ChromotingHost* host, |
| 41 const std::string& username) { | 41 const std::string& username) { |
| 42 CHECK(window_controller_ == nil); | 42 CHECK(window_controller_ == nil); |
| 43 NSString* nsUsername = base::SysUTF8ToNSString(username); | 43 NSString* nsUsername = base::SysUTF8ToNSString(username); |
| 44 window_controller_ = | 44 window_controller_ = |
| 45 [[DisconnectWindowController alloc] initWithHost:host | 45 [[DisconnectWindowController alloc] initWithHost:host |
| 46 window:this | |
| 47 username:nsUsername]; | 46 username:nsUsername]; |
| 48 [window_controller_ showWindow:nil]; | 47 [window_controller_ showWindow:nil]; |
| 49 } | 48 } |
| 50 | 49 |
| 51 void DisconnectWindowMac::Hide() { | 50 void DisconnectWindowMac::Hide() { |
| 52 // DisconnectWindowController is responsible for releasing itself in its | 51 // DisconnectWindowController is responsible for releasing itself in its |
| 53 // windowWillClose: method. | 52 // windowWillClose: method. |
| 54 [window_controller_ close]; | 53 [window_controller_ close]; |
| 55 window_controller_ = nil; | 54 window_controller_ = nil; |
| 56 } | 55 } |
| 57 | 56 |
| 58 remoting::DisconnectWindow* remoting::DisconnectWindow::Create() { | 57 remoting::DisconnectWindow* remoting::DisconnectWindow::Create() { |
| 59 return new DisconnectWindowMac; | 58 return new DisconnectWindowMac; |
| 60 } | 59 } |
| 61 | 60 |
| 62 } // namespace remoting | 61 } // namespace remoting |
| 63 | 62 |
| 64 @interface DisconnectWindowController() | 63 @interface DisconnectWindowController() |
| 65 @property (nonatomic, assign) remoting::ChromotingHost* host; | 64 @property (nonatomic, assign) remoting::ChromotingHost* host; |
| 66 @property (nonatomic, assign) remoting::DisconnectWindowMac* disconnectWindow; | |
| 67 @property (nonatomic, copy) NSString* username; | 65 @property (nonatomic, copy) NSString* username; |
| 66 |
| 67 - (BOOL)isRToL; |
| 68 |
| 68 @end | 69 @end |
| 69 | 70 |
| 70 @implementation DisconnectWindowController | 71 @implementation DisconnectWindowController |
| 71 | 72 |
| 72 @synthesize host = host_; | 73 @synthesize host = host_; |
| 73 @synthesize disconnectWindow = disconnectWindow_; | |
| 74 @synthesize username = username_; | 74 @synthesize username = username_; |
| 75 | 75 |
| 76 - (void)close { | |
| 77 self.host = NULL; | |
| 78 [super close]; | |
| 79 } | |
| 80 | |
| 81 - (id)initWithHost:(remoting::ChromotingHost*)host | 76 - (id)initWithHost:(remoting::ChromotingHost*)host |
| 82 window:(remoting::DisconnectWindowMac*)disconnectWindow | |
| 83 username:(NSString*)username { | 77 username:(NSString*)username { |
| 84 self = [super initWithWindowNibName:@"disconnect_window"]; | 78 self = [super initWithWindowNibName:@"disconnect_window"]; |
| 85 if (self) { | 79 if (self) { |
| 86 host_ = host; | 80 host_ = host; |
| 87 disconnectWindow_ = disconnectWindow; | |
| 88 username_ = [username copy]; | 81 username_ = [username copy]; |
| 89 } | 82 } |
| 90 return self; | 83 return self; |
| 91 } | 84 } |
| 92 | 85 |
| 93 - (void)dealloc { | 86 - (void)dealloc { |
| 94 [username_ release]; | 87 [username_ release]; |
| 95 [super dealloc]; | 88 [super dealloc]; |
| 96 } | 89 } |
| 97 | 90 |
| 98 - (IBAction)stopSharing:(id)sender { | 91 - (IBAction)stopSharing:(id)sender { |
| 99 if (self.host) { | 92 if (self.host) { |
| 100 self.host->Shutdown(NULL); | 93 self.host->Shutdown(NULL); |
| 101 self.host = NULL; | 94 self.host = NULL; |
| 102 } | 95 } |
| 103 self.disconnectWindow = NULL; | 96 } |
| 97 |
| 98 - (BOOL)isRToL { |
| 99 return host_->ui_strings().direction == remoting::UiStrings::RTL; |
| 100 } |
| 101 |
| 102 - (void)close { |
| 103 self.host = NULL; |
| 104 [super close]; |
| 104 } | 105 } |
| 105 | 106 |
| 106 - (void)windowDidLoad { | 107 - (void)windowDidLoad { |
| 107 string16 text = ReplaceStringPlaceholders( | 108 string16 text = ReplaceStringPlaceholders( |
| 108 host_->ui_strings().disconnect_message, | 109 host_->ui_strings().disconnect_message, |
| 109 base::SysNSStringToUTF16(self.username), | 110 base::SysNSStringToUTF16(self.username), |
| 110 NULL); | 111 NULL); |
| 111 [connectedToField_ setStringValue:base::SysUTF16ToNSString(text)]; | 112 [connectedToField_ setStringValue:base::SysUTF16ToNSString(text)]; |
| 112 | 113 |
| 113 [disconnectButton_ setTitle:base::SysUTF16ToNSString( | 114 [disconnectButton_ setTitle:base::SysUTF16ToNSString( |
| 114 host_->ui_strings().disconnect_button_text_plus_shortcut)]; | 115 host_->ui_strings().disconnect_button_text_plus_shortcut)]; |
| 115 | 116 |
| 116 // Resize the window dynamically based on the content. | 117 // Resize the window dynamically based on the content. |
| 117 CGFloat oldConnectedWidth = NSWidth([connectedToField_ bounds]); | 118 CGFloat oldConnectedWidth = NSWidth([connectedToField_ bounds]); |
| 118 [connectedToField_ sizeToFit]; | 119 [connectedToField_ sizeToFit]; |
| 119 CGFloat newConnectedWidth = NSWidth([connectedToField_ bounds]); | 120 NSRect connectedToFrame = [connectedToField_ frame]; |
| 121 CGFloat newConnectedWidth = NSWidth(connectedToFrame); |
| 122 |
| 123 // Set a max width for the connected to text field. |
| 124 if (newConnectedWidth > |
| 125 remoting::DisconnectWindow::kMaximumConnectedNameWidthInPixels) { |
| 126 newConnectedWidth |
| 127 = remoting::DisconnectWindow::kMaximumConnectedNameWidthInPixels; |
| 128 connectedToFrame.size.width = newConnectedWidth; |
| 129 [connectedToField_ setFrame:connectedToFrame]; |
| 130 } |
| 120 | 131 |
| 121 CGFloat oldDisconnectWidth = NSWidth([disconnectButton_ bounds]); | 132 CGFloat oldDisconnectWidth = NSWidth([disconnectButton_ bounds]); |
| 122 [disconnectButton_ sizeToFit]; | 133 [disconnectButton_ sizeToFit]; |
| 123 NSRect disconnectBounds = [disconnectButton_ frame]; | 134 NSRect disconnectFrame = [disconnectButton_ frame]; |
| 124 CGFloat newDisconnectWidth = NSWidth(disconnectBounds); | 135 CGFloat newDisconnectWidth = NSWidth(disconnectFrame); |
| 125 | 136 |
| 126 // Move the disconnect button appropriately. | 137 // Move the disconnect button appropriately. |
| 127 disconnectBounds.origin.x += newConnectedWidth - oldConnectedWidth; | 138 disconnectFrame.origin.x += newConnectedWidth - oldConnectedWidth; |
| 128 [disconnectButton_ setFrame:disconnectBounds]; | 139 [disconnectButton_ setFrame:disconnectFrame]; |
| 129 | 140 |
| 130 // Then resize the window appropriately | 141 // Then resize the window appropriately |
| 131 NSWindow *window = [self window]; | 142 NSWindow *window = [self window]; |
| 132 NSRect windowFrame = [window frame]; | 143 NSRect windowFrame = [window frame]; |
| 133 windowFrame.size.width += (newConnectedWidth - oldConnectedWidth + | 144 windowFrame.size.width += (newConnectedWidth - oldConnectedWidth + |
| 134 newDisconnectWidth - oldDisconnectWidth); | 145 newDisconnectWidth - oldDisconnectWidth); |
| 135 [window setFrame:windowFrame display:NO]; | 146 [window setFrame:windowFrame display:NO]; |
| 147 |
| 148 if ([self isRToL]) { |
| 149 // Handle right to left case |
| 150 CGFloat buttonInset = NSWidth(windowFrame) - NSMaxX(disconnectFrame); |
| 151 CGFloat buttonTextSpacing |
| 152 = NSMinX(disconnectFrame) - NSMaxX(connectedToFrame); |
| 153 disconnectFrame.origin.x = buttonInset; |
| 154 connectedToFrame.origin.x = NSMaxX(disconnectFrame) + buttonTextSpacing; |
| 155 [connectedToField_ setFrame:connectedToFrame]; |
| 156 [disconnectButton_ setFrame:disconnectFrame]; |
| 157 } |
| 136 } | 158 } |
| 137 | 159 |
| 138 - (void)windowWillClose:(NSNotification*)notification { | 160 - (void)windowWillClose:(NSNotification*)notification { |
| 139 [self stopSharing:self]; | 161 [self stopSharing:self]; |
| 140 [self autorelease]; | 162 [self autorelease]; |
| 141 } | 163 } |
| 142 | 164 |
| 143 @end | 165 @end |
| 144 | 166 |
| 167 |
| 168 @interface DisconnectWindow() |
| 169 - (BOOL)isRToL; |
| 170 @end |
| 171 |
| 145 @implementation DisconnectWindow | 172 @implementation DisconnectWindow |
| 146 | 173 |
| 147 - (id)initWithContentRect:(NSRect)contentRect | 174 - (id)initWithContentRect:(NSRect)contentRect |
| 148 styleMask:(unsigned int)aStyle | 175 styleMask:(unsigned int)aStyle |
| 149 backing:(NSBackingStoreType)bufferingType | 176 backing:(NSBackingStoreType)bufferingType |
| 150 defer:(BOOL)flag { | 177 defer:(BOOL)flag { |
| 151 // Pass NSBorderlessWindowMask for the styleMask to remove the title bar. | 178 // Pass NSBorderlessWindowMask for the styleMask to remove the title bar. |
| 152 self = [super initWithContentRect:contentRect | 179 self = [super initWithContentRect:contentRect |
| 153 styleMask:NSBorderlessWindowMask | 180 styleMask:NSBorderlessWindowMask |
| 154 backing:bufferingType | 181 backing:bufferingType |
| 155 defer:flag]; | 182 defer:flag]; |
| 156 | 183 |
| 157 if (self) { | 184 if (self) { |
| 158 // Set window to be clear and non-opaque so we can see through it. | 185 // Set window to be clear and non-opaque so we can see through it. |
| 159 [self setBackgroundColor:[NSColor clearColor]]; | 186 [self setBackgroundColor:[NSColor clearColor]]; |
| 160 [self setOpaque:NO]; | 187 [self setOpaque:NO]; |
| 161 [self setMovableByWindowBackground:YES]; | 188 [self setMovableByWindowBackground:YES]; |
| 162 | 189 |
| 163 // Pull the window up to Status Level so that it always displays. | 190 // Pull the window up to Status Level so that it always displays. |
| 164 [self setLevel:NSStatusWindowLevel]; | 191 [self setLevel:NSStatusWindowLevel]; |
| 165 } | 192 } |
| 166 return self; | 193 return self; |
| 167 } | 194 } |
| 168 | 195 |
| 196 - (BOOL)isRToL { |
| 197 DCHECK([[self windowController] respondsToSelector:@selector(isRToL)]); |
| 198 return [[self windowController] isRToL]; |
| 199 } |
| 200 |
| 169 @end | 201 @end |
| 170 | 202 |
| 203 |
| 204 @interface DisconnectView() |
| 205 - (BOOL)isRToL; |
| 206 @end |
| 207 |
| 171 @implementation DisconnectView | 208 @implementation DisconnectView |
| 172 | 209 |
| 210 - (BOOL)isRToL { |
| 211 DCHECK([[self window] isKindOfClass:[DisconnectWindow class]]); |
| 212 return [static_cast<DisconnectWindow*>([self window]) isRToL]; |
| 213 } |
| 214 |
| 173 - (void)drawRect:(NSRect)rect { | 215 - (void)drawRect:(NSRect)rect { |
| 174 // All magic numbers taken from screen shots provided by UX. | 216 // All magic numbers taken from screen shots provided by UX. |
| 175 NSRect bounds = NSInsetRect([self bounds], 1.5, 1.5); | 217 NSRect bounds = NSInsetRect([self bounds], 1, 1); |
| 176 | 218 |
| 177 NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:bounds | 219 NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:bounds |
| 178 xRadius:5 | 220 xRadius:5 |
| 179 yRadius:5]; | 221 yRadius:5]; |
| 180 NSColor *gray = [NSColor colorWithCalibratedWhite:0.91 alpha:1.0]; | 222 NSColor *gray = [NSColor colorWithCalibratedWhite:0.91 alpha:1.0]; |
| 181 [gray setFill]; | 223 [gray setFill]; |
| 182 [path fill]; | 224 [path fill]; |
| 183 [path setLineWidth:3]; | 225 [path setLineWidth:4]; |
| 184 NSColor *green = [NSColor colorWithCalibratedRed:0.13 | 226 NSColor *green = [NSColor colorWithCalibratedRed:0.13 |
| 185 green:0.69 | 227 green:0.69 |
| 186 blue:0.11 | 228 blue:0.11 |
| 187 alpha:1.0]; | 229 alpha:1.0]; |
| 188 [green setStroke]; | 230 [green setStroke]; |
| 189 [path stroke]; | 231 [path stroke]; |
| 190 | 232 |
| 191 // Draw drag handle on left hand side | 233 |
| 192 const CGFloat height = 21.0; | 234 // Draw drag handle on proper side |
| 193 const CGFloat inset = 12.0; | 235 const CGFloat kHeight = 21.0; |
| 236 const CGFloat kBaseInset = 12.0; |
| 237 const CGFloat kDragHandleWidth = 5.0; |
| 238 |
| 194 NSColor *dark = [NSColor colorWithCalibratedWhite:0.70 alpha:1.0]; | 239 NSColor *dark = [NSColor colorWithCalibratedWhite:0.70 alpha:1.0]; |
| 195 NSColor *light = [NSColor colorWithCalibratedWhite:0.97 alpha:1.0]; | 240 NSColor *light = [NSColor colorWithCalibratedWhite:0.97 alpha:1.0]; |
| 196 | 241 |
| 197 // Turn off aliasing so it's nice and crisp. | 242 // Turn off aliasing so it's nice and crisp. |
| 198 NSGraphicsContext *context = [NSGraphicsContext currentContext]; | 243 NSGraphicsContext *context = [NSGraphicsContext currentContext]; |
| 199 BOOL alias = [context shouldAntialias]; | 244 BOOL alias = [context shouldAntialias]; |
| 200 [context setShouldAntialias:NO]; | 245 [context setShouldAntialias:NO]; |
| 201 | 246 |
| 202 NSPoint top = NSMakePoint(inset, NSMidY(bounds) - height / 2.0); | 247 // Handle bidirectional locales properly. |
| 203 NSPoint bottom = NSMakePoint(inset, top.y + height); | 248 CGFloat inset = [self isRToL] ? NSMaxX(bounds) - kBaseInset - kDragHandleWidth |
| 249 : kBaseInset; |
| 250 |
| 251 NSPoint top = NSMakePoint(inset, NSMidY(bounds) - kHeight / 2.0); |
| 252 NSPoint bottom = NSMakePoint(inset, top.y + kHeight); |
| 204 | 253 |
| 205 path = [NSBezierPath bezierPath]; | 254 path = [NSBezierPath bezierPath]; |
| 206 [path moveToPoint:top]; | 255 [path moveToPoint:top]; |
| 207 [path lineToPoint:bottom]; | 256 [path lineToPoint:bottom]; |
| 208 [dark setStroke]; | 257 [dark setStroke]; |
| 209 [path stroke]; | 258 [path stroke]; |
| 210 | 259 |
| 211 top.x += 1; | 260 top.x += 1; |
| 212 bottom.x += 1; | 261 bottom.x += 1; |
| 213 path = [NSBezierPath bezierPath]; | 262 path = [NSBezierPath bezierPath]; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 229 path = [NSBezierPath bezierPath]; | 278 path = [NSBezierPath bezierPath]; |
| 230 [path moveToPoint:top]; | 279 [path moveToPoint:top]; |
| 231 [path lineToPoint:bottom]; | 280 [path lineToPoint:bottom]; |
| 232 [light setStroke]; | 281 [light setStroke]; |
| 233 [path stroke]; | 282 [path stroke]; |
| 234 | 283 |
| 235 [context setShouldAntialias:alias]; | 284 [context setShouldAntialias:alias]; |
| 236 } | 285 } |
| 237 | 286 |
| 238 @end | 287 @end |
| 239 | |
| OLD | NEW |