blob: fd93250adb1513b9600b513fd27dbf0d620d8b41 [file] [log] [blame]
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00001/*
Donald E Curtisa8736442015-08-05 15:48:13 -07002 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00003 *
Donald E Curtisa8736442015-08-05 15:48:13 -07004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00009 */
10
11#import "ARDMainView.h"
12
13#import "UIImage+ARDUtilities.h"
14
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000015static CGFloat const kRoomTextFieldHeight = 40;
16static CGFloat const kRoomTextFieldMargin = 8;
haysc913e6452015-10-02 11:44:03 -070017static CGFloat const kCallControlMargin = 8;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000018
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000019// Helper view that contains a text field and a clear button.
20@interface ARDRoomTextField : UIView <UITextFieldDelegate>
haysc913e6452015-10-02 11:44:03 -070021@property(nonatomic, readonly) NSString *roomText;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000022@end
23
24@implementation ARDRoomTextField {
25 UITextField *_roomText;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000026}
27
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000028- (instancetype)initWithFrame:(CGRect)frame {
29 if (self = [super initWithFrame:frame]) {
30 _roomText = [[UITextField alloc] initWithFrame:CGRectZero];
31 _roomText.borderStyle = UITextBorderStyleNone;
32 _roomText.font = [UIFont fontWithName:@"Roboto" size:12];
33 _roomText.placeholder = @"Room name";
hayscedd8fef2015-12-08 11:08:39 -080034 _roomText.autocorrectionType = UITextAutocorrectionTypeNo;
35 _roomText.autocapitalizationType = UITextAutocapitalizationTypeNone;
denicijaae708762016-11-02 03:02:29 -070036 _roomText.clearButtonMode = UITextFieldViewModeAlways;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000037 _roomText.delegate = self;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000038 [self addSubview:_roomText];
39
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000040 // Give rounded corners and a light gray border.
41 self.layer.borderWidth = 1;
42 self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
43 self.layer.cornerRadius = 2;
44 }
45 return self;
46}
47
48- (void)layoutSubviews {
denicijaae708762016-11-02 03:02:29 -070049 _roomText.frame =
50 CGRectMake(kRoomTextFieldMargin, 0, CGRectGetWidth(self.bounds) - kRoomTextFieldMargin,
51 kRoomTextFieldHeight);
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000052}
53
54- (CGSize)sizeThatFits:(CGSize)size {
55 size.height = kRoomTextFieldHeight;
56 return size;
57}
58
haysc913e6452015-10-02 11:44:03 -070059- (NSString *)roomText {
60 return _roomText.text;
61}
62
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000063#pragma mark - UITextFieldDelegate
64
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000065- (BOOL)textFieldShouldReturn:(UITextField *)textField {
66 // There is no other control that can take focus, so manually resign focus
67 // when return (Join) is pressed to trigger |textFieldDidEndEditing|.
68 [textField resignFirstResponder];
69 return YES;
70}
71
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000072@end
73
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000074@implementation ARDMainView {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000075 ARDRoomTextField *_roomText;
haysc913e6452015-10-02 11:44:03 -070076 UILabel *_callOptionsLabel;
77 UISwitch *_audioOnlySwitch;
78 UILabel *_audioOnlyLabel;
peah5085b0c2016-08-25 22:15:14 -070079 UISwitch *_aecdumpSwitch;
80 UILabel *_aecdumpLabel;
tkchinab1293a2016-08-30 12:35:05 -070081 UISwitch *_levelControlSwitch;
82 UILabel *_levelControlLabel;
haysc913e6452015-10-02 11:44:03 -070083 UISwitch *_loopbackSwitch;
84 UILabel *_loopbackLabel;
tkchind2511962016-05-06 18:54:15 -070085 UISwitch *_useManualAudioSwitch;
86 UILabel *_useManualAudioLabel;
haysc913e6452015-10-02 11:44:03 -070087 UIButton *_startCallButton;
Zeke Chin615fabb2016-02-24 10:58:52 -080088 UIButton *_audioLoopButton;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000089}
90
91@synthesize delegate = _delegate;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070092@synthesize isAudioLoopPlaying = _isAudioLoopPlaying;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000093
94- (instancetype)initWithFrame:(CGRect)frame {
95 if (self = [super initWithFrame:frame]) {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000096 _roomText = [[ARDRoomTextField alloc] initWithFrame:CGRectZero];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000097 [self addSubview:_roomText];
98
haysc913e6452015-10-02 11:44:03 -070099 UIFont *controlFont = [UIFont fontWithName:@"Roboto" size:20];
100 UIColor *controlFontColor = [UIColor colorWithWhite:0 alpha:.6];
101
102 _callOptionsLabel = [[UILabel alloc] initWithFrame:CGRectZero];
103 _callOptionsLabel.text = @"Call Options";
104 _callOptionsLabel.font = controlFont;
105 _callOptionsLabel.textColor = controlFontColor;
106 [_callOptionsLabel sizeToFit];
107 [self addSubview:_callOptionsLabel];
108
109 _audioOnlySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
110 [_audioOnlySwitch sizeToFit];
111 [self addSubview:_audioOnlySwitch];
112
113 _audioOnlyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
114 _audioOnlyLabel.text = @"Audio only";
115 _audioOnlyLabel.font = controlFont;
116 _audioOnlyLabel.textColor = controlFontColor;
117 [_audioOnlyLabel sizeToFit];
118 [self addSubview:_audioOnlyLabel];
119
120 _loopbackSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
121 [_loopbackSwitch sizeToFit];
122 [self addSubview:_loopbackSwitch];
123
124 _loopbackLabel = [[UILabel alloc] initWithFrame:CGRectZero];
125 _loopbackLabel.text = @"Loopback mode";
126 _loopbackLabel.font = controlFont;
127 _loopbackLabel.textColor = controlFontColor;
128 [_loopbackLabel sizeToFit];
129 [self addSubview:_loopbackLabel];
130
peah5085b0c2016-08-25 22:15:14 -0700131 _aecdumpSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
132 [_aecdumpSwitch sizeToFit];
133 [self addSubview:_aecdumpSwitch];
134
135 _aecdumpLabel = [[UILabel alloc] initWithFrame:CGRectZero];
136 _aecdumpLabel.text = @"Create AecDump";
137 _aecdumpLabel.font = controlFont;
138 _aecdumpLabel.textColor = controlFontColor;
139 [_aecdumpLabel sizeToFit];
140 [self addSubview:_aecdumpLabel];
141
tkchinab1293a2016-08-30 12:35:05 -0700142 _levelControlSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
143 [_levelControlSwitch sizeToFit];
144 [self addSubview:_levelControlSwitch];
145
146 _levelControlLabel = [[UILabel alloc] initWithFrame:CGRectZero];
147 _levelControlLabel.text = @"Use level controller";
148 _levelControlLabel.font = controlFont;
149 _levelControlLabel.textColor = controlFontColor;
150 [_levelControlLabel sizeToFit];
151 [self addSubview:_levelControlLabel];
152
tkchind2511962016-05-06 18:54:15 -0700153 _useManualAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
154 [_useManualAudioSwitch sizeToFit];
155 _useManualAudioSwitch.on = YES;
156 [self addSubview:_useManualAudioSwitch];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700157
tkchind2511962016-05-06 18:54:15 -0700158 _useManualAudioLabel = [[UILabel alloc] initWithFrame:CGRectZero];
159 _useManualAudioLabel.text = @"Use manual audio config";
160 _useManualAudioLabel.font = controlFont;
161 _useManualAudioLabel.textColor = controlFontColor;
162 [_useManualAudioLabel sizeToFit];
163 [self addSubview:_useManualAudioLabel];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700164
haysc913e6452015-10-02 11:44:03 -0700165 _startCallButton = [UIButton buttonWithType:UIButtonTypeSystem];
haysc913e6452015-10-02 11:44:03 -0700166 [_startCallButton setTitle:@"Start call"
167 forState:UIControlStateNormal];
168 _startCallButton.titleLabel.font = controlFont;
haysc913e6452015-10-02 11:44:03 -0700169 [_startCallButton sizeToFit];
170 [_startCallButton addTarget:self
171 action:@selector(onStartCall:)
172 forControlEvents:UIControlEventTouchUpInside];
173 [self addSubview:_startCallButton];
174
Zeke Chin615fabb2016-02-24 10:58:52 -0800175 // Used to test what happens to sounds when calls are in progress.
176 _audioLoopButton = [UIButton buttonWithType:UIButtonTypeSystem];
Zeke Chin615fabb2016-02-24 10:58:52 -0800177 _audioLoopButton.titleLabel.font = controlFont;
Zeke Chin615fabb2016-02-24 10:58:52 -0800178 [self updateAudioLoopButton];
179 [_audioLoopButton addTarget:self
180 action:@selector(onToggleAudioLoop:)
181 forControlEvents:UIControlEventTouchUpInside];
182 [self addSubview:_audioLoopButton];
183
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000184 self.backgroundColor = [UIColor whiteColor];
185 }
186 return self;
187}
188
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700189- (void)setIsAudioLoopPlaying:(BOOL)isAudioLoopPlaying {
190 if (_isAudioLoopPlaying == isAudioLoopPlaying) {
191 return;
192 }
193 _isAudioLoopPlaying = isAudioLoopPlaying;
194 [self updateAudioLoopButton];
195}
196
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000197- (void)layoutSubviews {
198 CGRect bounds = self.bounds;
199 CGFloat roomTextWidth = bounds.size.width - 2 * kRoomTextFieldMargin;
200 CGFloat roomTextHeight = [_roomText sizeThatFits:bounds.size].height;
denicija6d6762c2016-10-28 04:53:16 -0700201 _roomText.frame =
202 CGRectMake(kRoomTextFieldMargin, kRoomTextFieldMargin, roomTextWidth, roomTextHeight);
haysc913e6452015-10-02 11:44:03 -0700203
204 CGFloat callOptionsLabelTop =
205 CGRectGetMaxY(_roomText.frame) + kCallControlMargin * 4;
206 _callOptionsLabel.frame = CGRectMake(kCallControlMargin,
207 callOptionsLabelTop,
208 _callOptionsLabel.frame.size.width,
209 _callOptionsLabel.frame.size.height);
210
211 CGFloat audioOnlyTop =
212 CGRectGetMaxY(_callOptionsLabel.frame) + kCallControlMargin * 2;
213 CGRect audioOnlyRect = CGRectMake(kCallControlMargin * 3,
214 audioOnlyTop,
215 _audioOnlySwitch.frame.size.width,
216 _audioOnlySwitch.frame.size.height);
217 _audioOnlySwitch.frame = audioOnlyRect;
218 CGFloat audioOnlyLabelCenterX = CGRectGetMaxX(audioOnlyRect) +
219 kCallControlMargin + _audioOnlyLabel.frame.size.width / 2;
220 _audioOnlyLabel.center = CGPointMake(audioOnlyLabelCenterX,
221 CGRectGetMidY(audioOnlyRect));
222
223 CGFloat loopbackModeTop =
224 CGRectGetMaxY(_audioOnlySwitch.frame) + kCallControlMargin;
225 CGRect loopbackModeRect = CGRectMake(kCallControlMargin * 3,
226 loopbackModeTop,
227 _loopbackSwitch.frame.size.width,
228 _loopbackSwitch.frame.size.height);
229 _loopbackSwitch.frame = loopbackModeRect;
230 CGFloat loopbackModeLabelCenterX = CGRectGetMaxX(loopbackModeRect) +
231 kCallControlMargin + _loopbackLabel.frame.size.width / 2;
232 _loopbackLabel.center = CGPointMake(loopbackModeLabelCenterX,
233 CGRectGetMidY(loopbackModeRect));
234
peah5085b0c2016-08-25 22:15:14 -0700235 CGFloat aecdumpModeTop =
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700236 CGRectGetMaxY(_loopbackSwitch.frame) + kCallControlMargin;
peah5085b0c2016-08-25 22:15:14 -0700237 CGRect aecdumpModeRect = CGRectMake(kCallControlMargin * 3,
238 aecdumpModeTop,
239 _aecdumpSwitch.frame.size.width,
240 _aecdumpSwitch.frame.size.height);
241 _aecdumpSwitch.frame = aecdumpModeRect;
242 CGFloat aecdumpModeLabelCenterX = CGRectGetMaxX(aecdumpModeRect) +
243 kCallControlMargin + _aecdumpLabel.frame.size.width / 2;
244 _aecdumpLabel.center = CGPointMake(aecdumpModeLabelCenterX,
245 CGRectGetMidY(aecdumpModeRect));
246
tkchinab1293a2016-08-30 12:35:05 -0700247 CGFloat levelControlModeTop =
248 CGRectGetMaxY(_aecdumpSwitch.frame) + kCallControlMargin;
249 CGRect levelControlModeRect = CGRectMake(kCallControlMargin * 3,
250 levelControlModeTop,
251 _levelControlSwitch.frame.size.width,
252 _levelControlSwitch.frame.size.height);
253 _levelControlSwitch.frame = levelControlModeRect;
254 CGFloat levelControlModeLabelCenterX = CGRectGetMaxX(levelControlModeRect) +
255 kCallControlMargin + _levelControlLabel.frame.size.width / 2;
256 _levelControlLabel.center = CGPointMake(levelControlModeLabelCenterX,
257 CGRectGetMidY(levelControlModeRect));
peah5085b0c2016-08-25 22:15:14 -0700258
259 CGFloat useManualAudioTop =
tkchinab1293a2016-08-30 12:35:05 -0700260 CGRectGetMaxY(_levelControlSwitch.frame) + kCallControlMargin;
tkchind2511962016-05-06 18:54:15 -0700261 CGRect useManualAudioRect =
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700262 CGRectMake(kCallControlMargin * 3,
tkchind2511962016-05-06 18:54:15 -0700263 useManualAudioTop,
264 _useManualAudioSwitch.frame.size.width,
265 _useManualAudioSwitch.frame.size.height);
266 _useManualAudioSwitch.frame = useManualAudioRect;
267 CGFloat useManualAudioLabelCenterX = CGRectGetMaxX(useManualAudioRect) +
268 kCallControlMargin + _useManualAudioLabel.frame.size.width / 2;
269 _useManualAudioLabel.center =
270 CGPointMake(useManualAudioLabelCenterX,
271 CGRectGetMidY(useManualAudioRect));
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700272
Zeke Chin615fabb2016-02-24 10:58:52 -0800273 CGFloat audioLoopTop =
tkchind2511962016-05-06 18:54:15 -0700274 CGRectGetMaxY(useManualAudioRect) + kCallControlMargin * 3;
Zeke Chin615fabb2016-02-24 10:58:52 -0800275 _audioLoopButton.frame = CGRectMake(kCallControlMargin,
276 audioLoopTop,
277 _audioLoopButton.frame.size.width,
278 _audioLoopButton.frame.size.height);
279
280 CGFloat startCallTop =
281 CGRectGetMaxY(_audioLoopButton.frame) + kCallControlMargin * 3;
haysc913e6452015-10-02 11:44:03 -0700282 _startCallButton.frame = CGRectMake(kCallControlMargin,
283 startCallTop,
284 _startCallButton.frame.size.width,
285 _startCallButton.frame.size.height);
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000286}
287
haysc913e6452015-10-02 11:44:03 -0700288#pragma mark - Private
289
Zeke Chin615fabb2016-02-24 10:58:52 -0800290- (void)updateAudioLoopButton {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700291 if (_isAudioLoopPlaying) {
Zeke Chin615fabb2016-02-24 10:58:52 -0800292 [_audioLoopButton setTitle:@"Stop sound"
293 forState:UIControlStateNormal];
294 [_audioLoopButton sizeToFit];
295 } else {
Zeke Chin615fabb2016-02-24 10:58:52 -0800296 [_audioLoopButton setTitle:@"Play sound"
297 forState:UIControlStateNormal];
298 [_audioLoopButton sizeToFit];
299 }
300}
301
302- (void)onToggleAudioLoop:(id)sender {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700303 [_delegate mainViewDidToggleAudioLoop:self];
Zeke Chin615fabb2016-02-24 10:58:52 -0800304}
305
haysc913e6452015-10-02 11:44:03 -0700306- (void)onStartCall:(id)sender {
307 NSString *room = _roomText.roomText;
308 // If this is a loopback call, allow a generated room name.
309 if (!room.length && _loopbackSwitch.isOn) {
310 room = [[NSUUID UUID] UUIDString];
311 }
312 room = [room stringByReplacingOccurrencesOfString:@"-" withString:@""];
313 [_delegate mainView:self
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700314 didInputRoom:room
315 isLoopback:_loopbackSwitch.isOn
316 isAudioOnly:_audioOnlySwitch.isOn
peah5085b0c2016-08-25 22:15:14 -0700317 shouldMakeAecDump:_aecdumpSwitch.isOn
tkchinab1293a2016-08-30 12:35:05 -0700318 shouldUseLevelControl:_levelControlSwitch.isOn
tkchind2511962016-05-06 18:54:15 -0700319 useManualAudio:_useManualAudioSwitch.isOn];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000320}
321
322@end