diff --git a/CMakeLists.txt b/CMakeLists.txt index c619bc2748f9c789132934b174efef4448a054d8..fadcc7c828d635a030b50d2c6a38fcdbecb913c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,9 @@ SET(ringclient_CONTROLLERS src/HistoryVC.mm src/HistoryVC.h src/PersonsVC.mm - src/PersonsVC.h) + src/PersonsVC.h + src/ChatVC.mm + src/ChatVC.h) SET(ringclient_BACKENDS src/backends/AddressBookBackend.mm diff --git a/src/ChatVC.h b/src/ChatVC.h new file mode 100644 index 0000000000000000000000000000000000000000..f07f5afeace829c64852eafe4e95712385761838 --- /dev/null +++ b/src/ChatVC.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Savoir-Faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ +#import <Cocoa/Cocoa.h> + +@interface ChatVC : NSViewController <NSTextFieldDelegate> + +/** + * Message contained in messageField TextField. + * This is a KVO method to bind the text with the send Button + * if message.length is > 0, button is enabled, otherwise disabled + */ +@property (retain) NSString* message; + +@end diff --git a/src/ChatVC.mm b/src/ChatVC.mm new file mode 100644 index 0000000000000000000000000000000000000000..bedbdd2996d7fe9501388c237d5206f93afd6adf --- /dev/null +++ b/src/ChatVC.mm @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2015 Savoir-Faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#import "ChatVC.h" + +#import <QItemSelectionModel> +#import <qstring.h> + +#import <media/media.h> +#import <media/text.h> +#import <media/textrecording.h> +#import <callmodel.h> + +@interface MediaConnectionsHolder : NSObject + +@property QMetaObject::Connection newMediaAdded; +@property QMetaObject::Connection newMessage; + +@end + +@implementation MediaConnectionsHolder + +@end + +@interface ChatVC () + +@property (unsafe_unretained) IBOutlet NSTextView *chatView; +@property (unsafe_unretained) IBOutlet NSTextField *messageField; +@property (unsafe_unretained) IBOutlet NSButton *sendButton; + +@property MediaConnectionsHolder* mediaHolder; + +@end + +@implementation ChatVC +@synthesize messageField,chatView,sendButton, mediaHolder; + +- (void)awakeFromNib +{ + NSLog(@"Init ChatVC"); + + [self.view setWantsLayer:YES]; + [self.view setLayer:[CALayer layer]]; + [self.view.layer setBackgroundColor:[NSColor blackColor].CGColor]; + + mediaHolder = [[MediaConnectionsHolder alloc] init]; + + QObject::connect(CallModel::instance()->selectionModel(), + &QItemSelectionModel::currentChanged, + [=](const QModelIndex ¤t, const QModelIndex &previous) { + [self setupChat]; + }); +} + +- (void) setupChat +{ + QObject::disconnect(mediaHolder.newMediaAdded); + QObject::disconnect(mediaHolder.newMessage); + + QModelIndex callIdx = CallModel::instance()->selectionModel()->currentIndex(); + + if (!callIdx.isValid()) + return; + + Call* call = CallModel::instance()->getCall(callIdx); + + /* check if text media is already present */ + if (call->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::IN)) { + Media::Text *text = call->firstMedia<Media::Text>(Media::Media::Direction::IN); + [self parseChatModel:text->recording()->instantMessagingModel()]; + } else if (call->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::OUT)) { + Media::Text *text = call->firstMedia<Media::Text>(Media::Media::Direction::OUT); + [self parseChatModel:text->recording()->instantMessagingModel()]; + } else { + /* monitor media for messaging text messaging */ + mediaHolder.newMediaAdded = QObject::connect(call, + &Call::mediaAdded, + [self] (Media::Media* media) { + if (media->type() == Media::Media::Type::TEXT) { + QObject::disconnect(mediaHolder.newMediaAdded); + [self parseChatModel:((Media::Text*)media)->recording()->instantMessagingModel()]; + + } + }); + } +} + +- (void) parseChatModel:(QAbstractItemModel *)model +{ + QObject::disconnect(mediaHolder.newMessage); + [self.messageField setStringValue:@""]; + self.message = @""; + [self.chatView.textStorage.mutableString setString:@""]; + + /* put all the messages in the im model into the text view */ + for (int row = 0; row < model->rowCount(); ++row) { + [self appendNewMessage:model->index(row, 0)]; + } + + /* append new messages */ + mediaHolder.newMessage = QObject::connect(model, + &QAbstractItemModel::rowsInserted, + [self, model] (const QModelIndex &parent, int first, int last) { + for (int row = first; row <= last; ++row) { + QModelIndex idx = model->index(row, 0, parent); + [self appendNewMessage:idx]; + } + } + ); +} + +- (void) appendNewMessage:(const QModelIndex&) msgIdx +{ + if (!msgIdx.isValid()) + return; + + QVariant message = msgIdx.data(); + NSAttributedString* attr = [[NSAttributedString alloc] initWithString: + [NSString stringWithFormat:@"%@\n",message.value<QString>().toNSString()]]; + [[chatView textStorage] appendAttributedString:attr]; + [chatView scrollRangeToVisible:NSMakeRange([[chatView string] length], 0)]; + +} + +- (IBAction)sendMessage:(id)sender { + + QModelIndex callIdx = CallModel::instance()->selectionModel()->currentIndex(); + Call* call = CallModel::instance()->getCall(callIdx); + + /* make sure there is text to send */ + NSString* text = self.message; + if (text && text.length > 0) { + call->addOutgoingMedia<Media::Text>()->send(QString::fromNSString(text)); + // Empty the text after sending it + [self.messageField setStringValue:@""]; + self.message = @""; + } +} + +#pragma mark - NSTextFieldDelegate + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector +{ + if (commandSelector == @selector(insertNewline:) && self.message.length > 0) { + [self sendMessage:nil]; + return YES; + } + return NO; +} + +@end diff --git a/src/ConversationsVC.mm b/src/ConversationsVC.mm index c7dabad97726b68b14472e7a89971fdccfd5d5fe..13aa12ff520b9b3b5384cf3361cd23edef56d550 100644 --- a/src/ConversationsVC.mm +++ b/src/ConversationsVC.mm @@ -32,14 +32,10 @@ #import <callmodel.h> #import <QtCore/qitemselectionmodel.h> -#import "CurrentCallVC.h" - #define COLUMNID_CONVERSATIONS @"ConversationsColumn" // the single column name in our outline view @interface ConversationsVC () -@property CurrentCallVC* currentVC; -@property (assign) IBOutlet NSView *currentCallView; @property QNSTreeController *treeController; @property (assign) IBOutlet NSOutlineView *conversationsView; @@ -48,9 +44,6 @@ @implementation ConversationsVC @synthesize conversationsView; @synthesize treeController; -@synthesize currentVC; -@synthesize currentCallView; - - (void)awakeFromNib { NSLog(@"INIT Conversations VC"); @@ -73,15 +66,7 @@ [conversationsView reloadDataForRowIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(topLeft.row(), bottomRight.row() + 1)] columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, conversationsView.tableColumns.count)]]; - }); - - currentVC = [[CurrentCallVC alloc] initWithNibName:@"CurrentCall" bundle:nil]; - [currentCallView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [[currentVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - - [currentCallView addSubview:[self.currentVC view]]; - [currentVC initFrame]; } #pragma mark - NSOutlineViewDelegate methods diff --git a/src/CurrentCallVC.h b/src/CurrentCallVC.h index e24cf01203d9bb9d078ebe61ddd613eb0bc6003b..7000c554eebebf2c759222ad0e10e1ea693fd432 100644 --- a/src/CurrentCallVC.h +++ b/src/CurrentCallVC.h @@ -32,9 +32,11 @@ #import <Cocoa/Cocoa.h> +#import "views/CallView.h" + class Call; -@interface CurrentCallVC : NSViewController { +@interface CurrentCallVC : NSViewController <NSSplitViewDelegate, FullScreenDelegate> { } diff --git a/src/CurrentCallVC.mm b/src/CurrentCallVC.mm index aa853cbfea684293ff8fd6a9ef51b1495b35f603..0035a15daa32fb9c5111eef3fbc0451a4a3f18a4 100644 --- a/src/CurrentCallVC.mm +++ b/src/CurrentCallVC.mm @@ -40,11 +40,10 @@ #import <QItemSelection> #import <video/previewmanager.h> #import <video/renderer.h> +#import <media/text.h> #import "views/CallView.h" -/** FrameReceiver class - delegate for AVCaptureSession - */ @interface RendererConnectionsHolder : NSObject @property QMetaObject::Connection frameUpdated; @@ -59,21 +58,23 @@ @interface CurrentCallVC () -@property (assign) IBOutlet NSTextField *personLabel; -@property (assign) IBOutlet NSTextField *stateLabel; -@property (assign) IBOutlet NSButton *holdOnOffButton; -@property (assign) IBOutlet NSButton *hangUpButton; -@property (assign) IBOutlet NSButton *recordOnOffButton; -@property (assign) IBOutlet NSButton *pickUpButton; -@property (assign) IBOutlet NSTextField *timeSpentLabel; -@property (assign) IBOutlet NSView *controlsPanel; +@property (unsafe_unretained) IBOutlet NSTextField *personLabel; +@property (unsafe_unretained) IBOutlet NSTextField *stateLabel; +@property (unsafe_unretained) IBOutlet NSButton *holdOnOffButton; +@property (unsafe_unretained) IBOutlet NSButton *hangUpButton; +@property (unsafe_unretained) IBOutlet NSButton *recordOnOffButton; +@property (unsafe_unretained) IBOutlet NSButton *pickUpButton; +@property (unsafe_unretained) IBOutlet NSTextField *timeSpentLabel; +@property (unsafe_unretained) IBOutlet NSView *controlsPanel; +@property (unsafe_unretained) IBOutlet NSSplitView *splitView; +@property (unsafe_unretained) IBOutlet NSButton *chatButton; @property QHash<int, NSButton*> actionHash; // Video -@property (assign) IBOutlet CallView *videoView; +@property (unsafe_unretained) IBOutlet CallView *videoView; @property CALayer* videoLayer; -@property (assign) IBOutlet NSView *previewView; +@property (unsafe_unretained) IBOutlet NSView *previewView; @property CALayer* previewLayer; @property RendererConnectionsHolder* previewHolder; @@ -90,12 +91,14 @@ @synthesize hangUpButton; @synthesize recordOnOffButton; @synthesize pickUpButton; +@synthesize chatButton; @synthesize timeSpentLabel; @synthesize controlsPanel; @synthesize videoView; @synthesize videoLayer; @synthesize previewLayer; @synthesize previewView; +@synthesize splitView; @synthesize previewHolder; @synthesize videoHolder; @@ -128,10 +131,10 @@ -(void) updateCall { QModelIndex callIdx = CallModel::instance()->selectionModel()->currentIndex(); - [personLabel setStringValue:CallModel::instance()->data(callIdx, Qt::DisplayRole).toString().toNSString()]; - [timeSpentLabel setStringValue:CallModel::instance()->data(callIdx, (int)Call::Role::Length).toString().toNSString()]; + [personLabel setStringValue:callIdx.data(Qt::DisplayRole).toString().toNSString()]; + [timeSpentLabel setStringValue:callIdx.data((int)Call::Role::Length).toString().toNSString()]; - Call::State state = CallModel::instance()->data(callIdx, (int)Call::Role::State).value<Call::State>(); + Call::State state = callIdx.data((int)Call::Role::State).value<Call::State>(); switch (state) { case Call::State::DIALING: @@ -221,6 +224,8 @@ previewHolder = [[RendererConnectionsHolder alloc] init]; videoHolder = [[RendererConnectionsHolder alloc] init]; + [self.videoView setFullScreenDelegate:self]; + [self connect]; } @@ -233,6 +238,7 @@ [self animateOut]; return; } + [self collapseRightView]; [self updateCall]; [self updateAllActions]; [self animateOut]; @@ -264,7 +270,7 @@ { QModelIndex idx = CallModel::instance()->selectionModel()->currentIndex(); Call* call = CallModel::instance()->getCall(idx); - QObject::connect(call, + self.videoStarted = QObject::connect(call, &Call::videoStarted, [=](Video::Renderer* renderer) { NSLog(@"Video started!"); @@ -453,8 +459,37 @@ NSLog(@"frame %@ : %f %f %f %f \n\n",name ,frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); } +-(void)collapseRightView +{ + NSView *right = [[splitView subviews] objectAtIndex:1]; + NSView *left = [[splitView subviews] objectAtIndex:0]; + NSRect leftFrame = [left frame]; + [right setHidden:YES]; + [splitView display]; +} + +-(void)uncollapseRightView +{ + NSView *left = [[splitView subviews] objectAtIndex:0]; + NSView *right = [[splitView subviews] objectAtIndex:1]; + [right setHidden:NO]; + + CGFloat dividerThickness = [splitView dividerThickness]; + + // get the different frames + NSRect leftFrame = [left frame]; + NSRect rightFrame = [right frame]; + + leftFrame.size.width = (leftFrame.size.width - rightFrame.size.width - dividerThickness); + rightFrame.origin.x = leftFrame.size.width + dividerThickness; + [left setFrameSize:leftFrame.size]; + [right setFrame:rightFrame]; + [splitView display]; +} + + +#pragma mark - Button methods -#pragma button methods - (IBAction)hangUp:(id)sender { CallModel::instance()->getCall(CallModel::instance()->selectionModel()->currentIndex()) << Call::Action::REFUSE; } @@ -471,4 +506,50 @@ CallModel::instance()->getCall(CallModel::instance()->selectionModel()->currentIndex()) << Call::Action::HOLD; } +-(IBAction)toggleChat:(id)sender; +{ + BOOL rightViewCollapsed = [[self splitView] isSubviewCollapsed:[[[self splitView] subviews] objectAtIndex: 1]]; + if (rightViewCollapsed) { + [self uncollapseRightView]; + CallModel::instance()->getCall(CallModel::instance()->selectionModel()->currentIndex())->addOutgoingMedia<Media::Text>(); + } else { + [self collapseRightView]; + } + [chatButton setState:rightViewCollapsed]; +} + +#pragma mark - NSSplitViewDelegate + +/* Return YES if the subview should be collapsed because the user has double-clicked on an adjacent divider. If a split view has a delegate, and the delegate responds to this message, it will be sent once for the subview before a divider when the user double-clicks on that divider, and again for the subview after the divider, but only if the delegate returned YES when sent -splitView:canCollapseSubview: for the subview in question. When the delegate indicates that both subviews should be collapsed NSSplitView's behavior is undefined. + */ +- (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subview forDoubleClickOnDividerAtIndex:(NSInteger)dividerIndex; +{ + NSView* rightView = [[splitView subviews] objectAtIndex:1]; + return ([subview isEqual:rightView]); +} + + +- (BOOL)splitView:(NSSplitView *)splitView canCollapseSubview:(NSView *)subview; +{ + NSView* rightView = [[splitView subviews] objectAtIndex:1]; + return ([subview isEqual:rightView]); +} + + +# pragma mark - FullScreenDelegate + +- (void) callShouldToggleFullScreen +{ + if(self.splitView.isInFullScreenMode) + [self.splitView exitFullScreenModeWithOptions:nil]; + else { + NSApplicationPresentationOptions options = NSApplicationPresentationDefault +NSApplicationPresentationAutoHideDock + + NSApplicationPresentationAutoHideMenuBar + NSApplicationPresentationAutoHideToolbar; + NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:options], + NSFullScreenModeApplicationPresentationOptions, nil]; + + [self.splitView enterFullScreenMode:[NSScreen mainScreen] withOptions:opts]; + } +} + @end diff --git a/src/RingWindowController.mm b/src/RingWindowController.mm index f708f7c7540c64fb8052bc6670ed84835b83907f..7559041d048b5b74ab0738da5139b7bbebf1751d 100644 --- a/src/RingWindowController.mm +++ b/src/RingWindowController.mm @@ -36,15 +36,22 @@ #import "AppDelegate.h" #import "Constants.h" +#import "CurrentCallVC.h" @interface RingWindowController () @property NSSearchField* callField; +@property CurrentCallVC* currentVC; +@property (unsafe_unretained) IBOutlet NSView *callView; + @end @implementation RingWindowController @synthesize callField; +@synthesize currentVC; +@synthesize callView; + static NSString* const kSearchViewIdentifier = @"SearchViewIdentifier"; static NSString* const kPreferencesIdentifier = @"PreferencesIdentifier"; static NSString* const kCallButtonIdentifer = @"CallButtonIdentifier"; @@ -53,6 +60,13 @@ static NSString* const kCallButtonIdentifer = @"CallButtonIdentifier"; [super windowDidLoad]; [self.window setReleasedWhenClosed:FALSE]; [self displayMainToolBar]; + + currentVC = [[CurrentCallVC alloc] initWithNibName:@"CurrentCall" bundle:nil]; + [callView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [[currentVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + + [callView addSubview:[self.currentVC view]]; + [currentVC initFrame]; } - (IBAction)openPreferences:(id)sender diff --git a/src/views/CallView.h b/src/views/CallView.h index 06b459096122e404e7838fab1b47786f3aa10ea0..b15d5251430f2938aceda9a8f79050e2bd23c64c 100644 --- a/src/views/CallView.h +++ b/src/views/CallView.h @@ -29,6 +29,15 @@ */ #import <Cocoa/Cocoa.h> +@protocol FullScreenDelegate; +@protocol FullScreenDelegate + +@optional + +-(void) callShouldToggleFullScreen; + +@end + @interface CallView : NSView <NSDraggingDestination, NSOpenSavePanelDelegate> { //highlight the drop zone @@ -42,4 +51,9 @@ */ @property BOOL shouldAcceptInteractions; +/** + * Delegate to inform about desire to move + */ +@property (nonatomic) id <FullScreenDelegate> fullScreenDelegate; + @end diff --git a/src/views/CallView.mm b/src/views/CallView.mm index 8831db20e89719939deb5de6744a1dbd9d2eb725..43a5d80499f4f2636d07f962f46f9c802eaa9c76 100644 --- a/src/views/CallView.mm +++ b/src/views/CallView.mm @@ -186,15 +186,8 @@ else if([theEvent clickCount] == 2) { [NSObject cancelPreviousPerformRequestsWithTarget:self]; // cancel showContextualMenu - if(self.isInFullScreenMode) - [self exitFullScreenModeWithOptions:nil]; - else { - NSApplicationPresentationOptions options = NSApplicationPresentationDefault + NSApplicationPresentationAutoHideDock + - NSApplicationPresentationAutoHideMenuBar + NSApplicationPresentationAutoHideToolbar; - NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:options], NSFullScreenModeApplicationPresentationOptions, nil]; - - [self enterFullScreenMode:[NSScreen mainScreen] withOptions:opts]; - } + if(self.fullScreenDelegate) + [self.fullScreenDelegate callShouldToggleFullScreen]; } } diff --git a/ui/CurrentCall.xib b/ui/CurrentCall.xib index 1d6538e02f6862dc3d2c3bdec8cb43015ec3aec9..02a15e2c6147cfd0436298ec82e368cfab46c26a 100644 --- a/ui/CurrentCall.xib +++ b/ui/CurrentCall.xib @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D2134" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <dependencies> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="CurrentCallVC"> <connections> + <outlet property="chatButton" destination="fmp-x4-Pef" id="ARt-dr-TRo"/> <outlet property="controlsPanel" destination="Eoi-B8-iL6" id="4xn-3b-SNn"/> <outlet property="hangUpButton" destination="Kjq-iM-NBL" id="Puz-4L-Okl"/> <outlet property="holdOnOffButton" destination="anb-Y8-JQi" id="HSl-pE-Kwg"/> @@ -13,6 +14,7 @@ <outlet property="pickUpButton" destination="qgD-3D-nD5" id="mkD-IT-22E"/> <outlet property="previewView" destination="6y6-RH-qOp" id="1PY-sd-mh4"/> <outlet property="recordOnOffButton" destination="oRa-pS-HN2" id="N7C-wn-0le"/> + <outlet property="splitView" destination="GIJ-gB-FZo" id="PM0-az-Q8X"/> <outlet property="stateLabel" destination="kFD-FB-vig" id="SSO-14-q2t"/> <outlet property="timeSpentLabel" destination="cIU-M7-xpN" id="9Rl-t3-gjY"/> <outlet property="videoView" destination="2wf-Py-l6B" id="dEF-Gx-w6x"/> @@ -22,170 +24,289 @@ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/> <customView id="Hz6-mo-xeY"> - <rect key="frame" x="0.0" y="0.0" width="608" height="493"/> + <rect key="frame" x="0.0" y="0.0" width="1014" height="509"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <subviews> - <customView translatesAutoresizingMaskIntoConstraints="NO" id="2wf-Py-l6B" customClass="CallView"> - <rect key="frame" x="0.0" y="0.0" width="608" height="493"/> + <splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GIJ-gB-FZo"> + <rect key="frame" x="0.0" y="0.0" width="1014" height="509"/> <subviews> - <customView translatesAutoresizingMaskIntoConstraints="NO" id="6y6-RH-qOp" userLabel="Preview"> - <rect key="frame" x="413" y="20" width="175" height="120"/> - <constraints> - <constraint firstAttribute="height" constant="120" id="BvU-kV-0uD"/> - <constraint firstAttribute="width" constant="175" id="aEv-Tt-tSD"/> - </constraints> - </customView> - <customView translatesAutoresizingMaskIntoConstraints="NO" id="Eoi-B8-iL6" userLabel="Controls"> - <rect key="frame" x="20" y="20" width="385" height="77"/> + <customView id="2wf-Py-l6B" customClass="CallView"> + <rect key="frame" x="0.0" y="0.0" width="675" height="509"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <subviews> - <button horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kjq-iM-NBL"> - <rect key="frame" x="187" y="8" width="80" height="60"/> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="d0X-cW-Xgz"> + <rect key="frame" x="20" y="438" width="635" height="71"/> + <subviews> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bg3-hB-nE8"> + <rect key="frame" x="18" y="40" width="85" height="17"/> + <constraints> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="81" id="gT7-Wu-XtU"/> + </constraints> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Person name" id="osk-LS-0Qg"> + <font key="font" metaFont="system"/> + <color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kFD-FB-vig"> + <rect key="frame" x="18" y="20" width="37" height="17"/> + <constraints> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="29" id="pft-oc-ZNh"/> + </constraints> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="State" id="ugy-uK-901"> + <font key="font" metaFont="system"/> + <color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="highlightColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cIU-M7-xpN"> + <rect key="frame" x="513" y="23" width="104" height="24"/> + <constraints> + <constraint firstAttribute="width" constant="100" id="9vz-kb-6L6"/> + </constraints> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Time" id="zsO-T7-9yi"> + <font key="font" size="20" name="HelveticaNeue"/> + <color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="highlightColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="string" keyPath="layer.cornerRadius" value="15"/> + </userDefinedRuntimeAttributes> + </textField> + </subviews> <constraints> - <constraint firstAttribute="width" constant="76" id="7Ja-wI-kLL"/> - <constraint firstAttribute="height" constant="55" id="E2W-LK-NfM"/> + <constraint firstItem="kFD-FB-vig" firstAttribute="leading" secondItem="bg3-hB-nE8" secondAttribute="leading" id="LXG-QI-oPf"/> + <constraint firstItem="cIU-M7-xpN" firstAttribute="top" secondItem="d0X-cW-Xgz" secondAttribute="top" constant="24" id="Qc7-qp-qSV"/> + <constraint firstAttribute="trailing" secondItem="cIU-M7-xpN" secondAttribute="trailing" constant="20" id="RXf-xZ-4f9"/> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="568" id="Xeq-Aa-f1W"/> + <constraint firstItem="kFD-FB-vig" firstAttribute="top" secondItem="bg3-hB-nE8" secondAttribute="bottom" constant="3" id="Z06-5v-81Q"/> + <constraint firstItem="kFD-FB-vig" firstAttribute="top" secondItem="bg3-hB-nE8" secondAttribute="bottom" constant="3" id="gRn-E6-o6O"/> + <constraint firstItem="kFD-FB-vig" firstAttribute="leading" secondItem="d0X-cW-Xgz" secondAttribute="leading" constant="20" id="i5C-8o-qKp"/> + <constraint firstAttribute="bottom" secondItem="kFD-FB-vig" secondAttribute="bottom" constant="20" id="l71-7V-oLx"/> + <constraint firstItem="bg3-hB-nE8" firstAttribute="leading" secondItem="d0X-cW-Xgz" secondAttribute="leading" constant="20" id="nV4-Vy-vqK"/> + <constraint firstAttribute="centerY" secondItem="cIU-M7-xpN" secondAttribute="centerY" id="yvc-8B-cEu"/> </constraints> - <buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="64F5804D-D61F-4A20-A8D3-6F9E71A72A27" imagePosition="overlaps" alignment="left" borderStyle="border" imageScaling="proportionallyDown" id="kR5-bV-2KY"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> - </buttonCell> - <connections> - <action selector="hangUp:" target="-2" id="1Fj-b8-nfh"/> - </connections> - </button> - <button horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qgD-3D-nD5"> - <rect key="frame" x="103" y="8" width="80" height="60"/> + </customView> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="Eoi-B8-iL6" userLabel="Controls"> + <rect key="frame" x="20" y="20" width="452" height="77"/> + <subviews> + <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Kjq-iM-NBL"> + <rect key="frame" x="186" y="8" width="80" height="60"/> + <constraints> + <constraint firstAttribute="width" constant="76" id="7Ja-wI-kLL"/> + <constraint firstAttribute="height" constant="55" id="E2W-LK-NfM"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="536D2CB3-F984-4261-A185-5FD010473380" imagePosition="overlaps" alignment="left" borderStyle="border" imageScaling="proportionallyDown" id="kR5-bV-2KY"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="hangUp:" target="-2" id="1Fj-b8-nfh"/> + </connections> + </button> + <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qgD-3D-nD5"> + <rect key="frame" x="102" y="8" width="80" height="60"/> + <constraints> + <constraint firstAttribute="width" constant="76" id="9Aq-GM-wT2"/> + <constraint firstAttribute="height" constant="55" id="mnN-fs-Rr6"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="365E0BA1-E8E9-417C-9637-69685AEF3D44" imagePosition="overlaps" alignment="left" borderStyle="border" imageScaling="proportionallyDown" id="CoO-HS-nEB"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="accept:" target="-2" id="maS-G8-eY7"/> + </connections> + </button> + <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oRa-pS-HN2"> + <rect key="frame" x="18" y="8" width="80" height="60"/> + <constraints> + <constraint firstAttribute="width" constant="76" id="Afw-2T-aY9"/> + <constraint firstAttribute="height" constant="55" id="t21-HC-Wvs"/> + </constraints> + <buttonCell key="cell" type="bevel" title="Record" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" id="rhz-4Z-avV"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="toggleRecording:" target="-2" id="gAc-ZJ-9PN"/> + </connections> + </button> + <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="anb-Y8-JQi"> + <rect key="frame" x="270" y="8" width="80" height="60"/> + <constraints> + <constraint firstAttribute="width" constant="76" id="QBx-uC-sub"/> + <constraint firstAttribute="height" constant="55" id="nPV-iA-aaw"/> + </constraints> + <buttonCell key="cell" type="bevel" title="Hold" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" id="7w5-d1-mNe"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="toggleHold:" target="-2" id="O18-nN-hHE"/> + </connections> + </button> + <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fmp-x4-Pef"> + <rect key="frame" x="354" y="8" width="80" height="60"/> + <constraints> + <constraint firstAttribute="width" constant="76" id="eC5-B4-omb"/> + <constraint firstAttribute="height" constant="55" id="wYS-TH-4rc"/> + </constraints> + <buttonCell key="cell" type="bevel" title="Chat" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" id="1fJ-X6-Rza"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="toggleChat:" target="-2" id="7HN-HS-oqT"/> + </connections> + </button> + </subviews> <constraints> - <constraint firstAttribute="width" constant="76" id="9Aq-GM-wT2"/> - <constraint firstAttribute="height" constant="55" id="mnN-fs-Rr6"/> + <constraint firstItem="qgD-3D-nD5" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="1lr-kB-A5h"/> + <constraint firstItem="Kjq-iM-NBL" firstAttribute="leading" secondItem="qgD-3D-nD5" secondAttribute="trailing" constant="8" id="3iK-1x-F2q"/> + <constraint firstItem="anb-Y8-JQi" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="4C3-og-43v"/> + <constraint firstAttribute="bottom" secondItem="fmp-x4-Pef" secondAttribute="bottom" constant="11" id="4qt-Sw-3oV"/> + <constraint firstAttribute="bottom" secondItem="Kjq-iM-NBL" secondAttribute="bottom" constant="11" id="IPS-1V-PVm"/> + <constraint firstAttribute="bottom" secondItem="qgD-3D-nD5" secondAttribute="bottom" constant="11" id="KYy-za-dDq"/> + <constraint firstItem="anb-Y8-JQi" firstAttribute="leading" secondItem="Kjq-iM-NBL" secondAttribute="trailing" constant="8" id="Mcj-US-rZq"/> + <constraint firstAttribute="bottom" secondItem="anb-Y8-JQi" secondAttribute="bottom" constant="11" id="MwL-3I-lJv"/> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="385" id="TSJ-9A-brf"/> + <constraint firstItem="fmp-x4-Pef" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="Wmf-0A-jba"/> + <constraint firstItem="Kjq-iM-NBL" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="a1R-g8-5gl"/> + <constraint firstAttribute="bottom" secondItem="oRa-pS-HN2" secondAttribute="bottom" constant="11" id="aOv-xQ-1pk"/> + <constraint firstItem="fmp-x4-Pef" firstAttribute="leading" secondItem="anb-Y8-JQi" secondAttribute="trailing" constant="8" id="bSy-yw-J5C"/> + <constraint firstItem="oRa-pS-HN2" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="faC-l8-iCU"/> + <constraint firstItem="oRa-pS-HN2" firstAttribute="leading" secondItem="Eoi-B8-iL6" secondAttribute="leading" constant="20" id="htl-he-rlg"/> + <constraint firstItem="fmp-x4-Pef" firstAttribute="leading" secondItem="anb-Y8-JQi" secondAttribute="trailing" constant="8" id="jfN-xU-POX"/> + <constraint firstItem="qgD-3D-nD5" firstAttribute="leading" secondItem="oRa-pS-HN2" secondAttribute="trailing" constant="8" id="wQF-FD-dbj"/> </constraints> - <buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="234C9BC9-A500-43C5-873E-78EC0E1D8ED1" imagePosition="overlaps" alignment="left" borderStyle="border" imageScaling="proportionallyDown" id="CoO-HS-nEB"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> - </buttonCell> - <connections> - <action selector="accept:" target="-2" id="maS-G8-eY7"/> - </connections> - </button> - <button horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="anb-Y8-JQi"> - <rect key="frame" x="269" y="7" width="84" height="62"/> + </customView> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="6y6-RH-qOp" userLabel="Preview"> + <rect key="frame" x="480" y="20" width="175" height="120"/> <constraints> - <constraint firstAttribute="width" constant="76" id="QBx-uC-sub"/> - <constraint firstAttribute="height" constant="55" id="nPV-iA-aaw"/> + <constraint firstAttribute="height" constant="120" id="BvU-kV-0uD"/> + <constraint firstAttribute="width" constant="175" id="aEv-Tt-tSD"/> </constraints> - <buttonCell key="cell" type="bevel" title="Hold" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" id="7w5-d1-mNe"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> - </buttonCell> - <connections> - <action selector="toggleHold:" target="-2" id="O18-nN-hHE"/> - </connections> - </button> - <button horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oRa-pS-HN2"> - <rect key="frame" x="18" y="8" width="80" height="60"/> + </customView> + </subviews> + <constraints> + <constraint firstItem="6y6-RH-qOp" firstAttribute="leading" secondItem="Eoi-B8-iL6" secondAttribute="trailing" constant="8" id="7wV-uh-Xb7"/> + <constraint firstAttribute="trailing" secondItem="d0X-cW-Xgz" secondAttribute="trailing" constant="20" id="G79-Jv-EYw"/> + <constraint firstAttribute="bottom" secondItem="6y6-RH-qOp" secondAttribute="bottom" constant="20" id="HOt-7O-FU2"/> + <constraint firstAttribute="trailing" secondItem="6y6-RH-qOp" secondAttribute="trailing" constant="20" id="KTx-SN-RUg"/> + <constraint firstItem="d0X-cW-Xgz" firstAttribute="top" secondItem="2wf-Py-l6B" secondAttribute="top" id="MKB-zm-C75"/> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="675" id="ciq-ed-2FK"/> + <constraint firstItem="d0X-cW-Xgz" firstAttribute="leading" secondItem="2wf-Py-l6B" secondAttribute="leading" constant="20" id="efy-70-qsJ"/> + <constraint firstAttribute="bottom" secondItem="Eoi-B8-iL6" secondAttribute="bottom" constant="20" id="glQ-Is-Pk6"/> + <constraint firstItem="Eoi-B8-iL6" firstAttribute="leading" secondItem="2wf-Py-l6B" secondAttribute="leading" constant="20" id="sHw-xg-QAo"/> + </constraints> + </customView> + <customView id="TdD-3L-553"> + <rect key="frame" x="676" y="0.0" width="338" height="509"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kW2-Cx-fNv"> + <rect key="frame" x="274" y="13" width="50" height="32"/> <constraints> - <constraint firstAttribute="width" constant="76" id="Afw-2T-aY9"/> - <constraint firstAttribute="height" constant="55" id="t21-HC-Wvs"/> + <constraint firstAttribute="width" constant="38" id="0Qx-5g-ThL"/> </constraints> - <buttonCell key="cell" type="bevel" title="Record" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" id="rhz-4Z-avV"> + <buttonCell key="cell" type="push" bezelStyle="rounded" image="NSGoRightTemplate" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="5Nl-aV-9kl"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <font key="font" metaFont="system"/> </buttonCell> <connections> - <action selector="toggleRecording:" target="-2" id="gAc-ZJ-9PN"/> + <action selector="sendMessage:" target="LWe-df-dS6" id="Hlj-og-5rV"/> + <binding destination="LWe-df-dS6" name="enabled" keyPath="self.message.length" id="ec2-s1-Hpt"/> </connections> </button> - </subviews> - <constraints> - <constraint firstItem="qgD-3D-nD5" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="1lr-kB-A5h"/> - <constraint firstItem="anb-Y8-JQi" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="4C3-og-43v"/> - <constraint firstAttribute="bottom" secondItem="Kjq-iM-NBL" secondAttribute="bottom" constant="11" id="IPS-1V-PVm"/> - <constraint firstAttribute="bottom" secondItem="qgD-3D-nD5" secondAttribute="bottom" constant="11" id="KYy-za-dDq"/> - <constraint firstAttribute="bottom" secondItem="anb-Y8-JQi" secondAttribute="bottom" constant="11" id="MwL-3I-lJv"/> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="385" id="TSJ-9A-brf"/> - <constraint firstItem="Kjq-iM-NBL" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="a1R-g8-5gl"/> - <constraint firstAttribute="bottom" secondItem="oRa-pS-HN2" secondAttribute="bottom" constant="11" id="aOv-xQ-1pk"/> - <constraint firstItem="oRa-pS-HN2" firstAttribute="top" secondItem="Eoi-B8-iL6" secondAttribute="top" constant="11" id="faC-l8-iCU"/> - </constraints> - </customView> - <customView ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d0X-cW-Xgz"> - <rect key="frame" x="20" y="422" width="568" height="71"/> - <subviews> - <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bg3-hB-nE8"> - <rect key="frame" x="18" y="40" width="139" height="17"/> - <constraints> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="81" id="gT7-Wu-XtU"/> - </constraints> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Person name" id="osk-LS-0Qg"> + <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OBX-o0-u1k"> + <rect key="frame" x="20" y="20" width="252" height="22"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" bezelStyle="round" id="QW9-Ty-ZEe"> <font key="font" metaFont="system"/> - <color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/> + <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> </textFieldCell> + <connections> + <binding destination="LWe-df-dS6" name="value" keyPath="self.message" id="suS-k6-ypU"> + <dictionary key="options"> + <bool key="NSContinuouslyUpdatesValue" value="YES"/> + </dictionary> + </binding> + <outlet property="delegate" destination="LWe-df-dS6" id="9by-zr-IW0"/> + </connections> </textField> - <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kFD-FB-vig"> - <rect key="frame" x="18" y="20" width="37" height="17"/> - <constraints> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="29" id="pft-oc-ZNh"/> - </constraints> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="State" id="ugy-uK-901"> - <font key="font" metaFont="system"/> - <color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/> - <color key="backgroundColor" name="highlightColor" catalog="System" colorSpace="catalog"/> - </textFieldCell> - </textField> - <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cIU-M7-xpN"> - <rect key="frame" x="446" y="23" width="104" height="24"/> - <constraints> - <constraint firstAttribute="width" constant="100" id="9vz-kb-6L6"/> - </constraints> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Time" id="zsO-T7-9yi"> - <font key="font" size="20" name="HelveticaNeue"/> - <color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/> - <color key="backgroundColor" name="highlightColor" catalog="System" colorSpace="catalog"/> - </textFieldCell> - <userDefinedRuntimeAttributes> - <userDefinedRuntimeAttribute type="string" keyPath="layer.cornerRadius" value="15"/> - </userDefinedRuntimeAttributes> - </textField> + <scrollView borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="i3X-6S-mKF"> + <rect key="frame" x="0.0" y="50" width="338" height="459"/> + <clipView key="contentView" id="Tbz-Bj-Y3K"> + <rect key="frame" x="1" y="1" width="223" height="133"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textView editable="NO" importsGraphics="NO" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dataDetection="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="9jD-8j-lXO"> + <rect key="frame" x="0.0" y="0.0" width="223" height="439"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <size key="minSize" width="338" height="459"/> + <size key="maxSize" width="463" height="10000000"/> + <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <size key="minSize" width="338" height="459"/> + <size key="maxSize" width="463" height="10000000"/> + </textView> + </subviews> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </clipView> + <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="Uo5-G8-d2s"> + <rect key="frame" x="-100" y="-100" width="87" height="18"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="eno-qS-nJm"> + <rect key="frame" x="224" y="1" width="15" height="133"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> </subviews> <constraints> - <constraint firstItem="kFD-FB-vig" firstAttribute="leading" secondItem="bg3-hB-nE8" secondAttribute="leading" id="LXG-QI-oPf"/> - <constraint firstAttribute="trailing" secondItem="cIU-M7-xpN" secondAttribute="trailing" constant="20" id="RXf-xZ-4f9"/> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="568" id="Xeq-Aa-f1W"/> - <constraint firstItem="kFD-FB-vig" firstAttribute="top" secondItem="bg3-hB-nE8" secondAttribute="bottom" constant="3" id="Z06-5v-81Q"/> - <constraint firstItem="kFD-FB-vig" firstAttribute="top" secondItem="bg3-hB-nE8" secondAttribute="bottom" constant="3" id="gRn-E6-o6O"/> - <constraint firstItem="kFD-FB-vig" firstAttribute="leading" secondItem="d0X-cW-Xgz" secondAttribute="leading" constant="20" id="i5C-8o-qKp"/> - <constraint firstAttribute="bottom" secondItem="kFD-FB-vig" secondAttribute="bottom" constant="20" id="l71-7V-oLx"/> - <constraint firstItem="bg3-hB-nE8" firstAttribute="leading" secondItem="d0X-cW-Xgz" secondAttribute="leading" constant="20" id="nV4-Vy-vqK"/> - <constraint firstAttribute="centerY" secondItem="cIU-M7-xpN" secondAttribute="centerY" id="yvc-8B-cEu"/> + <constraint firstItem="kW2-Cx-fNv" firstAttribute="leading" secondItem="OBX-o0-u1k" secondAttribute="trailing" constant="8" id="5sg-0N-YSw"/> + <constraint firstAttribute="bottom" secondItem="kW2-Cx-fNv" secondAttribute="bottom" constant="20" id="EeC-o1-xNE"/> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="250" id="KI6-XT-afu"/> + <constraint firstItem="i3X-6S-mKF" firstAttribute="top" secondItem="TdD-3L-553" secondAttribute="top" id="LoI-gZ-Gp6"/> + <constraint firstItem="i3X-6S-mKF" firstAttribute="leading" secondItem="TdD-3L-553" secondAttribute="leading" id="NVH-57-1Yw"/> + <constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="Szn-hz-Zcv"/> + <constraint firstAttribute="bottom" secondItem="OBX-o0-u1k" secondAttribute="bottom" constant="20" id="eOH-Wv-Zuo"/> + <constraint firstAttribute="trailing" secondItem="kW2-Cx-fNv" secondAttribute="trailing" constant="20" id="g3z-YY-hyn"/> + <constraint firstItem="OBX-o0-u1k" firstAttribute="leading" secondItem="TdD-3L-553" secondAttribute="leading" constant="20" id="wTD-wE-axZ"/> + <constraint firstItem="OBX-o0-u1k" firstAttribute="top" secondItem="i3X-6S-mKF" secondAttribute="bottom" constant="8" id="yKJ-bq-2wk"/> + <constraint firstAttribute="trailing" secondItem="i3X-6S-mKF" secondAttribute="trailing" id="zdl-DO-8e8"/> </constraints> </customView> </subviews> - <constraints> - <constraint firstItem="6y6-RH-qOp" firstAttribute="leading" secondItem="Eoi-B8-iL6" secondAttribute="trailing" constant="8" id="7wV-uh-Xb7"/> - <constraint firstAttribute="trailing" secondItem="d0X-cW-Xgz" secondAttribute="trailing" constant="20" id="G79-Jv-EYw"/> - <constraint firstAttribute="bottom" secondItem="6y6-RH-qOp" secondAttribute="bottom" constant="20" id="HOt-7O-FU2"/> - <constraint firstAttribute="trailing" secondItem="6y6-RH-qOp" secondAttribute="trailing" constant="20" id="KTx-SN-RUg"/> - <constraint firstItem="d0X-cW-Xgz" firstAttribute="top" secondItem="2wf-Py-l6B" secondAttribute="top" id="MKB-zm-C75"/> - <constraint firstItem="d0X-cW-Xgz" firstAttribute="leading" secondItem="2wf-Py-l6B" secondAttribute="leading" constant="20" id="efy-70-qsJ"/> - <constraint firstAttribute="bottom" secondItem="Eoi-B8-iL6" secondAttribute="bottom" constant="20" id="glQ-Is-Pk6"/> - <constraint firstItem="Eoi-B8-iL6" firstAttribute="leading" secondItem="2wf-Py-l6B" secondAttribute="leading" constant="20" id="sHw-xg-QAo"/> - </constraints> - </customView> + <holdingPriorities> + <real value="250"/> + <real value="250"/> + </holdingPriorities> + <connections> + <outlet property="delegate" destination="-2" id="Srr-ek-32R"/> + </connections> + </splitView> </subviews> <constraints> - <constraint firstAttribute="trailing" secondItem="2wf-Py-l6B" secondAttribute="trailing" id="55Z-0g-5TN"/> - <constraint firstItem="2wf-Py-l6B" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="X7p-et-pnn"/> - <constraint firstAttribute="trailing" secondItem="2wf-Py-l6B" secondAttribute="trailing" id="YzN-ww-GnM"/> - <constraint firstAttribute="bottom" secondItem="2wf-Py-l6B" secondAttribute="bottom" id="a7w-Ws-Gv9"/> - <constraint firstItem="2wf-Py-l6B" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="fQz-Y7-SMk"/> - <constraint firstAttribute="bottom" secondItem="2wf-Py-l6B" secondAttribute="bottom" id="iMg-yV-adv"/> - <constraint firstItem="2wf-Py-l6B" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="mf8-S2-fcv"/> + <constraint firstAttribute="trailing" secondItem="GIJ-gB-FZo" secondAttribute="trailing" id="0em-qy-QDF"/> + <constraint firstItem="GIJ-gB-FZo" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="BMA-1U-7qS"/> + <constraint firstAttribute="bottom" secondItem="GIJ-gB-FZo" secondAttribute="bottom" id="cSp-R2-2P7"/> + <constraint firstItem="GIJ-gB-FZo" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="gYP-xn-tdT"/> </constraints> - <point key="canvasLocation" x="1225" y="13.5"/> + <point key="canvasLocation" x="1428" y="21.5"/> </customView> + <viewController id="LWe-df-dS6" customClass="ChatVC"> + <connections> + <outlet property="chatView" destination="9jD-8j-lXO" id="nRK-qZ-xex"/> + <outlet property="messageField" destination="OBX-o0-u1k" id="MS2-Hl-as4"/> + <outlet property="sendButton" destination="kW2-Cx-fNv" id="7iO-d1-LsM"/> + <outlet property="view" destination="TdD-3L-553" id="HQf-B1-D8b"/> + </connections> + </viewController> </objects> <resources> - <image name="234C9BC9-A500-43C5-873E-78EC0E1D8ED1" width="48" height="48"> + <image name="365E0BA1-E8E9-417C-9637-69685AEF3D44" width="48" height="48"> <mutableData key="keyedArchiveRepresentation"> YnBsaXN0MDDUAQIDBAUGOzxYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK0HCBEW GxwgISksLzU4VSRudWxs1AkKCwwNDg8QViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05TQ29sb3KA @@ -409,7 +530,7 @@ MlkyYDJoMnUyejJ8Mn4ygzKLMo4ykzKbMp4ysDKzMrgAAAAAAAACAQAAAAAAAAA/AAAAAAAAAAAAAAAA AAAyug </mutableData> </image> - <image name="64F5804D-D61F-4A20-A8D3-6F9E71A72A27" width="48" height="48"> + <image name="536D2CB3-F984-4261-A185-5FD010473380" width="48" height="48"> <mutableData key="keyedArchiveRepresentation"> YnBsaXN0MDDUAQIDBAUGOzxYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK0HCBEW GxwgISksLzU4VSRudWxs1AkKCwwNDg8QViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05TQ29sb3KA @@ -633,5 +754,6 @@ MlkyYDJoMnUyejJ8Mn4ygzKLMo4ykzKbMp4ysDKzMrgAAAAAAAACAQAAAAAAAAA/AAAAAAAAAAAAAAAA AAAyug </mutableData> </image> + <image name="NSGoRightTemplate" width="9" height="12"/> </resources> </document> diff --git a/ui/RingWindow.xib b/ui/RingWindow.xib index fdd2c01c0a0b585c86aae74b00cc949438a9bd04..af920b8f9f71036061d1375714d40559eb3c407d 100644 --- a/ui/RingWindow.xib +++ b/ui/RingWindow.xib @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1066" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D2134" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <dependencies> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="RingWindowController"> <connections> + <outlet property="callView" destination="tSW-YT-asL" id="NRy-rM-XW4"/> <outlet property="currentView" destination="se5-gp-TjO" id="Sae-7F-MB3"/> <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/> </connections> @@ -32,7 +33,7 @@ <rect key="frame" x="0.0" y="0.0" width="293" height="19"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> <tableColumns> <tableColumn identifier="ConversationsColumn" width="290" minWidth="40" maxWidth="1000" id="VDO-Cu-h8f"> @@ -92,7 +93,7 @@ <rect key="frame" x="0.0" y="0.0" width="226" height="19"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> <tableColumns> <tableColumn identifier="DayColumn" width="87.5703125" minWidth="40" maxWidth="1000" id="pTT-gU-NVa"> @@ -169,7 +170,7 @@ </tabViewItem> <tabViewItem label="Contacts" identifier="" id="Zbi-X6-DLT"> <view key="view" id="sag-tS-7Jw"> - <rect key="frame" x="10" y="7" width="289" height="405"/> + <rect key="frame" x="10" y="7" width="295" height="405"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView focusRingType="none" misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="48" horizontalPageScroll="10" verticalLineScroll="48" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rJv-ju-DFe"> @@ -182,7 +183,7 @@ <rect key="frame" x="0.0" y="0.0" width="293" height="48"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> <tableColumns> <tableColumn identifier="NameColumn" width="289.7734375" minWidth="40" maxWidth="1000" id="8Ve-L0-o7V"> @@ -229,8 +230,8 @@ </tabViewItem> </tabViewItems> </tabView> - <customView focusRingType="none" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tSW-YT-asL"> - <rect key="frame" x="323" y="0.0" width="725" height="626"/> + <customView focusRingType="none" translatesAutoresizingMaskIntoConstraints="NO" id="tSW-YT-asL"> + <rect key="frame" x="323" y="0.0" width="730" height="626"/> <constraints> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="626" id="5yo-rb-X1O"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="725" id="ccX-uq-zuj"/> @@ -263,8 +264,7 @@ <viewController id="txt-J3-pzW" customClass="ConversationsVC"> <connections> <outlet property="conversationsView" destination="zcl-pp-rGb" id="YXp-WN-UmC"/> - <outlet property="currentCallView" destination="tSW-YT-asL" id="r2r-Q3-clc"/> - <outlet property="view" destination="tSW-YT-asL" id="fv5-ly-rk8"/> + <outlet property="view" destination="bqQ-DB-Z0g" id="nJI-EM-4z2"/> </connections> </viewController> <viewController id="9RF-6W-vEW" customClass="PersonsVC">