restoring fold/unfold states
This commit is contained in:
@@ -31,6 +31,7 @@ typedef NS_ENUM(NSInteger, MapGyroTo) {
|
||||
@property NSString *name;
|
||||
@property NSMutableArray <NSData *> *buttonStatesEncoded;
|
||||
@property (nonatomic, assign) int16_t unfoldedExclusiveFolderSequence;
|
||||
@property NSSet<NSNumber *> *postExclusiveUnfoldedSequences;
|
||||
@property BOOL isSelected;
|
||||
@property (nonatomic, assign) MapGyroTo mapGyroTo;
|
||||
@property (nonatomic, assign) bool yawPitchToRightStick;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
[encoder encodeObject:self.name forKey:@"name"];
|
||||
[encoder encodeObject:self.buttonStatesEncoded forKey:@"buttonStates"];
|
||||
[encoder encodeInt32:self.unfoldedExclusiveFolderSequence forKey:@"unfoldedExclusiveFolderSequence"];
|
||||
[encoder encodeObject:self.postExclusiveUnfoldedSequences forKey:@"postExclusiveUnfoldedSequences"];
|
||||
[encoder encodeBool:self.isSelected forKey:@"isSelected"];
|
||||
[encoder encodeInt64:self.mapGyroTo forKey:@"mapGyroTo"];
|
||||
[encoder encodeBool:self.yawPitchToRightStick forKey:@"yawPitchToRightStick"];
|
||||
@@ -75,6 +76,15 @@
|
||||
nil]
|
||||
forKey:@"buttonStates"];
|
||||
self.unfoldedExclusiveFolderSequence = [decoder containsValueForKey:@"unfoldedExclusiveFolderSequence"] ? [decoder decodeInt32ForKey:@"unfoldedExclusiveFolderSequence"] : -1;
|
||||
self.postExclusiveUnfoldedSequences = [decoder containsValueForKey:@"postExclusiveUnfoldedSequences"] ?
|
||||
[decoder decodeObjectOfClasses:
|
||||
[NSSet setWithObjects:
|
||||
[NSMutableSet class],
|
||||
[NSSet class],
|
||||
[NSNumber class],
|
||||
nil]
|
||||
forKey:@"postExclusiveUnfoldedSequences"] :
|
||||
[NSSet set];
|
||||
self.isSelected = [decoder decodeBoolForKey:@"isSelected"];
|
||||
self.mapGyroTo = [decoder containsValueForKey:@"mapGyroTo"] ? [decoder decodeInt64ForKey:@"mapGyroTo"] : mapGyroToMouse;
|
||||
self.yawPitchToRightStick = [decoder containsValueForKey:@"yawPitchToRightStick"] ? [decoder decodeBoolForKey:@"yawPitchToRightStick"] : true;
|
||||
@@ -134,6 +144,7 @@
|
||||
copy.name = [self.name mutableCopy]; // NSString → NSMutableString
|
||||
copy.buttonStatesEncoded = [[NSMutableArray alloc] initWithArray:self.buttonStatesEncoded copyItems:YES];
|
||||
copy.unfoldedExclusiveFolderSequence = self.unfoldedExclusiveFolderSequence;
|
||||
copy.postExclusiveUnfoldedSequences = [self.postExclusiveUnfoldedSequences copy];
|
||||
copy.isSelected = self.isSelected;
|
||||
copy.mapGyroTo = self.mapGyroTo;
|
||||
copy.yawPitchToRightStick = self.yawPitchToRightStick;
|
||||
|
||||
@@ -209,7 +209,7 @@ static CGRect layoutViewBounds;
|
||||
- (NSMutableArray *) getAllProfiles {
|
||||
NSData *profilesArrayEncoded = [[NSUserDefaults standardUserDefaults] objectForKey: @"OSCProfiles"]; // Get the encoded array of encoded OSC profiles from persistent storage
|
||||
NSSet *classes = [NSSet setWithObjects:[NSString class], [NSMutableData class], [NSMutableArray class], [OSCProfile class], [OnScreenButtonState class], nil];
|
||||
|
||||
|
||||
NSMutableArray *profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:profilesArrayEncoded error:nil]; // Decode the encoded array itself, NOT the objects contained in the array
|
||||
|
||||
/* Decode each of the encoded profiles, place them into an array, then return the array */
|
||||
@@ -292,6 +292,7 @@ static CGRect layoutViewBounds;
|
||||
OSCProfile *selectedProfile = [self getSelectedProfile];
|
||||
selectedProfile.buttonStatesEncoded = buttonStatesEncoded;
|
||||
selectedProfile.unfoldedExclusiveFolderSequence = OnScreenWidgetView.unfoldedExclusiveFolderSequence;
|
||||
selectedProfile.postExclusiveUnfoldedSequences = OnScreenWidgetView.postExclusiveUnfoldedSequences;
|
||||
[self replaceSelectedProfileWith:selectedProfile overwriteDefault:NO];
|
||||
return true;
|
||||
}
|
||||
@@ -481,7 +482,7 @@ static CGRect layoutViewBounds;
|
||||
|
||||
- (OnScreenButtonState *)unarchiveButtonStateEncoded:(NSData *)data {
|
||||
OnScreenButtonState* buttonState;
|
||||
buttonState = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObjects:[NSString class], [OnScreenButtonState class], [NSSet class], nil]
|
||||
buttonState = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObjects:[NSString class], [OnScreenButtonState class], [NSSet class], [NSNumber class], nil]
|
||||
fromData:data
|
||||
error:nil];
|
||||
return buttonState;
|
||||
|
||||
@@ -11,9 +11,13 @@ import SVGKit
|
||||
|
||||
@objc class OnScreenWidgetView: UIView {
|
||||
@objc public static var mapping: [Int16:OnScreenWidgetView] = [:]
|
||||
@objc public static var isRestoring: Bool = false
|
||||
@objc public static func set(widget:OnScreenWidgetView, for key:Int16) {
|
||||
mapping[key] = widget
|
||||
}
|
||||
@objc public static func widgetFor(key:Int16) -> OnScreenWidgetView? {
|
||||
return mapping[key]
|
||||
}
|
||||
@objc public static func removeWidgetFromMappings(key:Int16) {
|
||||
mapping.removeValue(forKey: key)
|
||||
}
|
||||
@@ -21,6 +25,12 @@ import SVGKit
|
||||
mapping.removeAll()
|
||||
}
|
||||
@objc public static var unfoldedExclusiveFolderSequence:Int16 = -1
|
||||
@objc public static var postExclusiveUnfoldedSequences:Set<Int16> = Set()
|
||||
@objc public static func setPostExclusiveUnfoldeds(_ sequences:NSSet){
|
||||
let sequenceSet:Set<Int16> = sequences as? Set<Int16> ?? Set()
|
||||
postExclusiveUnfoldedSequences = Set(sequenceSet)
|
||||
print("postExclusiveUnfoldedSequences \(postExclusiveUnfoldedSequences) \(CACurrentMediaTime())")
|
||||
}
|
||||
|
||||
@objc public weak var guidelineDelegate: OnScreenWidgetGuidelineUpdateDelegate?
|
||||
@objc protocol OnScreenWidgetGuidelineUpdateDelegate: AnyObject {
|
||||
@@ -274,6 +284,7 @@ import SVGKit
|
||||
private var tickFlag: UInt8 = 0
|
||||
|
||||
@objc public var folded: Bool = false
|
||||
@objc public var persistedFolded: Bool = false
|
||||
@objc public var revealMode: RevealMode = .coexist
|
||||
@objc public var sequenceSet: Set<Int16> = Set()
|
||||
@objc public var parentSequence: Int16 = -1
|
||||
@@ -2804,6 +2815,7 @@ import SVGKit
|
||||
setCollection(hidden: folded, for: folder)
|
||||
if !folded, folder.revealMode == .exclusive {
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = folder.sequence
|
||||
if(!isRestoring) {OnScreenWidgetView.postExclusiveUnfoldedSequences.removeAll()}
|
||||
let currentRootFolder = OnScreenWidgetView.getRootFolder(of: folder) ?? folder
|
||||
var offshootRootFolders:Set<OnScreenWidgetView> = Set()
|
||||
folder.forEachWidget{ widget in
|
||||
@@ -2822,6 +2834,15 @@ import SVGKit
|
||||
guard currentRootFolder != folder else {return}
|
||||
setCollection(hidden: true, for:currentRootFolder, exception: folder, recursive: true)
|
||||
}
|
||||
if folded, folder.revealMode == .exclusive {
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = -1
|
||||
}
|
||||
if folder.revealMode == .coexist {
|
||||
if folded {
|
||||
OnScreenWidgetView.postExclusiveUnfoldedSequences.remove(folder.sequence)
|
||||
}
|
||||
else {OnScreenWidgetView.postExclusiveUnfoldedSequences.insert(folder.sequence)}
|
||||
}
|
||||
}
|
||||
|
||||
private static func getRootFolder(of widget:OnScreenWidgetView) -> OnScreenWidgetView?{
|
||||
@@ -2867,17 +2888,27 @@ import SVGKit
|
||||
}
|
||||
|
||||
@objc static func restoreFoldedStates(){
|
||||
isRestoring = true
|
||||
var unfoldedExclusiveFolder: OnScreenWidgetView?
|
||||
if unfoldedExclusiveFolderSequence != -1 {
|
||||
unfoldedExclusiveFolder = OnScreenWidgetView.mapping[unfoldedExclusiveFolderSequence]
|
||||
if(unfoldedExclusiveFolder != nil){
|
||||
OnScreenWidgetView.set(folded: false, for: unfoldedExclusiveFolder!)
|
||||
}
|
||||
}
|
||||
|
||||
for widget in OnScreenWidgetView.mapping.values {
|
||||
OnScreenWidgetView.setCollection(hidden: widget.folded, for: widget, exception: unfoldedExclusiveFolder)
|
||||
}
|
||||
|
||||
if(unfoldedExclusiveFolder != nil){
|
||||
OnScreenWidgetView.set(folded: false, for: unfoldedExclusiveFolder!)
|
||||
}
|
||||
|
||||
print("postExclusiveUnfoldedSequences \(postExclusiveUnfoldedSequences) stamp \(CACurrentMediaTime())")
|
||||
for sequence in postExclusiveUnfoldedSequences {
|
||||
guard let folder = OnScreenWidgetView.mapping[sequence] else { continue }
|
||||
OnScreenWidgetView.set(folded: false, for: folder)
|
||||
}
|
||||
|
||||
isRestoring = false
|
||||
}
|
||||
|
||||
override func didMoveToSuperview() {
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
andConfig:(StreamConfiguration*)streamConfig;
|
||||
- (void) clearOnScreenWidgets;
|
||||
- (void) reloadOnScreenWidgetViews:(bool)reload;
|
||||
- (void) saveRelocatedWidgetViews;
|
||||
- (void) saveStreamViewWidgetChanges;
|
||||
- (bool) isOnScreenWidgetEnabled;
|
||||
|
||||
- (CGSize) getVideoAreaSize;
|
||||
|
||||
@@ -494,19 +494,29 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
else return longSide;
|
||||
}
|
||||
|
||||
- (void)saveRelocatedWidgetViews{
|
||||
- (void)saveStreamViewWidgetChanges{
|
||||
/*
|
||||
NSMutableDictionary* relocatedWidgetDict = [NSMutableDictionary dictionary];
|
||||
|
||||
for(UIView* subview in self->_streamFrameTopLayerView.subviews){
|
||||
if([subview isKindOfClass:[OnScreenWidgetView class]]){
|
||||
OnScreenWidgetView* widget = (OnScreenWidgetView* )subview;
|
||||
if(widget.relocatedDuringStreaming) [relocatedWidgetDict setObject:widget forKey:@(widget.sequence)];
|
||||
OnScreenWidgetView* widget = [OnScreenWidgetView widgetForKey:newButtonState.sequence];
|
||||
if(widget.isFolder)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// NSLog(@"relocatedWidgetDict.allKeys.count %d, %f", relocatedWidgetDict.allKeys.count, CACurrentMediaTime());
|
||||
|
||||
if(relocatedWidgetDict.allKeys.count == 0) return;
|
||||
NSMutableSet* relocatedWidgetSequences = [NSMutableSet set];
|
||||
bool hasFolderStateChanged = false;
|
||||
for(OnScreenWidgetView* widget in [OnScreenWidgetView.mapping allValues]){
|
||||
if(widget.relocatedDuringStreaming) [relocatedWidgetSequences addObject:@(widget.sequence)];
|
||||
if(!hasFolderStateChanged) hasFolderStateChanged = widget.folded != widget.persistedFolded;
|
||||
}
|
||||
|
||||
if(relocatedWidgetSequences.count == 0 && !hasFolderStateChanged) return;
|
||||
NSLog(@"relocatedWidgetSequences.count %lu, hasFolderStateChanged %d %F", relocatedWidgetSequences.count, hasFolderStateChanged, CACurrentMediaTime());
|
||||
|
||||
oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
|
||||
OSCProfile *newProfile = [oscProfileMan getSelectedProfile];
|
||||
@@ -514,14 +524,20 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
for (NSInteger i = 0; i < newProfile.buttonStatesEncoded.count; i++) {
|
||||
NSData* buttonStateEncoded = newProfile.buttonStatesEncoded[i];
|
||||
OnScreenButtonState *newButtonState = [oscProfileMan unarchiveButtonStateEncoded:buttonStateEncoded];
|
||||
if([relocatedWidgetDict.allKeys containsObject:@(newButtonState.sequence)]){
|
||||
OnScreenWidgetView* widget = [relocatedWidgetDict objectForKey:@(newButtonState.sequence)];
|
||||
OnScreenWidgetView* widget = [OnScreenWidgetView.mapping objectForKey:@(newButtonState.sequence)];
|
||||
NSData *newButtonStateEncoded;
|
||||
if([relocatedWidgetSequences containsObject:@(widget.sequence)]
|
||||
|| widget.isFolder){
|
||||
newButtonState.position = [oscProfileMan normalizeWidgetPosition:widget.storedCenter];
|
||||
NSData *newButtonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:newButtonState requiringSecureCoding:YES error:nil];
|
||||
newButtonState.folded = widget.folded;
|
||||
newButtonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:newButtonState requiringSecureCoding:YES error:nil];
|
||||
newProfile.buttonStatesEncoded[i] = newButtonStateEncoded;
|
||||
}
|
||||
}
|
||||
|
||||
newProfile.unfoldedExclusiveFolderSequence = OnScreenWidgetView.unfoldedExclusiveFolderSequence;
|
||||
newProfile.postExclusiveUnfoldedSequences = OnScreenWidgetView.postExclusiveUnfoldedSequences;
|
||||
|
||||
[oscProfileMan replaceSelectedProfileWith:newProfile overwriteDefault:NO];
|
||||
}
|
||||
|
||||
@@ -565,6 +581,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
widgetView.sequenceSet = buttonState.sequenceSet;
|
||||
widgetView.parentSequence = buttonState.parentSequence;
|
||||
widgetView.folded = buttonState.folded;
|
||||
widgetView.persistedFolded = buttonState.folded;
|
||||
widgetView.revealMode = buttonState.revealMode;
|
||||
|
||||
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
|
||||
@@ -643,6 +660,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
}
|
||||
}
|
||||
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = oscProfile.unfoldedExclusiveFolderSequence;
|
||||
[OnScreenWidgetView setPostExclusiveUnfoldeds:oscProfile.postExclusiveUnfoldedSequences];
|
||||
[OnScreenWidgetView restoreFoldedStates];
|
||||
|
||||
NSLog(@"hasLegacyWidget %d %f", hasLegacyWidget, CACurrentMediaTime());
|
||||
|
||||
@@ -208,6 +208,8 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
|
||||
// if(widget.isFolder) [OnScreenWidgetView setWithFolded:widget.folded for:widget];
|
||||
}
|
||||
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = oscProfile.unfoldedExclusiveFolderSequence;
|
||||
[OnScreenWidgetView setPostExclusiveUnfoldeds:oscProfile.postExclusiveUnfoldedSequences];
|
||||
[OnScreenWidgetView restoreFoldedStates];
|
||||
NSLog(@"reloadOnScreenWidgets hasLegacyWidget %d %f", hasLegacyWidget, CACurrentMediaTime());
|
||||
if(hasLegacyWidget) [self reloadLegacyOnScreenControls:oscProfile];
|
||||
|
||||
@@ -761,7 +761,7 @@
|
||||
}
|
||||
|
||||
- (void)openWidgetLayoutTool{
|
||||
[_streamView saveRelocatedWidgetViews];
|
||||
[_streamView saveStreamViewWidgetChanges];
|
||||
_streamView.widgetToolOpened = true;
|
||||
[self->_streamView disableOnScreenControls];
|
||||
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
|
||||
@@ -772,7 +772,7 @@
|
||||
}
|
||||
|
||||
- (void)openWidgetProfileTableWithPickProfile:(BOOL)pickProfile{
|
||||
[_streamView saveRelocatedWidgetViews];
|
||||
[_streamView saveStreamViewWidgetChanges];
|
||||
_streamView.widgetToolOpened = true;
|
||||
[self->_streamView disableOnScreenControls];
|
||||
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
|
||||
@@ -1066,7 +1066,7 @@
|
||||
//sleep(1);
|
||||
appDidEnterBackgroundWithoutPip = true;
|
||||
|
||||
[_streamView saveRelocatedWidgetViews];
|
||||
[_streamView saveStreamViewWidgetChanges];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#endif
|
||||
@@ -1150,7 +1150,7 @@
|
||||
|
||||
- (void)expandSettingsView{
|
||||
self.mainFrameViewcontroller.settingsExpandedInStreamView = true; //notify mainFrameViewContorller that this is a setting expansion in stream view, some settings shall be disabled.
|
||||
[_streamView saveRelocatedWidgetViews];
|
||||
[_streamView saveStreamViewWidgetChanges];
|
||||
[self.mainFrameViewcontroller expandSettingsView];
|
||||
}
|
||||
|
||||
@@ -1675,7 +1675,7 @@
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
[self->_streamView saveRelocatedWidgetViews];
|
||||
[self->_streamView saveStreamViewWidgetChanges];
|
||||
|
||||
if (_isRestoringFromPiP) {
|
||||
Log(LOG_I, @"View size changed during PiP restore, skipping redundant reconfiguration.");
|
||||
|
||||
Reference in New Issue
Block a user