15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <Cocoa/Cocoa.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import "remoting/host/disconnect_window_mac.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/i18n/rtl.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/weak_ptr.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "remoting/base/string_resources.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/client_session_control.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/host_window.h"
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/base/l10n/l10n_util_mac.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)@interface DisconnectWindowController()
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (BOOL)isRToL;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (void)Hide;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)@end
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int kMaximumConnectedNameWidthInPixels = 600;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DisconnectWindowMac : public HostWindow {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DisconnectWindowMac();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DisconnectWindowMac();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // HostWindow overrides.
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Start(
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::WeakPtr<ClientSessionControl>& client_session_control)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DisconnectWindowController* window_controller_;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DisconnectWindowMac);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DisconnectWindowMac::DisconnectWindowMac()
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : window_controller_(nil) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisconnectWindowMac::~DisconnectWindowMac() {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DisconnectWindowController is responsible for releasing itself in its
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // windowWillClose: method.
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  [window_controller_ Hide];
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_controller_ = nil;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DisconnectWindowMac::Start(
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::WeakPtr<ClientSessionControl>& client_session_control) {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(client_session_control);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(window_controller_ == nil);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create the window.
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Closure disconnect_callback =
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ClientSessionControl::DisconnectSession,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 client_session_control);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string client_jid = client_session_control->client_jid();
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string username = client_jid.substr(0, client_jid.find('/'));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_controller_ =
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      [[DisconnectWindowController alloc] initWithCallback:disconnect_callback
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                  username:username];
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_controller_ showWindow:nil];
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow() {
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return scoped_ptr<HostWindow>(new DisconnectWindowMac());
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation DisconnectWindowController
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)- (id)initWithCallback:(const base::Closure&)disconnect_callback
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              username:(const std::string&)username {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self = [super initWithWindowNibName:@"disconnect_window"];
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disconnect_callback_ = disconnect_callback;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    username_ = base::UTF8ToUTF16(username);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)dealloc {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [super dealloc];
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (IBAction)stopSharing:(id)sender {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!disconnect_callback_.is_null()) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disconnect_callback_.Run();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)isRToL {
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return base::i18n::IsRTL();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (void)Hide {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  disconnect_callback_.Reset();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  [self close];
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)windowDidLoad {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  [connectedToField_ setStringValue:l10n_util::GetNSStringF(IDS_MESSAGE_SHARED,
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                            username_)];
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  [disconnectButton_ setTitle:l10n_util::GetNSString(IDS_STOP_SHARING_BUTTON)];
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resize the window dynamically based on the content.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat oldConnectedWidth = NSWidth([connectedToField_ bounds]);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [connectedToField_ sizeToFit];
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect connectedToFrame = [connectedToField_ frame];
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat newConnectedWidth = NSWidth(connectedToFrame);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a max width for the connected to text field.
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (newConnectedWidth > kMaximumConnectedNameWidthInPixels) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    newConnectedWidth = kMaximumConnectedNameWidthInPixels;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connectedToFrame.size.width = newConnectedWidth;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [connectedToField_ setFrame:connectedToFrame];
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat oldDisconnectWidth = NSWidth([disconnectButton_ bounds]);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [disconnectButton_ sizeToFit];
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect disconnectFrame = [disconnectButton_ frame];
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat newDisconnectWidth = NSWidth(disconnectFrame);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the disconnect button appropriately.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disconnectFrame.origin.x += newConnectedWidth - oldConnectedWidth;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [disconnectButton_ setFrame:disconnectFrame];
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then resize the window appropriately
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSWindow *window = [self window];
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect windowFrame = [window frame];
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windowFrame.size.width += (newConnectedWidth - oldConnectedWidth +
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             newDisconnectWidth - oldDisconnectWidth);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window setFrame:windowFrame display:NO];
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ([self isRToL]) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Handle right to left case
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CGFloat buttonInset = NSWidth(windowFrame) - NSMaxX(disconnectFrame);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CGFloat buttonTextSpacing
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        = NSMinX(disconnectFrame) - NSMaxX(connectedToFrame);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disconnectFrame.origin.x = buttonInset;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connectedToFrame.origin.x = NSMaxX(disconnectFrame) + buttonTextSpacing;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [connectedToField_ setFrame:connectedToFrame];
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [disconnectButton_ setFrame:disconnectFrame];
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Center the window at the bottom of the screen, above the dock (if present).
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect desktopRect = [[NSScreen mainScreen] visibleFrame];
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect windowRect = [[self window] frame];
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat x = (NSWidth(desktopRect) - NSWidth(windowRect)) / 2;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat y = NSMinY(desktopRect);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [[self window] setFrameOrigin:NSMakePoint(x, y)];
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)windowWillClose:(NSNotification*)notification {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [self stopSharing:self];
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [self autorelease];
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface DisconnectWindow()
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)isRToL;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation DisconnectWindow
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (id)initWithContentRect:(NSRect)contentRect
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                styleMask:(NSUInteger)aStyle
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  backing:(NSBackingStoreType)bufferingType
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  defer:(BOOL)flag {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass NSBorderlessWindowMask for the styleMask to remove the title bar.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self = [super initWithContentRect:contentRect
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          styleMask:NSBorderlessWindowMask
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            backing:bufferingType
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              defer:flag];
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set window to be clear and non-opaque so we can see through it.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [self setBackgroundColor:[NSColor clearColor]];
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [self setOpaque:NO];
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [self setMovableByWindowBackground:YES];
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Pull the window up to Status Level so that it always displays.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [self setLevel:NSStatusWindowLevel];
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)isRToL {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK([[self windowController] respondsToSelector:@selector(isRToL)]);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return [[self windowController] isRToL];
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface DisconnectView()
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)isRToL;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation DisconnectView
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)isRToL {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK([[self window] isKindOfClass:[DisconnectWindow class]]);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return [static_cast<DisconnectWindow*>([self window]) isRToL];
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)drawRect:(NSRect)rect {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All magic numbers taken from screen shots provided by UX.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSRect bounds = NSInsetRect([self bounds], 1, 1);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:bounds
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       xRadius:5
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       yRadius:5];
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSColor *gray = [NSColor colorWithCalibratedWhite:0.91 alpha:1.0];
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [gray setFill];
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path fill];
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path setLineWidth:4];
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSColor *green = [NSColor colorWithCalibratedRed:0.13
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             green:0.69
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              blue:0.11
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             alpha:1.0];
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [green setStroke];
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path stroke];
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw drag handle on proper side
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CGFloat kHeight = 21.0;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CGFloat kBaseInset = 12.0;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CGFloat kDragHandleWidth = 5.0;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSColor *dark = [NSColor colorWithCalibratedWhite:0.70 alpha:1.0];
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSColor *light = [NSColor colorWithCalibratedWhite:0.97 alpha:1.0];
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Turn off aliasing so it's nice and crisp.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSGraphicsContext *context = [NSGraphicsContext currentContext];
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BOOL alias = [context shouldAntialias];
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [context setShouldAntialias:NO];
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle bidirectional locales properly.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGFloat inset = [self isRToL] ? NSMaxX(bounds) - kBaseInset - kDragHandleWidth
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                : kBaseInset;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSPoint top = NSMakePoint(inset, NSMidY(bounds) - kHeight / 2.0);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSPoint bottom = NSMakePoint(inset, top.y + kHeight);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = [NSBezierPath bezierPath];
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path moveToPoint:top];
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path lineToPoint:bottom];
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [dark setStroke];
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path stroke];
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top.x += 1;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bottom.x += 1;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = [NSBezierPath bezierPath];
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path moveToPoint:top];
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path lineToPoint:bottom];
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [light setStroke];
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path stroke];
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top.x += 2;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bottom.x += 2;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = [NSBezierPath bezierPath];
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path moveToPoint:top];
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path lineToPoint:bottom];
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [dark setStroke];
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path stroke];
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top.x += 1;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bottom.x += 1;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = [NSBezierPath bezierPath];
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path moveToPoint:top];
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path lineToPoint:bottom];
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [light setStroke];
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [path stroke];
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [context setShouldAntialias:alias];
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
294