Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20561ae64f | ||
|
|
600e71223c | ||
|
|
c05949c43b | ||
|
|
e913d26ca6 | ||
|
|
427e8f67fc | ||
|
|
79e51defe1 | ||
|
|
5f800b7901 | ||
|
|
c3b44a32d5 | ||
|
|
539e120167 | ||
|
|
a924d63750 | ||
|
|
1affb03b89 | ||
|
|
dae484445b | ||
|
|
99d3ac45c3 | ||
|
|
33d6306359 | ||
|
|
5ee9e285e7 | ||
|
|
1be97e1c8a | ||
|
|
8d360d2266 | ||
|
|
2a49f8901f | ||
|
|
d8020a367f | ||
|
|
88c917c103 | ||
|
|
77b6d304f7 | ||
|
|
412c5c2516 | ||
|
|
6fbc55f193 |
@@ -1 +1,2 @@
|
||||
**/xcuserdata/
|
||||
Build
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
FB290DB719B2C870004C83CF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DB619B2C870004C83CF /* libz.dylib */; };
|
||||
FB290DB919B2C877004C83CF /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DB819B2C877004C83CF /* libbz2.dylib */; };
|
||||
FB290DC419B2E98F004C83CF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DC319B2E98F004C83CF /* libxml2.dylib */; };
|
||||
FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */; };
|
||||
FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */; };
|
||||
FB290E7919B37D81004C83CF /* iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* iPad.storyboard */; };
|
||||
FB290E7B19B38036004C83CF /* iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* iPhone.storyboard */; };
|
||||
FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; };
|
||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89460619F646E200339C8A /* CryptoManager.m */; };
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */ = {isa = PBXBuildFile; fileRef = FB89460719F646E200339C8A /* mkcert.c */; };
|
||||
@@ -47,6 +47,15 @@
|
||||
FB8946EB19F6AFE100339C8A /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E019F6AFB800339C8A /* libcrypto.a */; };
|
||||
FB8946EC19F6AFE400339C8A /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946E119F6AFB800339C8A /* libssl.a */; };
|
||||
FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB8946EA19F6AFB800339C8A /* libopus.a */; };
|
||||
FBD3494319FC9C04002D2A60 /* AppManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494219FC9C04002D2A60 /* AppManager.m */; };
|
||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494F19FF2174002D2A60 /* SettingsViewController.m */; };
|
||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */; };
|
||||
FBD3495B1A004411002D2A60 /* Host.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495A1A004411002D2A60 /* Host.m */; };
|
||||
FBD3495E1A004412002D2A60 /* Settings.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495D1A004412002D2A60 /* Settings.m */; };
|
||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD349611A0089F6002D2A60 /* DataManager.m */; };
|
||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86DF19F7A837001C18A8 /* UIComputerView.m */; };
|
||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
||||
FBDE86E919F82315001C18A8 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E819F82315001C18A8 /* App.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -95,8 +104,8 @@
|
||||
FB290DB619B2C870004C83CF /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||
FB290DB819B2C877004C83CF /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; };
|
||||
FB290DC319B2E98F004C83CF /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
|
||||
FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPad.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPhone.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
FB290E7819B37D81004C83CF /* iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = iPad.storyboard; sourceTree = SOURCE_ROOT; };
|
||||
FB290E7A19B38036004C83CF /* iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = iPhone.storyboard; sourceTree = SOURCE_ROOT; };
|
||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
||||
FB89460519F646E200339C8A /* CryptoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoManager.h; sourceTree = "<group>"; };
|
||||
FB89460619F646E200339C8A /* CryptoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoManager.m; sourceTree = "<group>"; };
|
||||
@@ -211,6 +220,25 @@
|
||||
FB8946E719F6AFB800339C8A /* opus_multistream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_multistream.h; sourceTree = "<group>"; };
|
||||
FB8946E819F6AFB800339C8A /* opus_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_types.h; sourceTree = "<group>"; };
|
||||
FB8946EA19F6AFB800339C8A /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libopus.a; sourceTree = "<group>"; };
|
||||
FBD3494119FC9C04002D2A60 /* AppManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppManager.h; sourceTree = "<group>"; };
|
||||
FBD3494219FC9C04002D2A60 /* AppManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppManager.m; sourceTree = "<group>"; };
|
||||
FBD3494E19FF2174002D2A60 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = "<group>"; };
|
||||
FBD3494F19FF2174002D2A60 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = "<group>"; };
|
||||
FBD3495119FF36FB002D2A60 /* SWRevealViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWRevealViewController.h; sourceTree = "<group>"; };
|
||||
FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.m; sourceTree = "<group>"; };
|
||||
FBD349571A003F05002D2A60 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
|
||||
FBD349591A004411002D2A60 /* Host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Host.h; path = Database/Host.h; sourceTree = "<group>"; };
|
||||
FBD3495A1A004411002D2A60 /* Host.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Host.m; path = Database/Host.m; sourceTree = "<group>"; };
|
||||
FBD3495C1A004412002D2A60 /* Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Settings.h; path = Database/Settings.h; sourceTree = "<group>"; };
|
||||
FBD3495D1A004412002D2A60 /* Settings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Settings.m; path = Database/Settings.m; sourceTree = "<group>"; };
|
||||
FBD349601A0089F6002D2A60 /* DataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataManager.h; path = Database/DataManager.h; sourceTree = "<group>"; };
|
||||
FBD349611A0089F6002D2A60 /* DataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DataManager.m; path = Database/DataManager.m; sourceTree = "<group>"; };
|
||||
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIComputerView.h; sourceTree = "<group>"; };
|
||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIComputerView.m; sourceTree = "<group>"; };
|
||||
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
||||
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
||||
FBDE86E719F82315001C18A8 /* App.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = App.h; path = ../App.h; sourceTree = "<group>"; };
|
||||
FBDE86E819F82315001C18A8 /* App.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = App.m; path = ../App.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -277,6 +305,7 @@
|
||||
FB290CF019B2C406004C83CF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD349571A003F05002D2A60 /* libsqlite3.dylib */,
|
||||
FB89468F19F6AFB800339C8A /* libs */,
|
||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */,
|
||||
FB290DC319B2E98F004C83CF /* libxml2.dylib */,
|
||||
@@ -299,14 +328,19 @@
|
||||
FB89461519F646E200339C8A /* Stream */,
|
||||
FB89461E19F646E200339C8A /* Utility */,
|
||||
FB89462319F646E200339C8A /* ViewControllers */,
|
||||
FBD3495F1A004453002D2A60 /* Database */,
|
||||
FB290CFA19B2C406004C83CF /* Supporting Files */,
|
||||
FB290D0219B2C406004C83CF /* AppDelegate.h */,
|
||||
FB290D0319B2C406004C83CF /* AppDelegate.m */,
|
||||
FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */,
|
||||
FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */,
|
||||
FB290E7819B37D81004C83CF /* iPad.storyboard */,
|
||||
FB290E7A19B38036004C83CF /* iPhone.storyboard */,
|
||||
FB89463719F6473800339C8A /* Launch Screen.xib */,
|
||||
FB290D0819B2C406004C83CF /* Images.xcassets */,
|
||||
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */,
|
||||
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */,
|
||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */,
|
||||
FBDE86E419F82297001C18A8 /* UIAppView.h */,
|
||||
FBDE86E519F82297001C18A8 /* UIAppView.m */,
|
||||
);
|
||||
path = Limelight;
|
||||
sourceTree = "<group>";
|
||||
@@ -371,6 +405,8 @@
|
||||
FB89461219F646E200339C8A /* MDNSManager.m */,
|
||||
FB89461319F646E200339C8A /* PairManager.h */,
|
||||
FB89461419F646E200339C8A /* PairManager.m */,
|
||||
FBD3494119FC9C04002D2A60 /* AppManager.h */,
|
||||
FBD3494219FC9C04002D2A60 /* AppManager.m */,
|
||||
);
|
||||
path = Network;
|
||||
sourceTree = "<group>";
|
||||
@@ -395,6 +431,8 @@
|
||||
children = (
|
||||
FB89461F19F646E200339C8A /* Computer.h */,
|
||||
FB89462019F646E200339C8A /* Computer.m */,
|
||||
FBDE86E719F82315001C18A8 /* App.h */,
|
||||
FBDE86E819F82315001C18A8 /* App.m */,
|
||||
FB89462119F646E200339C8A /* Utils.h */,
|
||||
FB89462219F646E200339C8A /* Utils.m */,
|
||||
);
|
||||
@@ -404,10 +442,14 @@
|
||||
FB89462319F646E200339C8A /* ViewControllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD3495119FF36FB002D2A60 /* SWRevealViewController.h */,
|
||||
FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */,
|
||||
FB89462419F646E200339C8A /* MainFrameViewController.h */,
|
||||
FB89462519F646E200339C8A /* MainFrameViewController.m */,
|
||||
FB89462619F646E200339C8A /* StreamFrameViewController.h */,
|
||||
FB89462719F646E200339C8A /* StreamFrameViewController.m */,
|
||||
FBD3494E19FF2174002D2A60 /* SettingsViewController.h */,
|
||||
FBD3494F19FF2174002D2A60 /* SettingsViewController.m */,
|
||||
);
|
||||
path = ViewControllers;
|
||||
sourceTree = "<group>";
|
||||
@@ -573,6 +615,19 @@
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD3495F1A004453002D2A60 /* Database */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD3495C1A004412002D2A60 /* Settings.h */,
|
||||
FBD3495D1A004412002D2A60 /* Settings.m */,
|
||||
FBD349591A004411002D2A60 /* Host.h */,
|
||||
FBD3495A1A004411002D2A60 /* Host.m */,
|
||||
FBD349601A0089F6002D2A60 /* DataManager.h */,
|
||||
FBD349611A0089F6002D2A60 /* DataManager.m */,
|
||||
);
|
||||
name = Database;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -668,9 +723,9 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */,
|
||||
FB290E7919B37D81004C83CF /* iPad.storyboard in Resources */,
|
||||
FB290CFE19B2C406004C83CF /* InfoPlist.strings in Resources */,
|
||||
FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */,
|
||||
FB290E7B19B38036004C83CF /* iPhone.storyboard in Resources */,
|
||||
FB290D0919B2C406004C83CF /* Images.xcassets in Resources */,
|
||||
FB89463819F6473800339C8A /* Launch Screen.xib in Resources */,
|
||||
);
|
||||
@@ -693,21 +748,30 @@
|
||||
files = (
|
||||
FB290D0719B2C406004C83CF /* Limelight.xcdatamodeld in Sources */,
|
||||
FB89463219F646E200339C8A /* VideoDecoderRenderer.m in Sources */,
|
||||
FBD3495E1A004412002D2A60 /* Settings.m in Sources */,
|
||||
FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */,
|
||||
FB89463419F646E200339C8A /* Utils.m in Sources */,
|
||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */,
|
||||
FB89463319F646E200339C8A /* Computer.m in Sources */,
|
||||
FB89462F19F646E200339C8A /* Connection.m in Sources */,
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
|
||||
FBDE86E919F82315001C18A8 /* App.m in Sources */,
|
||||
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
|
||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
||||
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
||||
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
||||
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
||||
FBD3495B1A004411002D2A60 /* Host.m in Sources */,
|
||||
FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */,
|
||||
FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */,
|
||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
||||
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
||||
FB290D0019B2C406004C83CF /* main.m in Sources */,
|
||||
FBD3494319FC9C04002D2A60 /* AppManager.m in Sources */,
|
||||
FB89462A19F646E200339C8A /* ControllerSupport.m in Sources */,
|
||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */,
|
||||
FB89463119F646E200339C8A /* StreamManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// App.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface App : NSObject
|
||||
|
||||
@property NSString* appId;
|
||||
@property NSString* appName;
|
||||
@property UIImage* appImage;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// App.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "App.h"
|
||||
#import "HttpManager.h"
|
||||
|
||||
@implementation App
|
||||
@synthesize appId, appName, appImage;
|
||||
|
||||
@end
|
||||
@@ -18,5 +18,6 @@
|
||||
|
||||
- (void)saveContext;
|
||||
- (NSURL *)applicationDocumentsDirectory;
|
||||
- (NSURL*) getStoreURL;
|
||||
|
||||
@end
|
||||
|
||||
@@ -100,7 +100,7 @@ static NSOperationQueue* mainQueue;
|
||||
return _persistentStoreCoordinator;
|
||||
}
|
||||
|
||||
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Limelight_iOS.sqlite"];
|
||||
NSURL *storeURL = [self getStoreURL];
|
||||
|
||||
NSError *error = nil;
|
||||
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
|
||||
@@ -143,4 +143,8 @@ static NSOperationQueue* mainQueue;
|
||||
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
}
|
||||
|
||||
- (NSURL*) getStoreURL {
|
||||
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Limelight_iOS.sqlite"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// DataManager.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Settings.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "Host.h"
|
||||
|
||||
@interface DataManager : NSObject
|
||||
|
||||
@property (strong, nonatomic) AppDelegate* appDelegate;
|
||||
|
||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width;
|
||||
- (Settings*) retrieveSettings;
|
||||
- (NSArray*) retrieveHosts;
|
||||
- (void) saveHosts;
|
||||
- (Host*) createHost:(NSString*)name hostname:(NSString*)address;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// DataManager.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DataManager.h"
|
||||
|
||||
@implementation DataManager
|
||||
static NSInteger DEFAULT_BITRATE = 10000;
|
||||
static NSInteger DEFAULT_FRAMERATE = 60;
|
||||
static NSInteger DEFAULT_HEIGHT = 720;
|
||||
static NSInteger DEFAULT_WIDTH = 1280;
|
||||
|
||||
- (id) init {
|
||||
self = [super init];
|
||||
self.appDelegate = [[UIApplication sharedApplication] delegate];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width {
|
||||
Settings* settingsToSave = [self retrieveSettings];
|
||||
settingsToSave.framerate = [NSNumber numberWithInteger:framerate];
|
||||
settingsToSave.bitrate = [NSNumber numberWithInteger:bitrate];
|
||||
settingsToSave.height = [NSNumber numberWithInteger:height];
|
||||
settingsToSave.width = [NSNumber numberWithInteger:width];
|
||||
NSError* error;
|
||||
if (![[self.appDelegate managedObjectContext] save:&error]) {
|
||||
NSLog(@"ERROR: Unable to save settings to database");
|
||||
}
|
||||
[self.appDelegate saveContext];
|
||||
}
|
||||
|
||||
- (Settings*) retrieveSettings {
|
||||
NSArray* fetchedRecords = [self fetchRecords:@"Settings"];
|
||||
if (fetchedRecords.count == 0) {
|
||||
// create a new settings object with the default values
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Settings" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
Settings* settings = [[Settings alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
|
||||
settings.framerate = [NSNumber numberWithInteger:DEFAULT_FRAMERATE];
|
||||
settings.bitrate = [NSNumber numberWithInteger:DEFAULT_BITRATE];
|
||||
settings.height = [NSNumber numberWithInteger:DEFAULT_HEIGHT];
|
||||
settings.width = [NSNumber numberWithInteger:DEFAULT_WIDTH];
|
||||
return settings;
|
||||
} else {
|
||||
// we should only ever have 1 settings object stored
|
||||
return [fetchedRecords objectAtIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
- (Host*) createHost:(NSString*)name hostname:(NSString*)address {
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Host" inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
Host* host = [[Host alloc] initWithEntity:entity insertIntoManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
|
||||
host.name = name;
|
||||
host.address = address;
|
||||
return host;
|
||||
}
|
||||
|
||||
- (void) saveHosts {
|
||||
NSError* error;
|
||||
if (![[self.appDelegate managedObjectContext] save:&error]) {
|
||||
NSLog(@"ERROR: Unable to save hosts to database");
|
||||
}
|
||||
[self.appDelegate saveContext];
|
||||
}
|
||||
|
||||
- (NSArray*) retrieveHosts {
|
||||
return [self fetchRecords:@"Host"];
|
||||
}
|
||||
|
||||
- (NSArray*) fetchRecords:(NSString*)entityName {
|
||||
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
|
||||
NSEntityDescription* entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self.appDelegate managedObjectContext]];
|
||||
[fetchRequest setEntity:entity];
|
||||
[fetchRequest setAffectedStores:[NSArray arrayWithObjects:[[self.appDelegate persistentStoreCoordinator] persistentStoreForURL:[self.appDelegate getStoreURL]], nil]];
|
||||
|
||||
NSError* error;
|
||||
NSArray* fetchedRecords = [[self.appDelegate managedObjectContext] executeFetchRequest:fetchRequest error:&error];
|
||||
//TODO: handle errors
|
||||
|
||||
return fetchedRecords;
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Host.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
|
||||
@interface Host : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSString * address;
|
||||
@property (nonatomic, retain) NSString * name;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Host.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Host.h"
|
||||
|
||||
|
||||
@implementation Host
|
||||
|
||||
@dynamic address;
|
||||
@dynamic name;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Settings.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
|
||||
@interface Settings : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSNumber * bitrate;
|
||||
@property (nonatomic, retain) NSNumber * framerate;
|
||||
@property (nonatomic, retain) NSNumber * height;
|
||||
@property (nonatomic, retain) NSNumber * width;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Settings.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/28/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Settings.h"
|
||||
|
||||
|
||||
@implementation Settings
|
||||
|
||||
@dynamic bitrate;
|
||||
@dynamic framerate;
|
||||
@dynamic height;
|
||||
@dynamic width;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "limelight_computer_add_icon_1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "limelight_computer_add_icon_2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "limelight_computer_add_icon_3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "limelight_computer_1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "limelight_computer_2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "limelight_computer_3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "limelight_no_app_image_1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "limelight_no_app_image_2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "limelight_no_app_image_3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "settings_1x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "settings_2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "settings_3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
@@ -19,36 +19,64 @@
|
||||
touchLocation = [touch locationInView:self];
|
||||
touchMoved = false;
|
||||
|
||||
printf("Touch down\n");
|
||||
NSLog(@"Touch down");
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
UITouch *touch = [[event allTouches] anyObject];
|
||||
CGPoint currentLocation = [touch locationInView:self];
|
||||
|
||||
if (touchLocation.x != currentLocation.x ||
|
||||
touchLocation.y != currentLocation.y)
|
||||
{
|
||||
LiSendMouseMoveEvent(currentLocation.x - touchLocation.x,
|
||||
currentLocation.y - touchLocation.y );
|
||||
if ([[event allTouches] count] == 1) {
|
||||
UITouch *touch = [[event allTouches] anyObject];
|
||||
CGPoint currentLocation = [touch locationInView:self];
|
||||
|
||||
if (touchLocation.x != currentLocation.x ||
|
||||
touchLocation.y != currentLocation.y)
|
||||
{
|
||||
LiSendMouseMoveEvent(currentLocation.x - touchLocation.x,
|
||||
currentLocation.y - touchLocation.y );
|
||||
|
||||
touchMoved = true;
|
||||
touchLocation = currentLocation;
|
||||
}
|
||||
} else if ([[event allTouches] count] == 2) {
|
||||
CGPoint firstLocation = [[[[event allTouches] allObjects] objectAtIndex:0] locationInView:self];
|
||||
CGPoint secondLocation = [[[[event allTouches] allObjects] objectAtIndex:1] locationInView:self];
|
||||
|
||||
CGPoint avgLocation = CGPointMake((firstLocation.x + secondLocation.x) / 2, (firstLocation.y + secondLocation.y) / 2);
|
||||
if (touchLocation.y != avgLocation.y) {
|
||||
LiSendScrollEvent(avgLocation.y - touchLocation.y);
|
||||
}
|
||||
touchMoved = true;
|
||||
touchLocation = currentLocation;
|
||||
touchLocation = avgLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
printf("Touch up\n");
|
||||
NSLog(@"Touch up");
|
||||
|
||||
|
||||
if (!touchMoved) {
|
||||
printf("Sending left mouse button press\n");
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
|
||||
// Wait 100 ms to simulate a real button press
|
||||
usleep(100 * 1000);
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
if ([[event allTouches] count] == 2) {
|
||||
NSLog(@"Sending right mouse button press");
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||
|
||||
// Wait 100 ms to simulate a real button press
|
||||
usleep(100 * 1000);
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||
|
||||
|
||||
} else {
|
||||
NSLog(@"Sending left mouse button press");
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||
|
||||
// Wait 100 ms to simulate a real button press
|
||||
usleep(100 * 1000);
|
||||
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.0</string>
|
||||
<string>0.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>7</string>
|
||||
<string>2</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
@@ -29,9 +29,9 @@
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>Launch Screen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>MainFrame-iPhone</string>
|
||||
<string>iPhone</string>
|
||||
<key>UIMainStoryboardFile~ipad</key>
|
||||
<string>MainFrame-iPad</string>
|
||||
<string>iPad</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
@@ -44,8 +44,6 @@
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model name="Test1.xcdatamodel" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
|
||||
<elements/>
|
||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6252" systemVersion="14C68k" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
|
||||
<entity name="Host" representedClassName="Host" syncable="YES">
|
||||
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="Settings" representedClassName="Settings" syncable="YES">
|
||||
<attribute name="bitrate" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="framerate" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="height" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="width" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Host" positionX="0" positionY="0" width="0" height="0"/>
|
||||
<element name="Settings" positionX="0" positionY="0" width="0" height="0"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// AppManager.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/25/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "App.h"
|
||||
#import "HttpManager.h"
|
||||
|
||||
@protocol AppAssetCallback <NSObject>
|
||||
|
||||
- (void) receivedAssetForApp:(App*)app;
|
||||
|
||||
@end
|
||||
|
||||
@interface AppManager : NSObject
|
||||
|
||||
+ (void) retrieveAppAssets:(NSArray*)apps withManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// AppManager.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/25/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppManager.h"
|
||||
|
||||
@implementation AppManager {
|
||||
App* _app;
|
||||
HttpManager* _hMan;
|
||||
id<AppAssetCallback> _callback;
|
||||
}
|
||||
|
||||
+ (void) retrieveAppAssets:(NSArray*)apps withManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback {
|
||||
for (App* app in apps) {
|
||||
AppManager* manager = [[AppManager alloc] initWithApp:app httpManager:hMan andCallback:callback];
|
||||
[manager retrieveAsset];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (id) initWithApp:(App*)app httpManager:(HttpManager*)hMan andCallback:(id<AppAssetCallback>)callback {
|
||||
self = [super init];
|
||||
_app = app;
|
||||
_hMan = hMan;
|
||||
_callback = callback;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) retrieveAsset {
|
||||
NSData* appAsset = [_hMan executeRequestSynchronously:[_hMan newAppAssetRequestWithAppId:_app.appId]];
|
||||
UIImage* appImage = [UIImage imageWithData:appAsset];
|
||||
_app.appImage = appImage;
|
||||
NSLog(@"App Name: %@ id:%@ image: %@", _app.appName, _app.appId, _app.appImage);
|
||||
[self performSelectorOnMainThread:@selector(sendCallBack) withObject:self waitUntilDone:NO];
|
||||
}
|
||||
|
||||
- (void) sendCallBack {
|
||||
[_callback receivedAssetForApp:_app];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
|
||||
+ (NSArray*) getAppListFromXML:(NSData*)xml;
|
||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml;
|
||||
|
||||
@@ -24,6 +25,7 @@
|
||||
- (NSURLRequest*) newServerInfoRequest;
|
||||
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid;
|
||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId;
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString*)appId;
|
||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||
@end
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "HttpManager.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "App.h"
|
||||
|
||||
#include <libxml2/libxml/xmlreader.h>
|
||||
#include <string.h>
|
||||
@@ -25,6 +26,60 @@
|
||||
|
||||
static const NSString* PORT = @"47984";
|
||||
|
||||
+ (NSArray*) getAppListFromXML:(NSData*)xml {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![HttpManager verifyStatus: rootNode]) {
|
||||
NSLog(@"ERROR: Request returned with failure status");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
NSMutableArray* appList = [[NSMutableArray alloc] init];
|
||||
|
||||
while (node != NULL) {
|
||||
NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)"App")) {
|
||||
xmlNodePtr appInfoNode = node->xmlChildrenNode;
|
||||
NSString* appName;
|
||||
NSString* appId;
|
||||
while (appInfoNode != NULL) {
|
||||
NSLog(@"appInfoNode: %s", appInfoNode->name);
|
||||
if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"AppTitle")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appName = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
} else if (!xmlStrcmp(appInfoNode->name, (const xmlChar*)"ID")) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, appInfoNode->xmlChildrenNode, 1);
|
||||
appId = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
appInfoNode = appInfoNode->next;
|
||||
}
|
||||
App* app = [[App alloc] init];
|
||||
app.appName = appName;
|
||||
app.appId = appId;
|
||||
[appList addObject:app];
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
xmlFree(rootNode);
|
||||
xmlFree(docPtr);
|
||||
|
||||
return appList;
|
||||
}
|
||||
|
||||
+ (NSString*) getStatusStringFromXML:(NSData*)xml {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], (int)[xml length]);
|
||||
|
||||
@@ -95,9 +150,10 @@ static const NSString* PORT = @"47984";
|
||||
}
|
||||
|
||||
+ (NSData*) fixXmlVersion:(NSData*) xmlData {
|
||||
NSString* xmlString = [[[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [xmlData length])];
|
||||
//NSLog(@"xmlString: %@", xmlString);
|
||||
return [NSData dataWithBytes:[xmlString UTF8String] length:[xmlString length]];
|
||||
NSString* dataString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
|
||||
NSString* xmlString = [dataString stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [dataString length])];
|
||||
|
||||
return [xmlString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert {
|
||||
@@ -198,6 +254,11 @@ static const NSString* PORT = @"47984";
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString *)appId {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/appasset?uniqueid=%@&appid=%@&AssetType=2&AssetIdx=0", _baseURL, _uniqueId, appId];
|
||||
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||
}
|
||||
|
||||
- (NSString*) bytesToHex:(NSData*)data {
|
||||
const unsigned char* bytes = [data bytes];
|
||||
NSMutableString *hex = [[NSMutableString alloc] init];
|
||||
@@ -212,12 +273,16 @@ static const NSString* PORT = @"47984";
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
NSLog(@"Received data: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
NSLog(@"\n\nReceived data: %@\n\n", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
[_respData appendData:data];
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||
if ([[NSString alloc] initWithData:_respData encoding:NSUTF8StringEncoding] != nil) {
|
||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||
} else {
|
||||
_requestResp = _respData;
|
||||
}
|
||||
dispatch_semaphore_signal(_requestLock);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
- (void) showPIN:(NSString*)PIN;
|
||||
- (void) pairSuccessful;
|
||||
- (void) pairFailed:(NSString*)message;
|
||||
- (void) alreadyPaired;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -32,14 +32,13 @@
|
||||
[_callback pairFailed:@"Unable to connect to PC"];
|
||||
return;
|
||||
}
|
||||
|
||||
if (![[HttpManager getStringFromXML:serverInfo tag:@"currentgame"] isEqual:@"0"]) {
|
||||
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
|
||||
}
|
||||
else if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
|
||||
[self initiatePair];
|
||||
} else {
|
||||
[_callback pairFailed:@"This device is already paired."];
|
||||
[_callback alreadyPaired];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -408,7 +408,19 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
|
||||
-(void) main
|
||||
{
|
||||
LiStartConnection(_host, &_streamConfig, &_clCallbacks, &_drCallbacks, &_arCallbacks, NULL, 0);
|
||||
PLATFORM_CALLBACKS dummyPlCallbacks;
|
||||
|
||||
// Only used on Windows
|
||||
dummyPlCallbacks.threadStart = NULL;
|
||||
dummyPlCallbacks.debugPrint = NULL;
|
||||
|
||||
LiStartConnection(_host,
|
||||
&_streamConfig,
|
||||
&_clCallbacks,
|
||||
&_drCallbacks,
|
||||
&_arCallbacks,
|
||||
&dummyPlCallbacks,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
@interface StreamConfiguration : NSObject
|
||||
|
||||
@property NSString* host;
|
||||
@property NSString* appID;
|
||||
@property int hostAddr;
|
||||
@property int width;
|
||||
@property int height;
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
#import "StreamConfiguration.h"
|
||||
|
||||
@implementation StreamConfiguration
|
||||
@synthesize host, hostAddr, width, height, frameRate, bitRate, riKeyId, riKey;
|
||||
@synthesize host, appID, hostAddr, width, height, frameRate, bitRate, riKeyId, riKey;
|
||||
@end
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
||||
NSString* pairStatus = [HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"];
|
||||
NSString* currentClient = [HttpManager getStringFromXML:serverInfoResp tag:@"CurrentClient"];
|
||||
if (currentGame == NULL || pairStatus == NULL) {
|
||||
[_callbacks launchFailed:@"Failed to connect to PC"];
|
||||
return;
|
||||
@@ -55,6 +56,11 @@
|
||||
|
||||
// resumeApp and launchApp handle calling launchFailed
|
||||
if (![currentGame isEqualToString:@"0"]) {
|
||||
if (![currentClient isEqualToString:@"1"]) {
|
||||
// The server is streaming to someone else
|
||||
[_callbacks launchFailed:@"There is another stream in progress"];
|
||||
return;
|
||||
}
|
||||
// App already running, resume it
|
||||
if (![self resumeApp:hMan]) {
|
||||
return;
|
||||
@@ -79,7 +85,7 @@
|
||||
|
||||
- (BOOL) launchApp:(HttpManager*)hMan {
|
||||
NSData* launchResp = [hMan executeRequestSynchronously:
|
||||
[hMan newLaunchRequest:@"67339056"
|
||||
[hMan newLaunchRequest:_config.appID
|
||||
width:_config.width
|
||||
height:_config.height
|
||||
refreshRate:_config.frameRate
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// UIAppView.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "App.h"
|
||||
|
||||
@protocol AppCallback <NSObject>
|
||||
|
||||
- (void) appClicked:(App*) app;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIAppView : UIView
|
||||
|
||||
- (id) initWithApp:(App*)app andCallback:(id<AppCallback>)callback;
|
||||
- (void) updateAppImage;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// UIAppView.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIAppView.h"
|
||||
|
||||
@implementation UIAppView {
|
||||
App* _app;
|
||||
UIButton* _appButton;
|
||||
UILabel* _appLabel;
|
||||
id<AppCallback> _callback;
|
||||
}
|
||||
static int LABEL_DY = 20;
|
||||
|
||||
- (id) initWithApp:(App*)app andCallback:(id<AppCallback>)callback {
|
||||
self = [super init];
|
||||
_app = app;
|
||||
_callback = callback;
|
||||
|
||||
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||
[_appButton setBackgroundImage:[UIImage imageNamed:@"NoAppImage"] forState:UIControlStateNormal];
|
||||
[_appButton sizeToFit];
|
||||
[_appButton addTarget:self action:@selector(appClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||
_appButton.layer.shadowColor = [[UIColor blackColor] CGColor];
|
||||
_appButton.layer.shadowOffset = CGSizeMake(5,8);
|
||||
_appButton.layer.shadowOpacity = 0.7;
|
||||
|
||||
_appLabel = [[UILabel alloc] init];
|
||||
[_appLabel setText:_app.appName];
|
||||
[_appLabel sizeToFit];
|
||||
_appLabel.center = CGPointMake(_appButton.bounds.origin.x + (_appButton.bounds.size.width / 2), _appButton.bounds.origin.y + _appButton.bounds.size.height + LABEL_DY);
|
||||
|
||||
[self updateBounds];
|
||||
[self addSubview:_appButton];
|
||||
[self addSubview:_appLabel];
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) updateBounds {
|
||||
float x = _appButton.frame.origin.x < _appLabel.frame.origin.x ? _appButton.frame.origin.x : _appLabel.frame.origin.x;
|
||||
float y = _appButton.frame.origin.y < _appLabel.frame.origin.y ? _appButton.frame.origin.y : _appLabel.frame.origin.y;
|
||||
self.bounds = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||
self.frame = CGRectMake(x , y, _appButton.frame.size.width > _appLabel.frame.size.width ? _appButton.frame.size.width : _appLabel.frame.size.width, _appButton.frame.size.height + _appLabel.frame.size.height + LABEL_DY / 2);
|
||||
}
|
||||
|
||||
- (void) appClicked {
|
||||
[_callback appClicked:_app];
|
||||
}
|
||||
|
||||
- (void) updateAppImage {
|
||||
if (_app.appImage != nil) {
|
||||
[_appButton setBackgroundImage:_app.appImage forState:UIControlStateNormal];
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// UIComputerView.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Computer.h"
|
||||
|
||||
@protocol HostCallback <NSObject>
|
||||
|
||||
- (void) hostClicked:(Computer*)computer;
|
||||
- (void) addHostClicked;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIComputerView : UIView
|
||||
|
||||
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback;
|
||||
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// UIComputerView.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/22/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIComputerView.h"
|
||||
|
||||
@implementation UIComputerView {
|
||||
Computer* _computer;
|
||||
UIButton* _hostButton;
|
||||
UILabel* _hostLabel;
|
||||
id<HostCallback> _callback;
|
||||
CGSize _labelSize;
|
||||
}
|
||||
static int LABEL_DY = 20;
|
||||
|
||||
- (id) init {
|
||||
self = [super init];
|
||||
_hostButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_hostButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||
[_hostButton setBackgroundImage:[UIImage imageNamed:@"Computer"] forState:UIControlStateNormal];
|
||||
[_hostButton sizeToFit];
|
||||
|
||||
_hostButton.layer.shadowColor = [[UIColor blackColor] CGColor];
|
||||
_hostButton.layer.shadowOffset = CGSizeMake(5,8);
|
||||
_hostButton.layer.shadowOpacity = 0.7;
|
||||
|
||||
_hostLabel = [[UILabel alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithComputer:(Computer*)computer andCallback:(id<HostCallback>)callback {
|
||||
self = [self init];
|
||||
_computer = computer;
|
||||
_callback = callback;
|
||||
|
||||
[_hostLabel setText:[_computer displayName]];
|
||||
[_hostLabel sizeToFit];
|
||||
[_hostButton addTarget:self action:@selector(hostClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||
[self updateBounds];
|
||||
[self addSubview:_hostButton];
|
||||
[self addSubview:_hostLabel];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) updateBounds {
|
||||
float x = _hostButton.frame.origin.x < _hostLabel.frame.origin.x ? _hostButton.frame.origin.x : _hostLabel.frame.origin.x;
|
||||
float y = _hostButton.frame.origin.y < _hostLabel.frame.origin.y ? _hostButton.frame.origin.y : _hostLabel.frame.origin.y;
|
||||
self.bounds = CGRectMake(x , y, _hostButton.frame.size.width > _hostLabel.frame.size.width ? _hostButton.frame.size.width : _hostLabel.frame.size.width, _hostButton.frame.size.height + _hostLabel.frame.size.height + LABEL_DY / 2);
|
||||
self.frame = CGRectMake(x , y, _hostButton.frame.size.width > _hostLabel.frame.size.width ? _hostButton.frame.size.width : _hostLabel.frame.size.width, _hostButton.frame.size.height + _hostLabel.frame.size.height + LABEL_DY / 2);
|
||||
}
|
||||
|
||||
- (id) initForAddWithCallback:(id<HostCallback>)callback {
|
||||
self = [self init];
|
||||
_callback = callback;
|
||||
|
||||
[_hostButton setBackgroundImage:[UIImage imageNamed:@"Computer"] forState:UIControlStateNormal];
|
||||
[_hostButton sizeToFit];
|
||||
[_hostButton addTarget:self action:@selector(addClicked) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[_hostLabel setText:@"Add Host"];
|
||||
[_hostLabel sizeToFit];
|
||||
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||
|
||||
UIImageView* addIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AddComputerIcon"]];
|
||||
[addIcon sizeToFit];
|
||||
addIcon.center = CGPointMake(_hostButton.frame.origin.x + _hostButton.frame.size.width, _hostButton.frame.origin.y);
|
||||
|
||||
[self updateBounds];
|
||||
[self addSubview:_hostButton];
|
||||
[self addSubview:_hostLabel];
|
||||
[self addSubview:addIcon];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) hostClicked {
|
||||
[_callback hostClicked:_computer];
|
||||
}
|
||||
|
||||
- (void) addClicked {
|
||||
[_callback addHostClicked];
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -15,6 +15,5 @@
|
||||
|
||||
- (id) initWithHost:(NSNetService*)host;
|
||||
- (id) initWithIp:(NSString*)host;
|
||||
- (id) initPlaceholder;
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,13 +28,20 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initPlaceholder {
|
||||
self = [super init];
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([object isKindOfClass:[Computer class]]) {
|
||||
return [self.hostName isEqual:[object valueForKey:@"hostName"]];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
NSUInteger prime = 31;
|
||||
NSUInteger result = 1;
|
||||
result = prime * result + (self.hostName == nil ? 0 : [self.hostName hash]);
|
||||
|
||||
self.hostName = NULL;
|
||||
self.displayName = @"No computers found";
|
||||
|
||||
return self;
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,16 +10,13 @@
|
||||
#import "MDNSManager.h"
|
||||
#import "PairManager.h"
|
||||
#import "StreamConfiguration.h"
|
||||
#import "UIComputerView.h"
|
||||
#import "UIAppView.h"
|
||||
#import "AppManager.h"
|
||||
#import "SWRevealViewController.h"
|
||||
|
||||
@interface MainFrameViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, MDNSCallback, NSURLConnectionDelegate, PairCallback, UITextFieldDelegate>
|
||||
@property (strong, nonatomic) IBOutlet UIPickerView *HostPicker;
|
||||
- (IBAction)StreamButton:(UIButton *)sender;
|
||||
- (IBAction)PairButton:(UIButton *)sender;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIPickerView *StreamConfigs;
|
||||
@property (strong, nonatomic) NSArray* streamConfigVals;
|
||||
@property (strong, nonatomic) NSArray* hostPickerVals;
|
||||
@property (strong, nonatomic) IBOutlet UITextField *hostTextField;
|
||||
@interface MainFrameViewController : UIViewController <MDNSCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate>
|
||||
@property (strong, nonatomic) IBOutlet UIBarButtonItem *settingsSidebarButton;
|
||||
|
||||
+ (StreamConfiguration*) getStreamConfiguration;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
//
|
||||
// MainFrameViewController.m
|
||||
// Limelight-iOS
|
||||
//
|
||||
@@ -14,47 +13,34 @@
|
||||
#import "VideoDecoderRenderer.h"
|
||||
#import "StreamManager.h"
|
||||
#import "Utils.h"
|
||||
#import "UIComputerView.h"
|
||||
#import "UIAppView.h"
|
||||
#import "App.h"
|
||||
#import "SettingsViewController.h"
|
||||
#import "DataManager.h"
|
||||
#import "Settings.h"
|
||||
|
||||
@implementation MainFrameViewController {
|
||||
NSOperationQueue* _opQueue;
|
||||
MDNSManager* _mDNSManager;
|
||||
Computer* _selectedHost;
|
||||
NSString* _uniqueId;
|
||||
NSData* _cert;
|
||||
|
||||
UIAlertView* _pairAlert;
|
||||
UIScrollView* hostScrollView;
|
||||
UIScrollView* appScrollView;
|
||||
|
||||
int currentPosition;
|
||||
}
|
||||
static NSString* deviceName = @"roth";
|
||||
static NSMutableSet* hostList;
|
||||
static StreamConfiguration* streamConfig;
|
||||
|
||||
+ (StreamConfiguration*) getStreamConfiguration {
|
||||
return streamConfig;
|
||||
}
|
||||
|
||||
- (void)PairButton:(UIButton *)sender
|
||||
{
|
||||
NSLog(@"Pair Button Pressed!");
|
||||
if ([self.hostTextField.text length] > 0) {
|
||||
_selectedHost = [[Computer alloc] initWithIp:self.hostTextField.text];
|
||||
NSLog(@"Using custom host: %@", self.hostTextField.text);
|
||||
}
|
||||
|
||||
if (![self validatePcSelected]) {
|
||||
NSLog(@"No valid PC selected");
|
||||
return;
|
||||
}
|
||||
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
NSString* uniqueId = [CryptoManager getUniqueID];
|
||||
NSData* cert = [CryptoManager readCertFromFile];
|
||||
|
||||
if ([Utils resolveHost:_selectedHost.hostName] == 0) {
|
||||
[self displayDnsFailedDialog];
|
||||
return;
|
||||
}
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:cert callback:self];
|
||||
|
||||
[_opQueue addOperation:pMan];
|
||||
}
|
||||
|
||||
- (void)showPIN:(NSString *)PIN {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
_pairAlert = [[UIAlertView alloc] initWithTitle:@"Pairing" message:[NSString stringWithFormat:@"Enter the following PIN on the host machine: %@", PIN]delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
|
||||
@@ -78,6 +64,26 @@ static StreamConfiguration* streamConfig;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)alreadyPaired {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_selectedHost.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* appListResp = [hMan executeRequestSynchronously:[hMan newAppListRequest]];
|
||||
NSArray* appList = [HttpManager getAppListFromXML:appListResp];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateApps:appList];
|
||||
});
|
||||
[AppManager retrieveAppAssets:appList withManager:hMan andCallback:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void) receivedAssetForApp:(App*)app {
|
||||
NSArray* subviews = [appScrollView subviews];
|
||||
for (UIAppView* appView in subviews) {
|
||||
[appView updateAppImage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)displayDnsFailedDialog {
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Network Error"
|
||||
message:@"Failed to resolve host."
|
||||
@@ -86,123 +92,129 @@ static StreamConfiguration* streamConfig;
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)StreamButton:(UIButton *)sender
|
||||
{
|
||||
NSLog(@"Stream Button Pressed!");
|
||||
if ([self.hostTextField.text length] > 0) {
|
||||
_selectedHost = [[Computer alloc] initWithIp:self.hostTextField.text];
|
||||
NSLog(@"Using custom host: %@", self.hostTextField.text);
|
||||
}
|
||||
|
||||
if (![self validatePcSelected]) {
|
||||
NSLog(@"No valid PC selected");
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) hostClicked:(Computer *)computer {
|
||||
NSLog(@"Clicked host: %@", computer.displayName);
|
||||
_selectedHost = computer;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:computer.hostName uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||
if ([[HttpManager getStringFromXML:serverInfoResp tag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||
NSLog(@"Already Paired");
|
||||
[self alreadyPaired];
|
||||
} else {
|
||||
NSLog(@"Trying to pair");
|
||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:_cert callback:self];
|
||||
[_opQueue addOperation:pMan];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void) addHostClicked {
|
||||
NSLog(@"Clicked add host");
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:@"Host Address" message:@"Please enter a hostname or IP address" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||
NSString* host = ((UITextField*)[[alertController textFields] objectAtIndex:0]).text;
|
||||
Computer* newHost = [[Computer alloc] initWithIp:host];
|
||||
[hostList addObject:newHost];
|
||||
[self updateHosts:[hostList allObjects]];
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
[dataMan createHost:newHost.displayName hostname:newHost.hostName];
|
||||
[dataMan saveHosts];
|
||||
|
||||
//TODO: get pair state
|
||||
|
||||
|
||||
}]];
|
||||
[alertController addTextFieldWithConfigurationHandler:nil];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void) appClicked:(App *)app {
|
||||
NSLog(@"Clicked app: %@", app.appName);
|
||||
streamConfig = [[StreamConfiguration alloc] init];
|
||||
streamConfig.host = _selectedHost.hostName;
|
||||
streamConfig.hostAddr = [Utils resolveHost:_selectedHost.hostName];
|
||||
streamConfig.appID = app.appId;
|
||||
if (streamConfig.hostAddr == 0) {
|
||||
[self displayDnsFailedDialog];
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long selectedConf = [self.StreamConfigs selectedRowInComponent:0];
|
||||
NSLog(@"selectedConf: %ld", selectedConf);
|
||||
switch (selectedConf) {
|
||||
case 0:
|
||||
streamConfig.width = 1280;
|
||||
streamConfig.height = 720;
|
||||
streamConfig.frameRate = 30;
|
||||
streamConfig.bitRate = 5000;
|
||||
break;
|
||||
default:
|
||||
case 1:
|
||||
streamConfig.width = 1280;
|
||||
streamConfig.height = 720;
|
||||
streamConfig.frameRate = 60;
|
||||
streamConfig.bitRate = 10000;
|
||||
break;
|
||||
case 2:
|
||||
streamConfig.width = 1920;
|
||||
streamConfig.height = 1080;
|
||||
streamConfig.frameRate = 30;
|
||||
streamConfig.bitRate = 10000;
|
||||
break;
|
||||
case 3:
|
||||
streamConfig.width = 1920;
|
||||
streamConfig.height = 1080;
|
||||
streamConfig.frameRate = 60;
|
||||
streamConfig.bitRate = 20000;
|
||||
break;
|
||||
}
|
||||
NSLog(@"StreamConfig: %@, %d, %dx%dx%d at %d Mbps", streamConfig.host, streamConfig.hostAddr, streamConfig.width, streamConfig.height, streamConfig.frameRate, streamConfig.bitRate);
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
|
||||
}
|
||||
|
||||
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
|
||||
{
|
||||
if (pickerView == self.StreamConfigs) {
|
||||
return [self.streamConfigVals objectAtIndex:row];
|
||||
} else if (pickerView == self.HostPicker) {
|
||||
return ((Computer*)([self.hostPickerVals objectAtIndex:row])).displayName;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSelectedHost:(NSInteger)selectedIndex
|
||||
{
|
||||
_selectedHost = (Computer*)([self.hostPickerVals objectAtIndex:selectedIndex]);
|
||||
if (_selectedHost.hostName == NULL) {
|
||||
// This must be the placeholder computer
|
||||
_selectedHost = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
|
||||
{
|
||||
if (pickerView == self.HostPicker) {
|
||||
[self setSelectedHost:[self.HostPicker selectedRowInComponent:0]];
|
||||
}
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
Settings* streamSettings = [dataMan retrieveSettings];
|
||||
|
||||
//TODO: figure out how to save this info!!
|
||||
}
|
||||
|
||||
// returns the number of 'columns' to display.
|
||||
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// returns the # of rows in each component..
|
||||
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
|
||||
{
|
||||
if (pickerView == self.StreamConfigs) {
|
||||
return self.streamConfigVals.count;
|
||||
} else if (pickerView == self.HostPicker) {
|
||||
return self.hostPickerVals.count;
|
||||
} else {
|
||||
return 0;
|
||||
streamConfig.frameRate = [streamSettings.framerate intValue];
|
||||
streamConfig.bitRate = [streamSettings.bitrate intValue];
|
||||
streamConfig.height = [streamSettings.height intValue];
|
||||
streamConfig.width = [streamSettings.width intValue];
|
||||
|
||||
|
||||
if (currentPosition != FrontViewPositionLeft) {
|
||||
[[self revealViewController] revealToggle:self];
|
||||
}
|
||||
[self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
|
||||
}
|
||||
|
||||
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position {
|
||||
// If we moved back to the center position, we should save the settings
|
||||
if (position == FrontViewPositionLeft) {
|
||||
[(SettingsViewController*)[revealController rearViewController] saveSettings];
|
||||
}
|
||||
currentPosition = position;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)", @"1280x720 (60Hz)", @"1920x1080 (30Hz)", @"1920x1080 (60Hz)",nil];
|
||||
[self.StreamConfigs selectRow:1 inComponent:0 animated:NO];
|
||||
|
||||
// Change button color
|
||||
_settingsSidebarButton.tintColor = [UIColor colorWithRed:.2 green:.9 blue:0.f alpha:1.f];
|
||||
|
||||
// Set the side bar button action. When it's tapped, it'll show the sidebar.
|
||||
_settingsSidebarButton.target = self.revealViewController;
|
||||
_settingsSidebarButton.action = @selector(revealToggle:);
|
||||
|
||||
// Set the gesture
|
||||
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
|
||||
|
||||
// Get callbacks associated with the viewController
|
||||
[self.revealViewController setDelegate:self];
|
||||
|
||||
// Set the current position to the center
|
||||
currentPosition = FrontViewPositionLeft;
|
||||
|
||||
// Set up crypto
|
||||
_opQueue = [[NSOperationQueue alloc] init];
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
_uniqueId = [CryptoManager getUniqueID];
|
||||
_cert = [CryptoManager readCertFromFile];
|
||||
|
||||
// Initialize the host picker list
|
||||
[self updateHosts:[[NSArray alloc] init]];
|
||||
// Only initialize the host picker list once
|
||||
if (hostList == nil) {
|
||||
hostList = [[NSMutableSet alloc] init];
|
||||
}
|
||||
|
||||
[self setAutomaticallyAdjustsScrollViewInsets:NO];
|
||||
|
||||
hostScrollView = [[UIScrollView alloc] init];
|
||||
hostScrollView.frame = CGRectMake(0, self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height, self.view.frame.size.width, self.view.frame.size.height / 2);
|
||||
[hostScrollView setShowsHorizontalScrollIndicator:NO];
|
||||
|
||||
appScrollView = [[UIScrollView alloc] init];
|
||||
appScrollView.frame = CGRectMake(0, hostScrollView.frame.size.height, self.view.frame.size.width, self.view.frame.size.height / 2);
|
||||
[appScrollView setShowsHorizontalScrollIndicator:NO];
|
||||
|
||||
[self retrieveSavedHosts];
|
||||
[self updateHosts:[hostList allObjects]];
|
||||
[self.view addSubview:hostScrollView];
|
||||
[self.view addSubview:appScrollView];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
||||
_mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
||||
[_mDNSManager searchForHosts];
|
||||
}
|
||||
@@ -213,17 +225,69 @@ static StreamConfiguration* streamConfig;
|
||||
[_mDNSManager stopSearching];
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
NSMutableArray *hostPickerValues = [[NSMutableArray alloc] initWithArray:hosts];
|
||||
- (void) retrieveSavedHosts {
|
||||
//TODO: Get rid of Computer and only use Host
|
||||
|
||||
if ([hostPickerValues count] == 0) {
|
||||
[hostPickerValues addObject:[[Computer alloc] initPlaceholder]];
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
NSArray* hosts = [dataMan retrieveHosts];
|
||||
for (Host* host in hosts) {
|
||||
Computer* comp = [[Computer alloc] initWithIp:host.address];
|
||||
comp.displayName = host.name;
|
||||
[hostList addObject:comp];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
[hostList addObjectsFromArray:hosts];
|
||||
[[hostScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
UIComputerView* addComp = [[UIComputerView alloc] initForAddWithCallback:self];
|
||||
UIComputerView* compView;
|
||||
float prevEdge = -1;
|
||||
for (Computer* comp in hostList) {
|
||||
compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self];
|
||||
compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2);
|
||||
prevEdge = compView.frame.origin.x + compView.frame.size.width;
|
||||
[hostScrollView addSubview:compView];
|
||||
}
|
||||
|
||||
self.hostPickerVals = hostPickerValues;
|
||||
[self.HostPicker reloadAllComponents];
|
||||
prevEdge = [self getCompViewX:addComp addComp:addComp prevEdge:prevEdge];
|
||||
addComp.center = CGPointMake(prevEdge, hostScrollView.frame.size.height / 2);
|
||||
|
||||
[self setSelectedHost:[self.HostPicker selectedRowInComponent:0]];
|
||||
[hostScrollView addSubview:addComp];
|
||||
[hostScrollView setContentSize:CGSizeMake(prevEdge + addComp.frame.size.width, hostScrollView.frame.size.height)];
|
||||
}
|
||||
|
||||
- (float) getCompViewX:(UIComputerView*)comp addComp:(UIComputerView*)addComp prevEdge:(float)prevEdge {
|
||||
if (prevEdge == -1) {
|
||||
return hostScrollView.frame.origin.x + comp.frame.size.width / 2 + addComp.frame.size.width / 2;
|
||||
} else {
|
||||
return prevEdge + addComp.frame.size.width / 2 + comp.frame.size.width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) updateApps:(NSArray*)apps {
|
||||
[[appScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
App* fakeApp = [[App alloc] init];
|
||||
fakeApp.appName = @"No App Name";
|
||||
UIAppView* noAppImage = [[UIAppView alloc] initWithApp:fakeApp andCallback:nil];
|
||||
float prevEdge = -1;
|
||||
UIAppView* appView;
|
||||
for (App* app in apps) {
|
||||
appView = [[UIAppView alloc] initWithApp:app andCallback:self];
|
||||
prevEdge = [self getAppViewX:appView noApp:noAppImage prevEdge:prevEdge];
|
||||
appView.center = CGPointMake(prevEdge, appScrollView.frame.size.height / 2);
|
||||
prevEdge = appView.frame.origin.x + appView.frame.size.width;
|
||||
[appScrollView addSubview:appView];
|
||||
}
|
||||
[appScrollView setContentSize:CGSizeMake(prevEdge + noAppImage.frame.size.width, appScrollView.frame.size.height)];
|
||||
}
|
||||
|
||||
- (float) getAppViewX:(UIAppView*)app noApp:(UIAppView*)noAppImage prevEdge:(float)prevEdge {
|
||||
if (prevEdge == -1) {
|
||||
return appScrollView.frame.origin.x + app.frame.size.width / 2 + noAppImage.frame.size.width / 2;
|
||||
} else {
|
||||
return prevEdge + app.frame.size.width / 2 + noAppImage.frame.size.width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)validatePcSelected {
|
||||
@@ -257,22 +321,4 @@ static StreamConfiguration* streamConfig;
|
||||
- (BOOL)shouldAutorotate {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSUInteger)supportedInterfaceOrientations {
|
||||
NSString *deviceType = [UIDevice currentDevice].model;
|
||||
if ([deviceType containsString:@"iPhone"] || [deviceType containsString:@"iPod"]) {
|
||||
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
} else {
|
||||
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
NSString *deviceType = [UIDevice currentDevice].model;
|
||||
if ([deviceType containsString:@"iPhone"] || [deviceType containsString:@"iPod"]) {
|
||||
return UIInterfaceOrientationPortrait;
|
||||
} else {
|
||||
return UIInterfaceOrientationLandscapeRight;
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013 Joan Lluch <joan.lluch@sweetwilliamsl.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Early code inspired on a similar class by Philip Kluz (Philip.Kluz@zuui.org)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
RELEASE NOTES
|
||||
|
||||
|
||||
Version 2.3.0 (Current Version)
|
||||
|
||||
- StoryBoard initializing bug fix
|
||||
- Minor Code refactoring
|
||||
|
||||
Version 2.2.0
|
||||
|
||||
- State Restoration support.
|
||||
- Reverted panGestureRecognizer implementation to before v2.1.0 (works better).
|
||||
- New properties 'toggleAnimationType', 'springDampingRatio'. Default reveal animation is 'Spring'
|
||||
- New property 'frontViewShadowColor'
|
||||
- New properties 'clipsViewsToBounds' and '_extendedPointInsideHit'
|
||||
- New delegate methods for finer control of front view location in the overdraw area, as long as deprecation note on former delegate methods
|
||||
- Other minor changes that should not affect current implementations
|
||||
|
||||
Version 2.1.0
|
||||
|
||||
- Removed SWDirectionPanGestureRecognizer. Horizontal panning is filtered on the shouldBegin delegate. This is cleaner, I hope it does not break previous funcionality
|
||||
- Took a cleaner approach to storyboard support. SWRevealViewControllerSegue is now deprecated and you should use SWRevealViewControllerSegueSetController and SWRevealViewControllerSeguePushController instead.
|
||||
- A minor change on the autoresizingMask of the internal views to fix a glitch on iOS8. This should not affect iOS7
|
||||
|
||||
Version 2.0.2
|
||||
|
||||
- Added new delegates for better control of gesture recognizers
|
||||
|
||||
Version 2.0.1
|
||||
|
||||
- Fix: draggableBorderWidth now correctly handles the cases where one of the rear controllers is not provided
|
||||
- Fix: the shadow related properties are now granted at any time after view load, not just after initialization.
|
||||
|
||||
Version 2.0.0
|
||||
|
||||
- Dropped support for iOS6 and earlier. This version will only work on iOS7
|
||||
|
||||
- The method setFrontViewController:animated: does not longer perform a full reveal animation. Instead it just replaces the frontViewController in
|
||||
its current position. Use the new pushFrontViewController:animated: method to perform a replacement of the front controlles with reveal animation
|
||||
as in the previous version
|
||||
|
||||
IMPORTANT: You must replace all calls to setFrontViewController:animated by calls to pushFrontViewController:animated to prevent breaking
|
||||
functionality on existing projects.
|
||||
|
||||
- Added support for animated replacement of child controllers: setRearViewController, setFrontViewController, setRightViewController now have animated versions.
|
||||
|
||||
- The new 'replaceViewAnimationDuration' property sets the default duration of child viewController replacement.
|
||||
|
||||
- Added the following new delegate methods
|
||||
revealController:willAddViewController:forOperation:animated:
|
||||
revealController:didAddViewController:forOperation:animated:
|
||||
|
||||
- The class also supports custom UIViewControllerAnimatedTransitioning related with the replacement of child viewControllers.
|
||||
You can implement the following new delegate method: revealController:animationControllerForOperation:fromViewController:toViewController:
|
||||
and provide an object conforming to UIViewControllerAnimatedTransitioning to implement custom animations.
|
||||
|
||||
Version 1.1.3
|
||||
|
||||
- Reverted the supportedInterfaceOrientations to the default behavior. This is consistent with Apple provided controllers
|
||||
|
||||
- The presentFrontViewHierarchically now dynamically takes into account the smaller header height of bars on iPhone landscape orientation
|
||||
|
||||
Version 1.1.2
|
||||
|
||||
- The status bar style and appearance are now handled in sync with the class animations.
|
||||
You can implement the methods preferredStatusBarStyle and prefersStatusBarHidden on your child controllers to define the desired appearance
|
||||
|
||||
- The loadView method now calls a method, loadStoryboardControllers, just for the purpose of loading child controllers from a storyboard.
|
||||
You can override this method and remove the @try @catch statements if you want the debugger not to stop at them in case you have set an exception breakpoint.
|
||||
|
||||
Version 1.1.1
|
||||
|
||||
- You can now get a tapGestureRecognizer from the class. See the tapGestureRecognizer method for more information.
|
||||
|
||||
- Both the panGestureRecognizer and the tapGestureRecognizer are now attached to the revealViewController's front content view
|
||||
by default, so they will start working just by calling their access methods even if you do not attach them to any of your views.
|
||||
This enables you to dissable interactions on your views -for example based on position- without breaking normal gesture behavior.
|
||||
|
||||
- Corrected a bug that caused a crash on iOS6 and earlier.
|
||||
|
||||
Version 1.1.0
|
||||
|
||||
- The method setFrontViewController:animated now performs the correct animations both for left and right controllers.
|
||||
|
||||
- The class now automatically handles the status bar appearance depending on the currently shown child controller.
|
||||
|
||||
Version 1.0.8
|
||||
|
||||
- Support for constant width frontView by setting a negative value to reveal widths. See properties rearViewRevealWidth and rightViewRevealWidth
|
||||
|
||||
- Support for draggableBorderWidth. See property of the same name.
|
||||
|
||||
- The Pan gesture recongnizer can be disabled by implementing the following delegate method and returning NO
|
||||
revealControllerPanGestureShouldBegin:
|
||||
|
||||
- Added the ability to track pan gesture reveal progress through the following new delegate methods
|
||||
revealController:panGestureBeganFromLocation:progress:
|
||||
revealController:panGestureMovedToLocation:progress:
|
||||
revealController:panGestureEndedToLocation:progress:
|
||||
|
||||
Previous Versions
|
||||
|
||||
- No release notes were updated for previous versions.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class SWRevealViewController;
|
||||
@protocol SWRevealViewControllerDelegate;
|
||||
|
||||
#pragma mark - SWRevealViewController Class
|
||||
|
||||
// Enum values for setFrontViewPosition:animated:
|
||||
typedef NS_ENUM( NSInteger, FrontViewPosition)
|
||||
{
|
||||
// Front controller is removed from view. Animated transitioning from this state will cause the same
|
||||
// effect than animating from FrontViewPositionLeftSideMost. Use this instead of FrontViewPositionLeftSideMost when
|
||||
// you want to remove the front view controller view from the view hierarchy.
|
||||
FrontViewPositionLeftSideMostRemoved,
|
||||
|
||||
// Left most position, front view is presented left-offseted by rightViewRevealWidth+rigthViewRevealOverdraw
|
||||
FrontViewPositionLeftSideMost,
|
||||
|
||||
// Left position, front view is presented left-offseted by rightViewRevealWidth
|
||||
FrontViewPositionLeftSide,
|
||||
|
||||
// Center position, rear view is hidden behind front controller
|
||||
FrontViewPositionLeft,
|
||||
|
||||
// Right possition, front view is presented right-offseted by rearViewRevealWidth
|
||||
FrontViewPositionRight,
|
||||
|
||||
// Right most possition, front view is presented right-offseted by rearViewRevealWidth+rearViewRevealOverdraw
|
||||
FrontViewPositionRightMost,
|
||||
|
||||
// Front controller is removed from view. Animated transitioning from this state will cause the same
|
||||
// effect than animating from FrontViewPositionRightMost. Use this instead of FrontViewPositionRightMost when
|
||||
// you intent to remove the front controller view from the view hierarchy.
|
||||
FrontViewPositionRightMostRemoved,
|
||||
|
||||
};
|
||||
|
||||
// Enum values for toggleAnimationType
|
||||
typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType)
|
||||
{
|
||||
SWRevealToggleAnimationTypeSpring, // <- produces a spring based animation
|
||||
SWRevealToggleAnimationTypeEaseOut, // <- produces an ease out curve animation
|
||||
};
|
||||
|
||||
|
||||
@interface SWRevealViewController : UIViewController
|
||||
|
||||
/* Basic API */
|
||||
|
||||
// Object instance init and rear view setting
|
||||
- (id)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController;
|
||||
|
||||
// Rear view controller, can be nil if not used
|
||||
@property (nonatomic) UIViewController *rearViewController;
|
||||
- (void)setRearViewController:(UIViewController *)rearViewController animated:(BOOL)animated;
|
||||
|
||||
// Optional right view controller, can be nil if not used
|
||||
@property (nonatomic) UIViewController *rightViewController;
|
||||
- (void)setRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated;
|
||||
|
||||
// Front view controller, can be nil on initialization but must be supplied by the time the view is loaded
|
||||
@property (nonatomic) UIViewController *frontViewController;
|
||||
- (void)setFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated;
|
||||
|
||||
// Sets the frontViewController using a default set of chained animations consisting on moving the
|
||||
// presented frontViewController to the right most possition, replacing it, and moving it back to the left position
|
||||
- (void)pushFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated;
|
||||
|
||||
// Sets the frontViewController position. You can call the animated version several times with different
|
||||
// positions to obtain a set of animations that will be performed in order one after the other.
|
||||
@property (nonatomic) FrontViewPosition frontViewPosition;
|
||||
- (void)setFrontViewPosition:(FrontViewPosition)frontViewPosition animated:(BOOL)animated;
|
||||
|
||||
// The following methods are meant to be directly connected to the action method of a button
|
||||
// to perform user triggered postion change of the controller views. This is ussually added to a
|
||||
// button on top left or right of the frontViewController
|
||||
- (IBAction)revealToggle:(id)sender;
|
||||
- (IBAction)rightRevealToggle:(id)sender; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// Toogles the current state of the front controller between Left or Right and fully visible
|
||||
// Use setFrontViewPosition to set a particular position
|
||||
- (void)revealToggleAnimated:(BOOL)animated;
|
||||
- (void)rightRevealToggleAnimated:(BOOL)animated; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// The following method will provide a panGestureRecognizer suitable to be added to any view
|
||||
// in order to perform usual drag and swipe gestures to reveal the rear views. This is usually added to the top bar
|
||||
// of a front controller, but it can be added to your frontViewController view or to the reveal controller view to provide full screen panning.
|
||||
// By default, the panGestureRecognizer is added to the view containing the front controller view. To keep this default behavior
|
||||
// you still need to call this method, just don't add it to any of your views. The default setup allows you to dissable
|
||||
// user interactions on your controller views without affecting the recognizer.
|
||||
- (UIPanGestureRecognizer*)panGestureRecognizer;
|
||||
|
||||
// The following method will provide a tapGestureRecognizer suitable to be added to any view on the frontController
|
||||
// for concealing the rear views. By default no tap recognizer is created or added to any view, however if you call this method after
|
||||
// the controller's view has been loaded the recognizer is added to the reveal controller's front container view.
|
||||
// Thus, you can disable user interactions on your frontViewController view without affecting the tap recognizer.
|
||||
- (UITapGestureRecognizer*)tapGestureRecognizer;
|
||||
|
||||
/* The following properties are provided for further customization, they are set to default values on initialization,
|
||||
you do not generally have to set them */
|
||||
|
||||
// Defines how much of the rear or right view is shown, default is 260.
|
||||
// Negative values indicate that the reveal width should be computed by substracting the full front view width,
|
||||
// so the revealed frontView width is kept constant when bounds change as opposed to the rear or right width.
|
||||
@property (nonatomic) CGFloat rearViewRevealWidth;
|
||||
@property (nonatomic) CGFloat rightViewRevealWidth; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// Defines how much of an overdraw can occur when dragging further than 'rearViewRevealWidth', default is 60.
|
||||
@property (nonatomic) CGFloat rearViewRevealOverdraw;
|
||||
@property (nonatomic) CGFloat rightViewRevealOverdraw; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// Defines how much displacement is applied to the rear view when animating or dragging the front view, default is 40.
|
||||
@property (nonatomic) CGFloat rearViewRevealDisplacement;
|
||||
@property (nonatomic) CGFloat rightViewRevealDisplacement; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// Defines a width on the border of the view attached to the panGesturRecognizer where the gesture is allowed,
|
||||
// default is 0 which means no restriction.
|
||||
@property (nonatomic) CGFloat draggableBorderWidth;
|
||||
|
||||
// If YES (the default) the controller will bounce to the Left position when dragging further than 'rearViewRevealWidth'
|
||||
@property (nonatomic) BOOL bounceBackOnOverdraw;
|
||||
@property (nonatomic) BOOL bounceBackOnLeftOverdraw; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// If YES (default is NO) the controller will allow permanent dragging up to the rightMostPosition
|
||||
@property (nonatomic) BOOL stableDragOnOverdraw;
|
||||
@property (nonatomic) BOOL stableDragOnLeftOverdraw; // <-- simetric implementation of the above for the rightViewController
|
||||
|
||||
// If YES (default is NO) the front view controller will be ofsseted vertically by the height of a navigation bar.
|
||||
// Use this on iOS7 when you add an instance of RevealViewController as a child of a UINavigationController (or another SWRevealViewController)
|
||||
// and you want the front view controller to be presented below the navigation bar of its UINavigationController grand parent.
|
||||
// The rearViewController will still appear full size and blurred behind the navigation bar of its UINavigationController grand parent
|
||||
@property (nonatomic) BOOL presentFrontViewHierarchically;
|
||||
|
||||
// Velocity required for the controller to toggle its state based on a swipe movement, default is 250
|
||||
@property (nonatomic) CGFloat quickFlickVelocity;
|
||||
|
||||
// Duration for the revealToggle animation, default is 0.25
|
||||
@property (nonatomic) NSTimeInterval toggleAnimationDuration;
|
||||
|
||||
// Animation type, default is SWRevealToggleAnimationTypeSpring
|
||||
@property (nonatomic) SWRevealToggleAnimationType toggleAnimationType;
|
||||
|
||||
// When animation type is SWRevealToggleAnimationTypeSpring determines the damping ratio, default is 1
|
||||
@property (nonatomic) CGFloat springDampingRatio;
|
||||
|
||||
// Duration for animated replacement of view controllers
|
||||
@property (nonatomic) NSTimeInterval replaceViewAnimationDuration;
|
||||
|
||||
// Defines the radius of the front view's shadow, default is 2.5f
|
||||
@property (nonatomic) CGFloat frontViewShadowRadius;
|
||||
|
||||
// Defines the radius of the front view's shadow offset default is {0.0f,2.5f}
|
||||
@property (nonatomic) CGSize frontViewShadowOffset;
|
||||
|
||||
// Defines the front view's shadow opacity, default is 1.0f
|
||||
@property (nonatomic) CGFloat frontViewShadowOpacity;
|
||||
|
||||
// Defines the front view's shadow color, default is blackColor
|
||||
@property (nonatomic) UIColor *frontViewShadowColor;
|
||||
|
||||
// Defines whether the controller should clip subviews to its view bounds. Default is NO.
|
||||
// Set this to YES when you are presenting this controller as a non full-screen child of a
|
||||
// custom container controller which does not explicitly clips its subviews.
|
||||
@property (nonatomic) BOOL clipsViewsToBounds;
|
||||
|
||||
// Defines whether your views clicable area extends beyond the bounds of this controller. Default is NO.
|
||||
// Set this to YES if you are presenting this controller as a non full-screen child of a custom container and you are not
|
||||
// clipping your front view to this controller bounds.
|
||||
@property (nonatomic) BOOL extendsPointInsideHit;
|
||||
|
||||
/* The class properly handles all the relevant calls to appearance methods on the contained controllers.
|
||||
Moreover you can assign a delegate to let the class inform you on positions and animation activity */
|
||||
|
||||
// Delegate
|
||||
@property (nonatomic,weak) id<SWRevealViewControllerDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - SWRevealViewControllerDelegate Protocol
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SWRevealControllerOperationNone,
|
||||
SWRevealControllerOperationReplaceRearController,
|
||||
SWRevealControllerOperationReplaceFrontController,
|
||||
SWRevealControllerOperationReplaceRightController,
|
||||
|
||||
} SWRevealControllerOperation;
|
||||
|
||||
|
||||
@protocol SWRevealViewControllerDelegate<NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
// The following delegate methods will be called before and after the front view moves to a position
|
||||
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position;
|
||||
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position;
|
||||
|
||||
// This will be called inside the reveal animation, thus you can use it to place your own code that will be animated in sync
|
||||
- (void)revealController:(SWRevealViewController *)revealController animateToPosition:(FrontViewPosition)position;
|
||||
|
||||
// Implement this to return NO when you want the pan gesture recognizer to be ignored
|
||||
- (BOOL)revealControllerPanGestureShouldBegin:(SWRevealViewController *)revealController;
|
||||
|
||||
// Implement this to return NO when you want the tap gesture recognizer to be ignored
|
||||
- (BOOL)revealControllerTapGestureShouldBegin:(SWRevealViewController *)revealController;
|
||||
|
||||
// Implement this to return YES if you want other gesture recognizer to share touch events with the pan gesture
|
||||
- (BOOL)revealController:(SWRevealViewController *)revealController
|
||||
panGestureRecognizerShouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
|
||||
|
||||
// Implement this to return YES if you want other gesture recognizer to share touch events with the tap gesture
|
||||
- (BOOL)revealController:(SWRevealViewController *)revealController
|
||||
tapGestureRecognizerShouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
|
||||
|
||||
// Called when the gestureRecognizer began and ended
|
||||
- (void)revealControllerPanGestureBegan:(SWRevealViewController *)revealController;
|
||||
- (void)revealControllerPanGestureEnded:(SWRevealViewController *)revealController;
|
||||
|
||||
// The following methods provide a means to track the evolution of the gesture recognizer.
|
||||
// The 'location' parameter is the X origin coordinate of the front view as the user drags it
|
||||
// The 'progress' parameter is a number ranging from 0 to 1 indicating the front view location relative to the
|
||||
// rearRevealWidth or rightRevealWidth. 1 is fully revealed, dragging ocurring in the overDraw region will result in values above 1.
|
||||
// The 'overProgress' parameter is a number ranging from 0 to 1 indicating the front view location relative to the
|
||||
// overdraw region. 0 is fully revealed, 1 is fully overdrawn. Negative values occur inside the normal reveal region
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureBeganFromLocation:(CGFloat)location progress:(CGFloat)progress overProgress:(CGFloat)overProgress;
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureMovedToLocation:(CGFloat)location progress:(CGFloat)progress overProgress:(CGFloat)overProgress;
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureEndedToLocation:(CGFloat)location progress:(CGFloat)progress overProgress:(CGFloat)overProgress;
|
||||
|
||||
// Notification of child controller replacement
|
||||
- (void)revealController:(SWRevealViewController *)revealController willAddViewController:(UIViewController *)viewController
|
||||
forOperation:(SWRevealControllerOperation)operation animated:(BOOL)animated;
|
||||
- (void)revealController:(SWRevealViewController *)revealController didAddViewController:(UIViewController *)viewController
|
||||
forOperation:(SWRevealControllerOperation)operation animated:(BOOL)animated;
|
||||
|
||||
// Support for custom transition animations while replacing child controllers. If implemented, it will be fired in response
|
||||
// to calls to 'setXXViewController' methods
|
||||
- (id<UIViewControllerAnimatedTransitioning>)revealController:(SWRevealViewController *)revealController
|
||||
animationControllerForOperation:(SWRevealControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC;
|
||||
|
||||
// DEPRECATED - The following delegate methods will be removed some time in the future
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureBeganFromLocation:(CGFloat)location progress:(CGFloat)progress; // (DEPRECATED)
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureMovedToLocation:(CGFloat)location progress:(CGFloat)progress; // (DEPRECATED)
|
||||
- (void)revealController:(SWRevealViewController *)revealController panGestureEndedToLocation:(CGFloat)location progress:(CGFloat)progress; // (DEPRECATED)
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - UIViewController(SWRevealViewController) Category
|
||||
|
||||
// A category of UIViewController to let childViewControllers easily access their parent SWRevealViewController
|
||||
@interface UIViewController(SWRevealViewController)
|
||||
|
||||
- (SWRevealViewController*)revealViewController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - StoryBoard support Classes
|
||||
|
||||
/* StoryBoard support */
|
||||
|
||||
// String identifiers to be applied to segues on a storyboard
|
||||
extern NSString* const SWSegueRearIdentifier; // this is @"sw_rear"
|
||||
extern NSString* const SWSegueFrontIdentifier; // this is @"sw_front"
|
||||
extern NSString* const SWSegueRightIdentifier; // this is @"sw_right"
|
||||
|
||||
/* This will allow the class to be defined on a storyboard */
|
||||
|
||||
// Use this along with one of the above segue identifiers to segue to the initial state
|
||||
@interface SWRevealViewControllerSegueSetController : UIStoryboardSegue
|
||||
@end
|
||||
|
||||
// Use this to push a view controller
|
||||
@interface SWRevealViewControllerSeguePushController : UIStoryboardSegue
|
||||
@end
|
||||
|
||||
|
||||
//#pragma mark - SWRevealViewControllerSegue (DEPRECATED)
|
||||
//
|
||||
//@interface SWRevealViewControllerSegue : UIStoryboardSegue // DEPRECATED: USE SWRevealViewControllerSegueSetController instead
|
||||
//@property (nonatomic, strong) void(^performBlock)( SWRevealViewControllerSegue* segue, UIViewController* svc, UIViewController* dvc );
|
||||
//@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// SettingsViewController.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/27/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface SettingsViewController : UIViewController
|
||||
@property (strong, nonatomic) IBOutlet UILabel *bitrateLabel;
|
||||
@property (strong, nonatomic) IBOutlet UISlider *bitrateSlider;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector;
|
||||
|
||||
- (void) saveSettings;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// SettingsViewController.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/27/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SettingsViewController.h"
|
||||
#import "Settings.h"
|
||||
#import "DataManager.h"
|
||||
|
||||
#define BITRATE_INTERVAL 100
|
||||
|
||||
@implementation SettingsViewController {
|
||||
NSInteger _bitrate;
|
||||
}
|
||||
static NSString* bitrateFormat = @"Bitrate: %d kbps";
|
||||
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
Settings* currentSettings = [dataMan retrieveSettings];
|
||||
|
||||
_bitrate = [currentSettings.bitrate integerValue];
|
||||
NSInteger framerate = [currentSettings.framerate integerValue] == 30 ? 0 : 1;
|
||||
NSInteger resolution = [currentSettings.height integerValue] == 720 ? 0 : 1;
|
||||
|
||||
[self.resolutionSelector setSelectedSegmentIndex:resolution];
|
||||
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
||||
[self.bitrateSlider setValue:_bitrate animated:YES];
|
||||
[self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged];
|
||||
[self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, (int)_bitrate]];
|
||||
}
|
||||
|
||||
- (void) bitrateSliderMoved {
|
||||
_bitrate = BITRATE_INTERVAL * floor((self.bitrateSlider.value/BITRATE_INTERVAL)+0.5);
|
||||
[self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, (int)_bitrate]];
|
||||
}
|
||||
|
||||
|
||||
- (void) saveSettings {
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
NSInteger framerate = [self.framerateSelector selectedSegmentIndex] == 0 ? 30 : 60;
|
||||
NSInteger height = [self.resolutionSelector selectedSegmentIndex] == 0 ? 720 : 1080;
|
||||
NSInteger width = height == 720 ? 1280 : 1920;
|
||||
[dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height width:width];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Navigation
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -25,8 +25,12 @@
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.stageLabel setText:@"Starting App"];
|
||||
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
||||
|
||||
[self.stageLabel setText:@"Starting App"];
|
||||
[self.stageLabel sizeToFit];
|
||||
self.stageLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
|
||||
self.spinner.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2 - self.stageLabel.frame.size.height - self.spinner.frame.size.height);
|
||||
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
||||
|
||||
_controllerSupport = [[ControllerSupport alloc] init];
|
||||
@@ -43,9 +47,13 @@
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void) returnToMainFrame {
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(NSNotification *)notification {
|
||||
[_streamMan stopStream];
|
||||
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||
[self returnToMainFrame];
|
||||
}
|
||||
|
||||
- (void) connectionStarted {
|
||||
@@ -53,6 +61,7 @@
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.spinner stopAnimating];
|
||||
[self.stageLabel setText:@"Waiting for first frame..."];
|
||||
[self.stageLabel sizeToFit];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,7 +70,7 @@
|
||||
|
||||
UIAlertController* conTermAlert = [UIAlertController alertControllerWithTitle:@"Connection Terminated" message:@"The connection terminated unexpectedly" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[conTermAlert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:conTermAlert animated:YES completion:nil];
|
||||
|
||||
@@ -74,6 +83,8 @@
|
||||
NSString* lowerCase = [NSString stringWithFormat:@"%s in progress...", stageName];
|
||||
NSString* titleCase = [[[lowerCase substringToIndex:1] uppercaseString] stringByAppendingString:[lowerCase substringFromIndex:1]];
|
||||
[self.stageLabel setText:titleCase];
|
||||
[self.stageLabel sizeToFit];
|
||||
self.stageLabel.center = CGPointMake(self.view.frame.size.width / 2, self.stageLabel.center.y);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,7 +97,7 @@
|
||||
stageName, errorCode]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
@@ -96,7 +107,7 @@
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||
[self returnToMainFrame];
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
@@ -118,13 +129,4 @@
|
||||
- (BOOL)shouldAutorotate {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSUInteger)supportedInterfaceOrientations {
|
||||
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
return UIInterfaceOrientationLandscapeRight;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="wb7-af-jn8">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Main Frame View Controller-->
|
||||
<scene sceneID="Me4-Nr-liz">
|
||||
<objects>
|
||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="9ZL-gP-cfY"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="Shd-7C-CVq"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" horizontalHuggingPriority="222" id="ugc-rC-3gm">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bJR-sz-8uh">
|
||||
<rect key="frame" x="0.0" y="80" width="1024" height="216"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="wb7-af-jn8" id="EW1-pG-aj0"/>
|
||||
<outlet property="delegate" destination="wb7-af-jn8" id="Piq-cV-gxM"/>
|
||||
</connections>
|
||||
</pickerView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="taW-Um-zc6" userLabel="Start Stream Btn">
|
||||
<rect key="frame" x="317" y="273" width="391" height="141"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="391" id="f7x-eA-edG"/>
|
||||
<constraint firstAttribute="height" constant="141" id="sdD-TL-lHS"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="26"/>
|
||||
<state key="normal" title="Start Streaming Steam!">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="StreamButton:" destination="wb7-af-jn8" eventType="touchUpInside" id="u2m-8A-Tor"/>
|
||||
</connections>
|
||||
</button>
|
||||
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rnA-uG-hAA">
|
||||
<rect key="frame" x="0.0" y="380" width="1024" height="216"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="wb7-af-jn8" id="25E-op-oh6"/>
|
||||
<outlet property="delegate" destination="wb7-af-jn8" id="gjZ-oj-THD"/>
|
||||
</connections>
|
||||
</pickerView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Nz-KX-Du4" userLabel="Pair Btn">
|
||||
<rect key="frame" x="439" y="595" width="147" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="C4p-5e-fbL"/>
|
||||
<constraint firstAttribute="width" constant="147" id="I0J-8h-40c"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="26"/>
|
||||
<state key="normal" title="Pair with PC">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="PairButton:" destination="wb7-af-jn8" eventType="touchUpInside" id="Ct1-6m-aYg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Geforce Host" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="OCq-Pr-kFE">
|
||||
<rect key="frame" x="233" y="235" width="601" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="601" id="haa-mB-l8k"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="wb7-af-jn8" id="YMu-2k-Dyk"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="taW-Um-zc6" firstAttribute="top" secondItem="OCq-Pr-kFE" secondAttribute="bottom" constant="8" symbolic="YES" id="7GU-HB-BX8"/>
|
||||
<constraint firstItem="OCq-Pr-kFE" firstAttribute="leading" secondItem="ugc-rC-3gm" secondAttribute="leading" constant="233" id="DM7-XL-gaO"/>
|
||||
<constraint firstAttribute="centerX" secondItem="rnA-uG-hAA" secondAttribute="centerX" id="EBV-fm-cGh"/>
|
||||
<constraint firstItem="taW-Um-zc6" firstAttribute="top" secondItem="ugc-rC-3gm" secondAttribute="top" constant="273" id="Gki-EV-x7L"/>
|
||||
<constraint firstItem="rnA-uG-hAA" firstAttribute="trailing" secondItem="bJR-sz-8uh" secondAttribute="trailing" id="RKH-ES-jQD"/>
|
||||
<constraint firstItem="rnA-uG-hAA" firstAttribute="leading" secondItem="bJR-sz-8uh" secondAttribute="leading" id="UNO-rw-Z5K"/>
|
||||
<constraint firstItem="taW-Um-zc6" firstAttribute="centerX" secondItem="rnA-uG-hAA" secondAttribute="centerX" id="clq-Co-82x"/>
|
||||
<constraint firstItem="Shd-7C-CVq" firstAttribute="top" secondItem="rnA-uG-hAA" secondAttribute="bottom" constant="172" id="gRA-PG-Iqy"/>
|
||||
<constraint firstItem="Shd-7C-CVq" firstAttribute="top" secondItem="0Nz-KX-Du4" secondAttribute="bottom" constant="137" id="nJf-9A-cfP"/>
|
||||
<constraint firstItem="rnA-uG-hAA" firstAttribute="centerX" secondItem="0Nz-KX-Du4" secondAttribute="centerX" id="toQ-ei-Pr0"/>
|
||||
<constraint firstItem="rnA-uG-hAA" firstAttribute="top" secondItem="bJR-sz-8uh" secondAttribute="bottom" constant="84" id="zMG-gd-Hxd"/>
|
||||
<constraint firstItem="rnA-uG-hAA" firstAttribute="leading" secondItem="ugc-rC-3gm" secondAttribute="leading" id="znq-P0-UWg"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="HostPicker" destination="bJR-sz-8uh" id="pWB-P3-ZJ2"/>
|
||||
<outlet property="StreamConfigs" destination="rnA-uG-hAA" id="LPP-jQ-5eW"/>
|
||||
<outlet property="hostTextField" destination="OCq-Pr-kFE" id="HS2-KF-inc"/>
|
||||
<segue destination="OIm-0n-i9v" kind="modal" identifier="createStreamFrame" modalPresentationStyle="fullScreen" id="MOD-9A-3Sk"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-375" y="-162"/>
|
||||
</scene>
|
||||
<!--Stream Frame View Controller-->
|
||||
<scene sceneID="RuD-qk-7nb">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="NG3-N1-D4k"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="3MH-n6-BSR"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" translatesAutoresizingMaskIntoConstraints="NO" id="iOs-1X-mSU">
|
||||
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dDs-kT-po6">
|
||||
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="dDs-kT-po6" firstAttribute="top" secondItem="iOs-1X-mSU" secondAttribute="bottom" constant="8" id="VZj-wk-dHp"/>
|
||||
<constraint firstAttribute="centerY" secondItem="iOs-1X-mSU" secondAttribute="centerY" id="YAN-0k-Rds"/>
|
||||
<constraint firstAttribute="centerX" secondItem="dDs-kT-po6" secondAttribute="centerX" id="bLr-5Z-OH3"/>
|
||||
<constraint firstAttribute="centerX" secondItem="iOs-1X-mSU" secondAttribute="centerX" id="ruD-8B-gj3"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="iOs-1X-mSU" id="LSl-lr-7fF"/>
|
||||
<outlet property="stageLabel" destination="dDs-kT-po6" id="ziI-M8-UVf"/>
|
||||
<segue destination="wb7-af-jn8" kind="modal" identifier="returnToMainFrame" id="Ryr-0y-o43"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1252" y="-312"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="lightContent"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
@@ -1,144 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="dgh-JZ-Q7z">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Main Frame View Controller-->
|
||||
<scene sceneID="emz-kO-L7q">
|
||||
<objects>
|
||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="0HR-9w-kvY"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="2rs-P3-zn7"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="eqF-iA-Rqx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J5M-pv-UHA">
|
||||
<rect key="frame" x="82" y="303" width="156" height="30"/>
|
||||
<state key="normal" title="Start Streaming Steam">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="StreamButton:" destination="dgh-JZ-Q7z" eventType="touchUpInside" id="3Bj-I0-bKs"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ATh-Tf-xRL">
|
||||
<rect key="frame" x="137" y="341" width="46" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="46" id="mm8-gm-flQ"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Pair">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="PairButton:" destination="dgh-JZ-Q7z" eventType="touchUpInside" id="jHN-B5-hsw"/>
|
||||
</connections>
|
||||
</button>
|
||||
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0xb-lk-PHK">
|
||||
<rect key="frame" x="0.0" y="354" width="320" height="162"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="dgh-JZ-Q7z" id="R0Y-EX-neJ"/>
|
||||
<outlet property="delegate" destination="dgh-JZ-Q7z" id="mkk-oI-y7K"/>
|
||||
</connections>
|
||||
</pickerView>
|
||||
<pickerView contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="nFR-to-qQs">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="216"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="dgh-JZ-Q7z" id="C28-Eh-A6L"/>
|
||||
<outlet property="delegate" destination="dgh-JZ-Q7z" id="dTy-8g-aj1"/>
|
||||
</connections>
|
||||
</pickerView>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Geforce Host" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="unc-nO-WPH">
|
||||
<rect key="frame" x="16" y="224" width="288" height="30"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="dgh-JZ-Q7z" id="DCy-4m-RHG"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="0xb-lk-PHK" firstAttribute="leading" secondItem="2rs-P3-zn7" secondAttribute="leading" id="350-bN-0q6"/>
|
||||
<constraint firstAttribute="centerX" secondItem="J5M-pv-UHA" secondAttribute="centerX" id="5jf-C1-faJ"/>
|
||||
<constraint firstItem="unc-nO-WPH" firstAttribute="top" secondItem="0HR-9w-kvY" secondAttribute="bottom" constant="224" id="A1r-Mh-dg7"/>
|
||||
<constraint firstAttribute="centerX" secondItem="0xb-lk-PHK" secondAttribute="centerX" id="By0-u3-3MA"/>
|
||||
<constraint firstItem="0xb-lk-PHK" firstAttribute="centerX" secondItem="J5M-pv-UHA" secondAttribute="centerX" id="Gab-EA-Il5"/>
|
||||
<constraint firstItem="unc-nO-WPH" firstAttribute="leading" secondItem="J5M-pv-UHA" secondAttribute="leading" constant="-66" id="Qk0-0J-79M"/>
|
||||
<constraint firstItem="0xb-lk-PHK" firstAttribute="top" secondItem="J5M-pv-UHA" secondAttribute="bottom" constant="21" id="RNw-zD-7u7"/>
|
||||
<constraint firstItem="0xb-lk-PHK" firstAttribute="top" secondItem="ATh-Tf-xRL" secondAttribute="bottom" constant="-17" id="TN4-kv-Yli"/>
|
||||
<constraint firstItem="J5M-pv-UHA" firstAttribute="top" secondItem="nFR-to-qQs" secondAttribute="bottom" constant="87" id="Vcz-ix-cdp"/>
|
||||
<constraint firstItem="nFR-to-qQs" firstAttribute="top" secondItem="0HR-9w-kvY" secondAttribute="bottom" id="XWH-Vw-VfH"/>
|
||||
<constraint firstItem="0xb-lk-PHK" firstAttribute="centerX" secondItem="ATh-Tf-xRL" secondAttribute="centerX" id="bEv-zi-oip"/>
|
||||
<constraint firstItem="J5M-pv-UHA" firstAttribute="top" secondItem="unc-nO-WPH" secondAttribute="bottom" constant="49" id="dU2-fJ-SU7"/>
|
||||
<constraint firstItem="ATh-Tf-xRL" firstAttribute="top" secondItem="J5M-pv-UHA" secondAttribute="bottom" constant="8" id="gNc-KC-Q9G"/>
|
||||
<constraint firstItem="unc-nO-WPH" firstAttribute="trailing" secondItem="J5M-pv-UHA" secondAttribute="trailing" constant="66" id="h4a-vk-mBB"/>
|
||||
<constraint firstAttribute="centerX" secondItem="nFR-to-qQs" secondAttribute="centerX" id="h9S-ek-7bf"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<toolbarItems/>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="HostPicker" destination="nFR-to-qQs" id="lTE-tT-lYY"/>
|
||||
<outlet property="StreamConfigs" destination="0xb-lk-PHK" id="VxB-Ur-PNy"/>
|
||||
<outlet property="hostTextField" destination="unc-nO-WPH" id="MbD-KQ-MoG"/>
|
||||
<segue destination="mI3-9F-XwU" kind="modal" identifier="createStreamFrame" id="cPc-eP-un1"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="HNf-lX-GEO" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="131" y="0.0"/>
|
||||
</scene>
|
||||
<!--Stream Frame View Controller-->
|
||||
<scene sceneID="5Eb-q2-vjt">
|
||||
<objects>
|
||||
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="DRq-YB-9Rh"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="KH1-hM-RYW"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" translatesAutoresizingMaskIntoConstraints="NO" id="0vm-Iv-K4b">
|
||||
<rect key="frame" x="150" y="274" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2HK-Z5-4Ch">
|
||||
<rect key="frame" x="138" y="302" width="45" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="2HK-Z5-4Ch" secondAttribute="centerX" constant="-0.5" id="Blw-Hy-66z"/>
|
||||
<constraint firstAttribute="centerX" secondItem="0vm-Iv-K4b" secondAttribute="centerX" id="mCQ-CP-Yik"/>
|
||||
<constraint firstAttribute="centerY" secondItem="0vm-Iv-K4b" secondAttribute="centerY" id="t8e-qp-g1j"/>
|
||||
<constraint firstItem="2HK-Z5-4Ch" firstAttribute="top" secondItem="0vm-Iv-K4b" secondAttribute="bottom" constant="8" id="tta-Uo-bBO"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="0vm-Iv-K4b" id="Lif-zG-6Jh"/>
|
||||
<outlet property="stageLabel" destination="2HK-Z5-4Ch" id="1bI-Ig-OpD"/>
|
||||
<segue destination="dgh-JZ-Q7z" kind="modal" identifier="returnToMainFrame" id="djB-MF-L5D"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="pqv-jd-33O" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="584" y="0.0"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14C68k" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="EVd-wq-ego">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Limelight-->
|
||||
<scene sceneID="Me4-Nr-liz">
|
||||
<objects>
|
||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Icf-Kt-Ai7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Limelight" id="pSu-bl-gL9">
|
||||
<barButtonItem key="leftBarButtonItem" image="Settings" id="pGu-Vp-WrR"/>
|
||||
</navigationItem>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="settingsSidebarButton" destination="pGu-Vp-WrR" id="bIM-oj-LgU"/>
|
||||
<segue destination="OIm-0n-i9v" kind="push" identifier="createStreamFrame" id="7gN-E7-Ips"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="797" y="514"/>
|
||||
</scene>
|
||||
<!--Settings View Controller-->
|
||||
<scene sceneID="tWo-uo-hHg">
|
||||
<objects>
|
||||
<viewController id="BsV-3c-455" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="WRy-3f-gEP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10000 kbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="lMt-4H-fkV">
|
||||
<rect key="frame" x="16" y="58" width="151" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="10000" minValue="0.0" maxValue="50000" id="JAY-nj-UNz">
|
||||
<rect key="frame" x="14" y="87" width="213" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</slider>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Aiv-r8-9k2">
|
||||
<rect key="frame" x="16" y="156" width="83" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pYZ-GR-EwO">
|
||||
<rect key="frame" x="16" y="244" width="87" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="ckc-Dm-8ex">
|
||||
<rect key="frame" x="16" y="273" width="123" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<segments>
|
||||
<segment title="720p"/>
|
||||
<segment title="1080p"/>
|
||||
</segments>
|
||||
</segmentedControl>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="lGK-vl-pdw">
|
||||
<rect key="frame" x="16" y="185" width="123" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<segments>
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</segments>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="bitrateLabel" destination="lMt-4H-fkV" id="ItM-l3-1Jk"/>
|
||||
<outlet property="bitrateSlider" destination="JAY-nj-UNz" id="fHd-v5-9Vo"/>
|
||||
<outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/>
|
||||
<outlet property="resolutionSelector" destination="ckc-Dm-8ex" id="rl6-rx-wd3"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="01j-TU-OoL" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="779" y="1425"/>
|
||||
</scene>
|
||||
<!--Reveal View Controller-->
|
||||
<scene sceneID="rR7-ZT-bc7">
|
||||
<objects>
|
||||
<viewController id="EVd-wq-ego" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="hGs-BR-t4b">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<segue destination="baW-rW-rBd" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="RBe-eP-uG6"/>
|
||||
<segue destination="BsV-3c-455" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="U4R-8o-x2S"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lUU-kb-wrO" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-1728" y="514"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="FxL-or-HET">
|
||||
<objects>
|
||||
<navigationController id="baW-rW-rBd" sceneMemberID="viewController">
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="RUe-14-4Ya">
|
||||
<rect key="frame" x="0.0" y="0.0" width="768" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="wb7-af-jn8" kind="relationship" relationship="rootViewController" id="nkY-JG-Wki"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iLe-Yz-zIG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-397" y="514"/>
|
||||
</scene>
|
||||
<!--Stream Frame View Controller-->
|
||||
<scene sceneID="RuD-qk-7nb">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="iOs-1X-mSU">
|
||||
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</activityIndicatorView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dDs-kT-po6">
|
||||
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="iUf-9X-GeA"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="iOs-1X-mSU" id="LSl-lr-7fF"/>
|
||||
<outlet property="stageLabel" destination="dDs-kT-po6" id="ziI-M8-UVf"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1946" y="514"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Settings" width="25" height="25"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="lightContent"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14C68k" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="DL0-L5-LOv">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Limelight-->
|
||||
<scene sceneID="emz-kO-L7q">
|
||||
<objects>
|
||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="RId-Pb-IBX">
|
||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Limelight" id="1jn-Sf-Xky">
|
||||
<barButtonItem key="leftBarButtonItem" image="Settings" id="5gr-O1-slj"/>
|
||||
</navigationItem>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="settingsSidebarButton" destination="5gr-O1-slj" id="vK6-bY-5h5"/>
|
||||
<segue destination="mI3-9F-XwU" kind="push" identifier="createStreamFrame" id="Vgc-B6-lvM"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="HNf-lX-GEO" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1363" y="796"/>
|
||||
</scene>
|
||||
<!--Reveal View Controller-->
|
||||
<scene sceneID="QYt-XN-Ojr">
|
||||
<objects>
|
||||
<viewController id="DL0-L5-LOv" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Usg-e0-g4a">
|
||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<segue destination="rYd-e6-cQU" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="vBQ-bn-yZu"/>
|
||||
<segue destination="ftZ-kC-fxI" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="V3E-d5-bsZ"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="RXm-iV-Zqb" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-66" y="796"/>
|
||||
</scene>
|
||||
<!--Side Bar-->
|
||||
<scene sceneID="uYM-56-Ivb">
|
||||
<objects>
|
||||
<viewController id="rYd-e6-cQU" userLabel="Side Bar" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="iNk-qF-gIr" customClass="UIScrollView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="10000" minValue="0.0" maxValue="50000" id="3nn-MI-9Xu">
|
||||
<rect key="frame" x="14" y="72" width="204" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</slider>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10000 kbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SBv-Wn-LB7">
|
||||
<rect key="frame" x="17" y="43" width="151" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="dLF-qJ-2nY">
|
||||
<rect key="frame" x="16" y="156" width="123" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<segments>
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</segments>
|
||||
</segmentedControl>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Kkv-DF-MAl">
|
||||
<rect key="frame" x="16" y="127" width="83" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8zy-ri-Dqc">
|
||||
<rect key="frame" x="16" y="206" width="87" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="PCM-t4-Sha">
|
||||
<rect key="frame" x="16" y="235" width="123" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<segments>
|
||||
<segment title="720p"/>
|
||||
<segment title="1080p"/>
|
||||
</segments>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="bitrateLabel" destination="SBv-Wn-LB7" id="Wdu-me-Bvd"/>
|
||||
<outlet property="bitrateSlider" destination="3nn-MI-9Xu" id="IuD-Rk-vPp"/>
|
||||
<outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/>
|
||||
<outlet property="resolutionSelector" destination="PCM-t4-Sha" id="t60-W2-wkV"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="RWc-Km-KG5" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1363" y="1266"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="pfX-8A-htT">
|
||||
<objects>
|
||||
<navigationController id="ftZ-kC-fxI" sceneMemberID="viewController">
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="0ZA-Ec-QgD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="dgh-JZ-Q7z" kind="relationship" relationship="rootViewController" id="NhF-R8-8s3"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Dr2-S8-dHh" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="660" y="796"/>
|
||||
</scene>
|
||||
<!--Stream Frame View Controller-->
|
||||
<scene sceneID="5Eb-q2-vjt">
|
||||
<objects>
|
||||
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2HK-Z5-4Ch">
|
||||
<rect key="frame" x="262" y="149" width="45" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="0vm-Iv-K4b">
|
||||
<rect key="frame" x="274" y="121" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="8uX-4T-BiC"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="0vm-Iv-K4b" id="Lif-zG-6Jh"/>
|
||||
<outlet property="stageLabel" destination="2HK-Z5-4Ch" id="1bI-Ig-OpD"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="pqv-jd-33O" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2092" y="796"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Settings" width="25" height="25"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||