preset advanced widget template profile
This commit is contained in:
1 parent
a03a50d238
commit
f260d75372
6 files changed
+62
-8
No files matched your search
@@ -10,6 +10,7 @@
|
|||||||
#import "OnScreenButtonState.h"
|
#import "OnScreenButtonState.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#define DEFAULT_TEMPLATE_NAME @"高级控件模板(Advanced widget templates)"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This object contains information pertaining to any of the user created, custom on screen controller layout configurations, or 'profiles.' The object contains a 'name' property for easy reference, as well as an 'isSelected' property which is used to determine whether this particular custom OSC layout should show on screen during game stream view. Only one 'OSCProfile' is set to 'isSelected' at any given time. The object also contains an array of 'OnScreenButtonStates' which provides information that allows us to move and hide/unhide each of the 19 on screen buttons. Note that the 'buttonStates' property should contain an NSMutableArray of ENCODED 'OnScreenButtonState' objects. This allows us to save the 'OSCProfile' object to NSUserDefaults.
|
This object contains information pertaining to any of the user created, custom on screen controller layout configurations, or 'profiles.' The object contains a 'name' property for easy reference, as well as an 'isSelected' property which is used to determine whether this particular custom OSC layout should show on screen during game stream view. Only one 'OSCProfile' is set to 'isSelected' at any given time. The object also contains an array of 'OnScreenButtonStates' which provides information that allows us to move and hide/unhide each of the 19 on screen buttons. Note that the 'buttonStates' property should contain an NSMutableArray of ENCODED 'OnScreenButtonState' objects. This allows us to save the 'OSCProfile' object to NSUserDefaults.
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
Note that the implementation file contains a number of 'Helper' methods. These helper methods are only used in this class's implementation file and help to reduce re-writing large blocks of code that are called multiple times throughout the file
|
Note that the implementation file contains a number of 'Helper' methods. These helper methods are only used in this class's implementation file and help to reduce re-writing large blocks of code that are called multiple times throughout the file
|
||||||
*/
|
*/
|
||||||
@interface OSCProfilesManager : NSObject
|
@interface OSCProfilesManager : NSObject
|
||||||
|
@property NSMutableArray <OSCProfile *> *currentProfiles;
|
||||||
|
|
||||||
|
|
||||||
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds;
|
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds;
|
||||||
@@ -40,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (NSMutableArray *) getEncodedProfiles;
|
- (NSMutableArray *) getEncodedProfiles;
|
||||||
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded;
|
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded;
|
||||||
- (OnScreenButtonState *)unarchiveButtonStateEncoded:(NSData *)data;
|
- (OnScreenButtonState *)unarchiveButtonStateEncoded:(NSData *)data;
|
||||||
|
- (void) importDefaultTemplates;
|
||||||
|
|
||||||
#pragma mark - Setters
|
#pragma mark - Setters
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +65,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
* Lets the caller of this method know whether a profile with a given name already exists in persistent storage
|
* Lets the caller of this method know whether a profile with a given name already exists in persistent storage
|
||||||
*/
|
*/
|
||||||
- (BOOL) profileNameAlreadyExist:(NSString*)name;
|
- (BOOL) profileNameAlreadyExist:(NSString*)name;
|
||||||
|
- (BOOL) profileName:(NSString*) name alreadyExistIn:(NSMutableArray*)profiles;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ static CGRect streamViewBounds;
|
|||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
_sharedManager = [[self alloc] init];
|
_sharedManager = [[self alloc] init];
|
||||||
});
|
});
|
||||||
|
// _sharedManager.currentProfiles = [_sharedManager getAllProfiles];
|
||||||
return _sharedManager;
|
return _sharedManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +138,38 @@ static CGRect streamViewBounds;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded {
|
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded {
|
||||||
NSMutableArray* localEncodedPofiles = [self getEncodedProfiles];
|
NSMutableArray* targetProfiles = [_currentProfiles mutableCopy]; //_currentProfiles is availabled as long as getAllProfiles was called before calling this method (_currentProfiles avoids frequent accessing persisted data)
|
||||||
[localEncodedPofiles removeObjectAtIndex:0];
|
if([self profileName:DEFAULT_TEMPLATE_NAME alreadyExistIn:targetProfiles] && targetProfiles.count > 1) [targetProfiles removeObjectAtIndex:1];
|
||||||
|
if(targetProfiles.count > 0) [targetProfiles removeObjectAtIndex:0];
|
||||||
|
NSMutableArray* localEncodedPofiles = [self encodedProfilesFromArray:targetProfiles];
|
||||||
[profilesEncoded addObjectsFromArray:localEncodedPofiles];
|
[profilesEncoded addObjectsFromArray:localEncodedPofiles];
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) importDefaultTemplates{
|
||||||
|
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"widgetTemplates" ofType:@"bin"];
|
||||||
|
if (filePath) {
|
||||||
|
// 2. 读取二进制数据
|
||||||
|
NSError *error;
|
||||||
|
NSData *fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
|
||||||
|
NSMutableArray *profilesEncoded;
|
||||||
|
if (fileData && !error) {
|
||||||
|
// 3. 成功读取
|
||||||
|
NSSet *classes = [NSSet setWithObjects: [NSMutableData class], [NSMutableArray class], nil];
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
// 在 iOS 13 及以上使用 unarchivedObjectOfClasses
|
||||||
|
profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:fileData error:&error];
|
||||||
|
} else {
|
||||||
|
// 在 iOS 12 及以下使用 unarchiveObjectWithData(旧方法)
|
||||||
|
profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSMutableArray class] fromData:fileData error:&error];
|
||||||
|
}
|
||||||
|
[self importEncodedProfiles:profilesEncoded];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Globally Accessible Methods
|
#pragma mark - Globally Accessible Methods
|
||||||
|
|
||||||
@@ -165,6 +190,7 @@ static CGRect streamViewBounds;
|
|||||||
profileDecoded = [NSKeyedUnarchiver unarchivedObjectOfClasses: classes fromData:profileEncoded error: nil];
|
profileDecoded = [NSKeyedUnarchiver unarchivedObjectOfClasses: classes fromData:profileEncoded error: nil];
|
||||||
[profilesDecoded addObject: profileDecoded];
|
[profilesDecoded addObject: profileDecoded];
|
||||||
}
|
}
|
||||||
|
_currentProfiles = profilesDecoded;
|
||||||
return profilesDecoded;
|
return profilesDecoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,15 +378,22 @@ static CGRect streamViewBounds;
|
|||||||
|
|
||||||
- (BOOL) profileNameAlreadyExist:(NSString*)name {
|
- (BOOL) profileNameAlreadyExist:(NSString*)name {
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
NSMutableArray *profiles = [self getAllProfiles];
|
||||||
|
|
||||||
/* Iterate through the decoded profiles and return 'YES' if one of the profiles' 'name' properties equals the 'name' passed into this method */
|
/* Iterate through the decoded profiles and return 'YES' if one of the profiles' 'name' properties equals the 'name' passed into this method */
|
||||||
for (OSCProfile *profile in profiles) {
|
for (OSCProfile *profile in profiles) {
|
||||||
|
|
||||||
if ([profile.name isEqualToString:name]) {
|
if ([profile.name isEqualToString:name]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) profileName:(NSString*) name alreadyExistIn:(NSMutableArray*)profiles {
|
||||||
|
/* Iterate through the decoded profiles and return 'YES' if one of the profiles' 'name' properties equals the 'name' passed into this method */
|
||||||
|
for (OSCProfile *profile in profiles) {
|
||||||
|
if ([profile.name isEqualToString:name]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,7 +406,7 @@ static CGRect streamViewBounds;
|
|||||||
error:nil];
|
error:nil];
|
||||||
} else {
|
} else {
|
||||||
// 在 iOS 12 及以下使用 unarchiveObjectWithData(旧方法)
|
// 在 iOS 12 及以下使用 unarchiveObjectWithData(旧方法)
|
||||||
buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass: [OnScreenButtonState class] fromData:data error:nil];
|
buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:data error:nil];
|
||||||
}
|
}
|
||||||
return buttonState;
|
return buttonState;
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
+8
-1
@@ -163,10 +163,17 @@
|
|||||||
|
|
||||||
self.undoButton.alpha = 0.3; // no changes to undo yet, so fade out the undo button a bit
|
self.undoButton.alpha = 0.3; // no changes to undo yet, so fade out the undo button a bit
|
||||||
|
|
||||||
if ([[profilesManager getAllProfiles] count] == 0) { // if no saved OSC profiles exist yet then create one called 'Default' and associate it with Moonlight's legacy 'Full' OSC layout that's already been laid out on the screen at this point
|
NSMutableArray* allProfiles = [profilesManager getAllProfiles];
|
||||||
|
/*
|
||||||
|
if ([allProfiles count] == 0) { // if no saved OSC profiles exist yet then create one called 'Default' and associate it with Moonlight's legacy 'Full' OSC layout that's already been laid out on the screen at this point
|
||||||
[profilesManager saveProfileWithName:@"Default" andButtonLayers:self.layoutOSC.OSCButtonLayers];
|
[profilesManager saveProfileWithName:@"Default" andButtonLayers:self.layoutOSC.OSCButtonLayers];
|
||||||
|
[profilesManager importDefaultTemplates];
|
||||||
|
}*/
|
||||||
|
if (![profilesManager profileName:DEFAULT_TEMPLATE_NAME alreadyExistIn:allProfiles]){
|
||||||
|
[profilesManager importDefaultTemplates];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(setControllerCALayerSliderValues:)
|
selector:@selector(setControllerCALayerSliderValues:)
|
||||||
name:@"LegacyOscCALayerSelectedNotification"
|
name:@"LegacyOscCALayerSelectedNotification"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
84351B2D2C29AD6100A77989 /* ToolBarContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B292C29AD6000A77989 /* ToolBarContainerView.m */; };
|
84351B2D2C29AD6100A77989 /* ToolBarContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B292C29AD6000A77989 /* ToolBarContainerView.m */; };
|
||||||
84351B5C2C29ADBE00A77989 /* ProfileTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */; };
|
84351B5C2C29ADBE00A77989 /* ProfileTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */; };
|
||||||
84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */; };
|
84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */; };
|
||||||
|
843667F02D9D7173004A7D7F /* widgetTemplates.bin in Resources */ = {isa = PBXBuildFile; fileRef = 843667EF2D9D7173004A7D7F /* widgetTemplates.bin */; };
|
||||||
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */; };
|
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */; };
|
||||||
843CC7F62C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */; };
|
843CC7F62C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */; };
|
||||||
843E93BE2C41528700B1651F /* OrientationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843E93BD2C41528700B1651F /* OrientationHelper.swift */; };
|
843E93BE2C41528700B1651F /* OrientationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843E93BD2C41528700B1651F /* OrientationHelper.swift */; };
|
||||||
@@ -145,6 +146,7 @@
|
|||||||
84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileTableViewCell.m; sourceTree = "<group>"; };
|
84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileTableViewCell.m; sourceTree = "<group>"; };
|
||||||
84351B5A2C29ADBE00A77989 /* ProfileTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileTableViewCell.h; sourceTree = "<group>"; };
|
84351B5A2C29ADBE00A77989 /* ProfileTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileTableViewCell.h; sourceTree = "<group>"; };
|
||||||
84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ProfileTableViewCell.xib; sourceTree = "<group>"; };
|
84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ProfileTableViewCell.xib; sourceTree = "<group>"; };
|
||||||
|
843667EF2D9D7173004A7D7F /* widgetTemplates.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = widgetTemplates.bin; path = Limelight/PresetConfigs/widgetTemplates.bin; sourceTree = SOURCE_ROOT; };
|
||||||
843CC7EE2C1E757D00BBC475 /* NativeTouchPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeTouchPointer.h; sourceTree = "<group>"; };
|
843CC7EE2C1E757D00BBC475 /* NativeTouchPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeTouchPointer.h; sourceTree = "<group>"; };
|
||||||
843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeTouchPointer.m; sourceTree = "<group>"; };
|
843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeTouchPointer.m; sourceTree = "<group>"; };
|
||||||
843CC7F42C1E778000BBC475 /* NativeTouchHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeTouchHandler.h; sourceTree = "<group>"; };
|
843CC7F42C1E778000BBC475 /* NativeTouchHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeTouchHandler.h; sourceTree = "<group>"; };
|
||||||
@@ -453,6 +455,14 @@
|
|||||||
path = Cells;
|
path = Cells;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
843667ED2D9D70A3004A7D7F /* PresetConfigs */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
843667EF2D9D7173004A7D7F /* widgetTemplates.bin */,
|
||||||
|
);
|
||||||
|
name = PresetConfigs;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
84FD0B492C312C0B006B5BE5 /* Localization */ = {
|
84FD0B492C312C0B006B5BE5 /* Localization */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -578,6 +588,7 @@
|
|||||||
FB290CFA19B2C406004C83CF /* Supporting Files */ = {
|
FB290CFA19B2C406004C83CF /* Supporting Files */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
843667ED2D9D70A3004A7D7F /* PresetConfigs */,
|
||||||
FB290CFB19B2C406004C83CF /* Limelight-Info.plist */,
|
FB290CFB19B2C406004C83CF /* Limelight-Info.plist */,
|
||||||
FB290CFC19B2C406004C83CF /* InfoPlist.strings */,
|
FB290CFC19B2C406004C83CF /* InfoPlist.strings */,
|
||||||
FB290CFF19B2C406004C83CF /* main.m */,
|
FB290CFF19B2C406004C83CF /* main.m */,
|
||||||
@@ -1000,6 +1011,7 @@
|
|||||||
FB89463819F6473800339C8A /* Launch Screen.xib in Resources */,
|
FB89463819F6473800339C8A /* Launch Screen.xib in Resources */,
|
||||||
8454AC662C31907F00F0A302 /* iPad.storyboard in Resources */,
|
8454AC662C31907F00F0A302 /* iPad.storyboard in Resources */,
|
||||||
8454AC6A2C319BDA00F0A302 /* iPhone.storyboard in Resources */,
|
8454AC6A2C319BDA00F0A302 /* iPhone.storyboard in Resources */,
|
||||||
|
843667F02D9D7173004A7D7F /* widgetTemplates.bin in Resources */,
|
||||||
84FD0B542C3134A6006B5BE5 /* Localizable.xcstrings in Resources */,
|
84FD0B542C3134A6006B5BE5 /* Localizable.xcstrings in Resources */,
|
||||||
84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */,
|
84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user