onscreen keyboard profile test
This commit is contained in:
1 parent
d90bf747fc
commit
fd768db70b
14 files changed
+275
-63
No files matched your search
@@ -669,7 +669,7 @@ ICAgICAgICAgICAgICA
|
|||||||
<view alpha="0.75" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZU-G0-fgM" userLabel="Toolbar Root View" customClass="ToolBarContainerView">
|
<view alpha="0.75" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZU-G0-fgM" userLabel="Toolbar Root View" customClass="ToolBarContainerView">
|
||||||
<rect key="frame" x="0.0" y="24" width="834" height="50"/>
|
<rect key="frame" x="0.0" y="24" width="834" height="50"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="70" translatesAutoresizingMaskIntoConstraints="NO" id="YLK-IE-ajS">
|
<stackView autoresizesSubviews="NO" opaque="NO" contentMode="scaleToFill" spacing="70" translatesAutoresizingMaskIntoConstraints="NO" id="YLK-IE-ajS">
|
||||||
<rect key="frame" x="152" y="0.0" width="530" height="50"/>
|
<rect key="frame" x="152" y="0.0" width="530" height="50"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qJs-n8-eV7" userLabel="Trash">
|
<button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qJs-n8-eV7" userLabel="Trash">
|
||||||
@@ -685,7 +685,7 @@ ICAgICAgICAgICAgICA
|
|||||||
<action selector="trashCanTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="6s3-Wc-6us"/>
|
<action selector="trashCanTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="6s3-Wc-6us"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="F7X-l4-cl3" userLabel="Undo">
|
<button autoresizesSubviews="NO" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="F7X-l4-cl3" userLabel="Undo">
|
||||||
<rect key="frame" x="120" y="0.0" width="50" height="50"/>
|
<rect key="frame" x="120" y="0.0" width="50" height="50"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="50" id="9OY-7z-dfc"/>
|
<constraint firstAttribute="width" constant="50" id="9OY-7z-dfc"/>
|
||||||
@@ -700,25 +700,27 @@ ICAgICAgICAgICAgICA
|
|||||||
</button>
|
</button>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EPu-dl-Tv8">
|
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EPu-dl-Tv8">
|
||||||
<rect key="frame" x="240" y="0.0" width="50" height="50"/>
|
<rect key="frame" x="240" y="0.0" width="50" height="50"/>
|
||||||
|
<subviews>
|
||||||
|
<button autoresizesSubviews="NO" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uda-zt-xrG" userLabel="Save">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="50" id="TEB-dw-YGo"/>
|
||||||
|
<constraint firstAttribute="height" constant="50" id="z50-CE-W0m"/>
|
||||||
|
</constraints>
|
||||||
|
<color key="tintColor" red="0.6705882353" green="0.61568627450000002" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
|
<state key="normal" image="SquareAndArrowDown"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="saveTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="bUV-Ja-Htd"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="50" id="G6V-W8-Ech"/>
|
<constraint firstAttribute="width" constant="50" id="G6V-W8-Ech"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</stackView>
|
</stackView>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uda-zt-xrG" userLabel="Save">
|
|
||||||
<rect key="frame" x="360" y="0.0" width="50" height="50"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="50" id="TEB-dw-YGo"/>
|
|
||||||
<constraint firstAttribute="height" constant="50" id="z50-CE-W0m"/>
|
|
||||||
</constraints>
|
|
||||||
<color key="tintColor" red="0.6705882353" green="0.61568627450000002" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
|
||||||
<state key="normal" image="SquareAndArrowDown"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="saveTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="bUV-Ja-Htd"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1EQ-sU-0bc" userLabel="Load">
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1EQ-sU-0bc" userLabel="Load">
|
||||||
<rect key="frame" x="480" y="0.0" width="50" height="50"/>
|
<rect key="frame" x="360" y="0.0" width="50" height="50"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="50" id="0Up-sg-4RI"/>
|
<constraint firstAttribute="height" constant="50" id="0Up-sg-4RI"/>
|
||||||
<constraint firstAttribute="width" constant="50" id="EBU-5l-gEs"/>
|
<constraint firstAttribute="width" constant="50" id="EBU-5l-gEs"/>
|
||||||
@@ -730,6 +732,20 @@ ICAgICAgICAgICAgICA
|
|||||||
<action selector="loadTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="84k-1w-sd2"/>
|
<action selector="loadTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="84k-1w-sd2"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bMH-Yb-sb6" userLabel="Add">
|
||||||
|
<rect key="frame" x="480" y="0.0" width="50" height="50"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="50" id="hGO-XD-eLY"/>
|
||||||
|
<constraint firstAttribute="width" constant="50" id="rWU-3E-f4u"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="53"/>
|
||||||
|
<color key="tintColor" red="0.6705882353" green="0.61568627450000002" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
|
<state key="normal" title="+"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="addTapped:" destination="xSZ-i2-Jts" eventType="touchUpInside" id="7dP-Lk-Mdj"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="EPu-dl-Tv8" firstAttribute="centerY" secondItem="YLK-IE-ajS" secondAttribute="centerY" id="9Du-ZM-F8k"/>
|
<constraint firstItem="EPu-dl-Tv8" firstAttribute="centerY" secondItem="YLK-IE-ajS" secondAttribute="centerY" id="9Du-ZM-F8k"/>
|
||||||
@@ -797,6 +813,8 @@ ICAgICAgICAgICAgICA
|
|||||||
<constraint firstItem="fZU-G0-fgM" firstAttribute="top" secondItem="O1f-cu-KVo" secondAttribute="bottom" id="Ppb-J1-lXg" userLabel="Toolbar Top Constraint iPad"/>
|
<constraint firstItem="fZU-G0-fgM" firstAttribute="top" secondItem="O1f-cu-KVo" secondAttribute="bottom" id="Ppb-J1-lXg" userLabel="Toolbar Top Constraint iPad"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<toolbarItems/>
|
||||||
|
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="chevronImageView" destination="iVZ-Fd-dY7" id="403-Nj-wRx"/>
|
<outlet property="chevronImageView" destination="iVZ-Fd-dY7" id="403-Nj-wRx"/>
|
||||||
<outlet property="chevronView" destination="hKp-ds-86I" id="Og9-aT-zNH"/>
|
<outlet property="chevronView" destination="hKp-ds-86I" id="Og9-aT-zNH"/>
|
||||||
|
|||||||
@@ -162,7 +162,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* save the name, position, and visibility of button being touched in array in case user wants to undo the change later */
|
/* save the name, position, and visibility of button being touched in array in case user wants to undo the change later */
|
||||||
OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name isKeyboardButton:NO isHidden:layerBeingDragged.isHidden andPosition:layerBeingDragged.position];
|
OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name buttonType:GameControllerButton andPosition:layerBeingDragged.position];
|
||||||
|
// add hidden attr here
|
||||||
|
onScreenButtonState.isHidden = layerBeingDragged.isHidden;
|
||||||
|
|
||||||
[layoutChanges addObject:onScreenButtonState];
|
[layoutChanges addObject:onScreenButtonState];
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"OSCLayoutChanged" object:self]; // lets the view controller know whether to fade the undo button in or out depending on whether there are any further OSC layout changes the user is allowed to undo
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"OSCLayoutChanged" object:self]; // lets the view controller know whether to fade the undo button in or out depending on whether there are any further OSC layout changes the user is allowed to undo
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
|
|
||||||
+ (OSCProfilesManager *) sharedManager;
|
+ (OSCProfilesManager *) sharedManager;
|
||||||
|
+ (void) setOnScreenKeyViewsDict:(NSMutableDictionary* )dict;
|
||||||
|
|
||||||
#pragma mark - Getters
|
#pragma mark - Getters
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
- (void) saveProfileWithName:(NSString*)name andButtonLayers:(NSMutableArray *)buttonLayers;
|
- (void) saveProfileWithName:(NSString*)name andButtonLayers:(NSMutableArray *)buttonLayers;
|
||||||
|
|
||||||
- (bool) updateSelectedProfileSucceedWithButtonLayers:(NSMutableArray *)buttonLayers;
|
- (bool) updateSelectedProfile:(NSMutableArray *) oscButtonLayers;
|
||||||
/**
|
/**
|
||||||
* Delete current selected profile.
|
* Delete current selected profile.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,10 +7,13 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "OSCProfilesManager.h"
|
#import "OSCProfilesManager.h"
|
||||||
|
#import "OnScreenButtonState.h"
|
||||||
|
#import "Moonlight-Swift.h"
|
||||||
|
#import "LayoutOnScreenControlsViewController.h"
|
||||||
|
|
||||||
@implementation OSCProfilesManager
|
@implementation OSCProfilesManager
|
||||||
|
|
||||||
|
static NSMutableDictionary *onScreenKeyViewsDict;
|
||||||
|
|
||||||
#pragma mark - Initializer
|
#pragma mark - Initializer
|
||||||
|
|
||||||
@@ -27,6 +30,11 @@
|
|||||||
|
|
||||||
#pragma mark - Class Helper Methods
|
#pragma mark - Class Helper Methods
|
||||||
|
|
||||||
|
|
||||||
|
+ (void) setOnScreenKeyViewsDict:(NSMutableDictionary* )dict{
|
||||||
|
onScreenKeyViewsDict = dict;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the profile whose 'name' property has a value that is equal to the 'name' passed into the method
|
* Returns the profile whose 'name' property has a value that is equal to the 'name' passed into the method
|
||||||
*/
|
*/
|
||||||
@@ -94,7 +102,6 @@
|
|||||||
NSMutableArray *profiles = [self getAllProfiles];
|
NSMutableArray *profiles = [self getAllProfiles];
|
||||||
|
|
||||||
for (OSCProfile *profile in profiles) { // set all profiles' 'isSelected' property to NO since the new profile we're saving over the old profile with will be the 'selected' profile
|
for (OSCProfile *profile in profiles) { // set all profiles' 'isSelected' property to NO since the new profile we're saving over the old profile with will be the 'selected' profile
|
||||||
|
|
||||||
profile.isSelected = NO;
|
profile.isSelected = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +199,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (bool) updateSelectedProfileSucceedWithButtonLayers:(NSMutableArray *)buttonLayers {
|
- (bool) updateSelectedProfile:(NSMutableArray *) oscButtonLayers {
|
||||||
/* iterate through each OSC button the user sees on screen, create an 'OnScreenButtonState' object from each button, encode each object, and then add each object to an array */
|
/* iterate through each OSC button the user sees on screen, create an 'OnScreenButtonState' object from each button, encode each object, and then add each object to an array */
|
||||||
/*
|
/*
|
||||||
NSSet *validPositionButtonNames = [NSSet setWithObjects:
|
NSSet *validPositionButtonNames = [NSSet setWithObjects:
|
||||||
@@ -211,9 +218,12 @@
|
|||||||
@"startButton",
|
@"startButton",
|
||||||
nil]; */
|
nil]; */
|
||||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
||||||
for (CALayer *buttonLayer in buttonLayers) {
|
for (CALayer *oscButtonLayer in oscButtonLayers) {
|
||||||
|
|
||||||
|
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:GameControllerButton andPosition:oscButtonLayer.position];
|
||||||
|
// add hidden attr here
|
||||||
|
buttonState.isHidden = oscButtonLayer.isHidden;
|
||||||
|
|
||||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isKeyboardButton:NO isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
|
||||||
/* //-------------------------------------
|
/* //-------------------------------------
|
||||||
NSLog(@"buttonName to be saved: %@", buttonState.name);
|
NSLog(@"buttonName to be saved: %@", buttonState.name);
|
||||||
if([validPositionButtonNames containsObject:buttonState.name]) buttonState.hasValidPosition = true; // this is for setting up DZ for custom OSC buttons.
|
if([validPositionButtonNames containsObject:buttonState.name]) buttonState.hasValidPosition = true; // this is for setting up DZ for custom OSC buttons.
|
||||||
@@ -222,6 +232,19 @@
|
|||||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save keyboard button as buttonstate
|
||||||
|
[onScreenKeyViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { // this dict is passed from the layout tool VC, as a static obj in this class.
|
||||||
|
OnScreenKeyView *keyView = value;
|
||||||
|
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:keyView.keyString buttonType:KeyboardButton andPosition:keyView.frame.origin];
|
||||||
|
buttonState.alias = keyView.keyLabel;
|
||||||
|
buttonState.timestamp = keyView.timestamp;
|
||||||
|
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||||
|
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if([self getIndexOfSelectedProfile]==0) return false;
|
if([self getIndexOfSelectedProfile]==0) return false;
|
||||||
OSCProfile *newProfile = [[OSCProfile alloc] initWithName:[self getSelectedProfile].name
|
OSCProfile *newProfile = [[OSCProfile alloc] initWithName:[self getSelectedProfile].name
|
||||||
buttonStates:buttonStatesEncoded isSelected:YES]; // create a new 'OSCProfile'. Set the array of encoded button states created above to the 'buttonStates' property of the new profile, along with a 'name'. Set 'isSelected' argument to YES which will set this saved profile as the one that will show up in the game stream view
|
buttonStates:buttonStatesEncoded isSelected:YES]; // create a new 'OSCProfile'. Set the array of encoded button states created above to the 'buttonStates' property of the new profile, along with a 'name'. Set 'isSelected' argument to YES which will set this saved profile as the one that will show up in the game stream view
|
||||||
@@ -258,7 +281,9 @@
|
|||||||
nil]; */
|
nil]; */
|
||||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
||||||
for (CALayer *buttonLayer in buttonLayers) {
|
for (CALayer *buttonLayer in buttonLayers) {
|
||||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isKeyboardButton:NO isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name buttonType:GameControllerButton andPosition:buttonLayer.position];
|
||||||
|
// add hidden attr here
|
||||||
|
buttonState.isHidden = buttonLayer.isHidden;
|
||||||
/* //-------------------------------------
|
/* //-------------------------------------
|
||||||
NSLog(@"buttonName to be saved: %@", buttonState.name);
|
NSLog(@"buttonName to be saved: %@", buttonState.name);
|
||||||
if([validPositionButtonNames containsObject:buttonState.name]) buttonState.hasValidPosition = true; // this is for setting up DZ for custom OSC buttons.
|
if([validPositionButtonNames containsObject:buttonState.name]) buttonState.hasValidPosition = true; // this is for setting up DZ for custom OSC buttons.
|
||||||
|
|||||||
@@ -20,12 +20,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@interface OnScreenButtonState : NSObject <NSCoding, NSSecureCoding>
|
@interface OnScreenButtonState : NSObject <NSCoding, NSSecureCoding>
|
||||||
|
|
||||||
@property NSString *name;
|
@property NSString *name;
|
||||||
|
@property NSString *alias;
|
||||||
@property CGPoint position;
|
@property CGPoint position;
|
||||||
@property (nonatomic, assign) BOOL isHidden;
|
@property (nonatomic, assign) BOOL isHidden;
|
||||||
@property (nonatomic, assign) BOOL isKeyboardButton;
|
@property (nonatomic, assign) uint8_t buttonType;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval timestamp;
|
||||||
// @property (nonatomic, assign) BOOL hasValidPosition;
|
// @property (nonatomic, assign) BOOL hasValidPosition;
|
||||||
|
|
||||||
- (id) initWithButtonName:(NSString*)name isKeyboardButton:(BOOL)isKeyboardButton isHidden:(BOOL)isHidden andPosition:(CGPoint)position;
|
typedef NS_ENUM(NSInteger, OnScreenButtonType) {
|
||||||
|
GameControllerButton,
|
||||||
|
KeyboardButton
|
||||||
|
};
|
||||||
|
|
||||||
|
- (id) initWithButtonName:(NSString*)name buttonType:(uint8_t)buttonType andPosition:(CGPoint)position;
|
||||||
|
|
||||||
+ (BOOL) supportsSecureCoding;
|
+ (BOOL) supportsSecureCoding;
|
||||||
- (void) encodeWithCoder:(NSCoder*)encoder;
|
- (void) encodeWithCoder:(NSCoder*)encoder;
|
||||||
|
|||||||
@@ -10,12 +10,13 @@
|
|||||||
|
|
||||||
@implementation OnScreenButtonState
|
@implementation OnScreenButtonState
|
||||||
|
|
||||||
- (id) initWithButtonName:(NSString*)name isKeyboardButton:(BOOL)isKeyboardButton isHidden:(BOOL)isHidden andPosition:(CGPoint)position {
|
|
||||||
|
- (id) initWithButtonName:(NSString*)name buttonType:(uint8_t)buttonType andPosition:(CGPoint)position {
|
||||||
if ((self = [self init])) {
|
if ((self = [self init])) {
|
||||||
self.name = name;
|
self.name = name;
|
||||||
self.isHidden = isHidden;
|
//self.isHidden = isHidden;
|
||||||
self.position = position;
|
self.position = position;
|
||||||
self.isKeyboardButton = isKeyboardButton;
|
self.buttonType = buttonType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -27,19 +28,21 @@
|
|||||||
|
|
||||||
- (void) encodeWithCoder:(NSCoder*)encoder {
|
- (void) encodeWithCoder:(NSCoder*)encoder {
|
||||||
[encoder encodeObject:self.name forKey:@"name"];
|
[encoder encodeObject:self.name forKey:@"name"];
|
||||||
[encoder encodeBool:self.isKeyboardButton forKey:@"isKeyboardButton"];
|
[encoder encodeObject:self.alias forKey:@"alias"];
|
||||||
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
|
[encoder encodeDouble:self.timestamp forKey:@"timestamp"];
|
||||||
// [encoder encodeBool:self.hasValidPosition forKey:@"hasValidPosition"];
|
[encoder encodeInt:self.buttonType forKey:@"buttonType"];
|
||||||
[encoder encodeCGPoint:self.position forKey:@"position"];
|
[encoder encodeCGPoint:self.position forKey:@"position"];
|
||||||
|
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCoder:(NSCoder*)decoder {
|
- (id) initWithCoder:(NSCoder*)decoder {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
self.name = [decoder decodeObjectForKey:@"name"];
|
self.name = [decoder decodeObjectForKey:@"name"];
|
||||||
self.isKeyboardButton = [decoder decodeBoolForKey:@"isKeyboardButton"];
|
self.alias = [decoder decodeObjectForKey:@"alias"];
|
||||||
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
|
self.timestamp = [decoder decodeDoubleForKey:@"timestamp"];
|
||||||
// self.hasValidPosition = [decoder decodeBoolForKey:@"hasValidPosition"];
|
self.buttonType = [decoder decodeIntForKey:@"buttonType"];
|
||||||
self.position = [decoder decodeCGPointForKey:@"position"];
|
self.position = [decoder decodeCGPointForKey:@"position"];
|
||||||
|
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -272,7 +272,8 @@ static float L3_Y;
|
|||||||
NSLog(@"_activeCustomOscButtonPositionDict update: STARTOVER");
|
NSLog(@"_activeCustomOscButtonPositionDict update: STARTOVER");
|
||||||
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
|
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
|
||||||
OnScreenButtonState *buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
|
OnScreenButtonState *buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
|
||||||
if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] ){
|
|
||||||
|
if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] && (buttonState.buttonType == GameControllerButton || [profilesManager getIndexOfSelectedProfile] == 0 ) ){
|
||||||
[_activeCustomOscButtonPositionDict setObject:[NSValue valueWithCGPoint:buttonState.position] forKey:buttonState.name]; // we got a buttonname -> position dict here
|
[_activeCustomOscButtonPositionDict setObject:[NSValue valueWithCGPoint:buttonState.position] forKey:buttonState.name]; // we got a buttonname -> position dict here
|
||||||
NSLog(@"_activeCustomOscButtonPositionDict update, button name:%@, position: %f, %f", buttonState.name, buttonState.position.x, buttonState.position.y);
|
NSLog(@"_activeCustomOscButtonPositionDict update, button name:%@, position: %f, %f", buttonState.name, buttonState.position.x, buttonState.position.y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objc class OnScreenKeyView: UIView {
|
@objc class OnScreenKeyView: UIView {
|
||||||
@objc static var relocationMode: Bool = false
|
@objc static public var editMode: Bool = false
|
||||||
@objc var keyLabel: String
|
@objc static public var timestampOfButtonBeingDragged: TimeInterval = 0
|
||||||
@objc var keyString: String
|
@objc public var keyLabel: String
|
||||||
|
@objc public var keyString: String
|
||||||
|
@objc public var timestamp: TimeInterval
|
||||||
private let label: UILabel
|
private let label: UILabel
|
||||||
private let originalBackgroundColor: UIColor
|
private let originalBackgroundColor: UIColor
|
||||||
private var storedLocation: CGPoint = .zero
|
private var storedLocation: CGPoint = .zero
|
||||||
@@ -22,7 +25,7 @@ import UIKit
|
|||||||
self.keyLabel = keyLabel
|
self.keyLabel = keyLabel
|
||||||
self.label = UILabel()
|
self.label = UILabel()
|
||||||
self.originalBackgroundColor = UIColor(white: 0.2, alpha: 0.7)
|
self.originalBackgroundColor = UIColor(white: 0.2, alpha: 0.7)
|
||||||
|
self.timestamp = 0;
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
setupView()
|
setupView()
|
||||||
}
|
}
|
||||||
@@ -39,16 +42,17 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc public func enableRelocationMode(enabled: Bool){
|
@objc public func enableRelocationMode(enabled: Bool){
|
||||||
OnScreenKeyView.relocationMode = enabled
|
OnScreenKeyView.editMode = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupView() {
|
private func setupView() {
|
||||||
label.text = self.keyLabel
|
label.text = self.keyLabel
|
||||||
label.font = UIFont.systemFont(ofSize: 30)
|
label.font = UIFont.systemFont(ofSize: 22)
|
||||||
label.textColor = UIColor(white: 1.0, alpha: 0.8)
|
label.textColor = UIColor(white: 1.0, alpha: 0.8)
|
||||||
label.shadowColor = .black
|
label.shadowColor = .black
|
||||||
label.translatesAutoresizingMaskIntoConstraints = false
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
self.translatesAutoresizingMaskIntoConstraints = true // this is mandatory to prevent unexpected key view location change
|
||||||
self.layer.borderColor = UIColor.black.cgColor
|
self.layer.borderColor = UIColor.black.cgColor
|
||||||
self.layer.borderWidth = 2
|
self.layer.borderWidth = 2
|
||||||
self.layer.cornerRadius = 8
|
self.layer.cornerRadius = 8
|
||||||
@@ -64,8 +68,10 @@ import UIKit
|
|||||||
])
|
])
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.088),
|
//self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.088),
|
||||||
self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height * 0.1),
|
//self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height * 0.1),
|
||||||
|
self.widthAnchor.constraint(equalToConstant: 85),
|
||||||
|
self.heightAnchor.constraint(equalToConstant: 65),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +79,13 @@ import UIKit
|
|||||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
super.touchesBegan(touches, with: event)
|
super.touchesBegan(touches, with: event)
|
||||||
//self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 0.7)
|
//self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 0.7)
|
||||||
self.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.7)
|
|
||||||
|
|
||||||
|
|
||||||
if !OnScreenKeyView.relocationMode { LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_DOWN), 0) }
|
if !OnScreenKeyView.editMode {
|
||||||
|
self.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.7)
|
||||||
|
LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_DOWN), 0)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Store the initial center point of the key
|
|
||||||
if let touch = touches.first {
|
if let touch = touches.first {
|
||||||
let touchLocation = touch.location(in: superview)
|
let touchLocation = touch.location(in: superview)
|
||||||
storedLocation = touchLocation
|
storedLocation = touchLocation
|
||||||
@@ -89,15 +96,17 @@ import UIKit
|
|||||||
|
|
||||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
super.touchesMoved(touches, with: event)
|
super.touchesMoved(touches, with: event)
|
||||||
|
OnScreenKeyView.timestampOfButtonBeingDragged = self.timestamp
|
||||||
|
|
||||||
// Move the KeyView based on touch movement in relocation mode
|
// Move the KeyView based on touch movement in relocation mode
|
||||||
if OnScreenKeyView.relocationMode {
|
if OnScreenKeyView.editMode {
|
||||||
if let touch = touches.first {
|
if let touch = touches.first {
|
||||||
let currentLocation = touch.location(in: superview)
|
let currentLocation = touch.location(in: superview)
|
||||||
let offsetX = currentLocation.x - storedLocation.x
|
let offsetX = currentLocation.x - storedLocation.x
|
||||||
let offsetY = currentLocation.y - storedLocation.y
|
let offsetY = currentLocation.y - storedLocation.y
|
||||||
|
|
||||||
center = CGPoint(x: center.x + offsetX, y: center.y + offsetY)
|
center = CGPoint(x: center.x + offsetX, y: center.y + offsetY)
|
||||||
|
//NSLog("x coord: %f, y coord: %f", self.frame.origin.x, self.frame.origin.y)
|
||||||
storedLocation = currentLocation // Update initial center for next movement
|
storedLocation = currentLocation // Update initial center for next movement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +115,30 @@ import UIKit
|
|||||||
|
|
||||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
super.touchesEnded(touches, with: event)
|
super.touchesEnded(touches, with: event)
|
||||||
|
if !OnScreenKeyView.editMode {
|
||||||
|
LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_UP), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
self.backgroundColor = self.originalBackgroundColor
|
self.backgroundColor = self.originalBackgroundColor
|
||||||
if !OnScreenKeyView.relocationMode { LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_UP), 0) }
|
|
||||||
|
guard let superview = superview else { return }
|
||||||
|
|
||||||
|
// Deactivate existing constraints if necessary
|
||||||
|
NSLayoutConstraint.deactivate(self.constraints)
|
||||||
|
|
||||||
|
// Add new constraints based on the current center position
|
||||||
|
translatesAutoresizingMaskIntoConstraints = true
|
||||||
|
|
||||||
|
// Create new constraints
|
||||||
|
let newLeadingConstraint = self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: self.frame.origin.x)
|
||||||
|
let newTopConstraint = self.topAnchor.constraint(equalTo: superview.topAnchor, constant: self.frame.origin.y)
|
||||||
|
|
||||||
|
// Activate the new location constraints
|
||||||
|
NSLayoutConstraint.activate([newLeadingConstraint, newTopConstraint])
|
||||||
|
|
||||||
|
// Trigger layout update
|
||||||
|
superview.layoutIfNeeded()
|
||||||
|
|
||||||
|
setupView(); //re-setup keyview style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#import "ToolBarContainerView.h"
|
#import "ToolBarContainerView.h"
|
||||||
#import "OSCProfilesManager.h"
|
#import "OSCProfilesManager.h"
|
||||||
#import "OSCProfilesTableViewController.h"
|
#import "OSCProfilesTableViewController.h"
|
||||||
|
#import "Moonlight-Swift.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@@ -19,8 +20,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
@interface LayoutOnScreenControlsViewController : UIViewController
|
@interface LayoutOnScreenControlsViewController : UIViewController
|
||||||
- (void)profileRefresh;
|
- (void)profileRefresh;
|
||||||
|
- (void)reloadOnScreenKeyboardButtons;
|
||||||
|
|
||||||
@property LayoutOnScreenControls *layoutOSC; // object that contains a view which contains the on screen controller buttons that allows the user to drag and positions each button on the screen using touch
|
@property LayoutOnScreenControls *layoutOSC; // object that contains a view which contains the on screen controller buttons that allows the user to drag and positions each button on the screen using touch
|
||||||
|
@property (nonatomic) NSMutableDictionary* onScreenKeyViewsDict;
|
||||||
|
|
||||||
@property int OSCSegmentSelected;
|
@property int OSCSegmentSelected;
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *trashCanButton;
|
@property (weak, nonatomic) IBOutlet UIButton *trashCanButton;
|
||||||
|
|||||||
+114
-9
@@ -12,6 +12,7 @@
|
|||||||
#import "OnScreenControls.h"
|
#import "OnScreenControls.h"
|
||||||
#import "OSCProfilesManager.h"
|
#import "OSCProfilesManager.h"
|
||||||
#import "LocalizationHelper.h"
|
#import "LocalizationHelper.h"
|
||||||
|
#import "Moonlight-Swift.h"
|
||||||
|
|
||||||
@interface LayoutOnScreenControlsViewController ()
|
@interface LayoutOnScreenControlsViewController ()
|
||||||
|
|
||||||
@@ -34,14 +35,59 @@
|
|||||||
|
|
||||||
|
|
||||||
- (void) viewWillDisappear:(BOOL)animated{
|
- (void) viewWillDisappear:(BOOL)animated{
|
||||||
|
OnScreenKeyView.editMode = false;
|
||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) reloadOnScreenKeyboardButtons {
|
||||||
|
/*
|
||||||
|
[self.onScreenKeyViewsDict enumerateKeysAndObjectsUsingBlock:^(id timeIntervalKey, id keyView, BOOL *stop) {
|
||||||
|
[keyView removeFromSuperview];
|
||||||
|
}];*/
|
||||||
|
|
||||||
|
for (UIView *subview in self.view.subviews) {
|
||||||
|
// 检查子视图是否是特定类型的实例
|
||||||
|
if ([subview isKindOfClass:[OnScreenKeyView class]]) {
|
||||||
|
// 如果是,就添加到将要被移除的数组中
|
||||||
|
[subview removeFromSuperview];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.onScreenKeyViewsDict removeAllObjects];
|
||||||
|
|
||||||
|
NSLog(@"reload os Key here");
|
||||||
|
|
||||||
|
// _activeCustomOscButtonPositionDict will be updated every time when the osc profile is reloaded
|
||||||
|
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
|
||||||
|
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
|
||||||
|
OnScreenButtonState* buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
|
||||||
|
if(buttonState.buttonType == KeyboardButton){
|
||||||
|
OnScreenKeyView* keyView = [[OnScreenKeyView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct keyView
|
||||||
|
keyView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
|
||||||
|
keyView.timestamp = buttonState.timestamp; // will be set as key in in the dict.
|
||||||
|
// Add the KeyView to the view controller's view
|
||||||
|
[self.view addSubview:keyView];
|
||||||
|
[keyView setKeyLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
|
||||||
|
|
||||||
|
[self.onScreenKeyViewsDict setObject:keyView forKey:@(keyView.timestamp)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
/*
|
||||||
|
[self.onScreenKeyViewsDict enumerateKeysAndObjectsUsingBlock:^(id timeIntervalKey, id keyView, BOOL *stop) {
|
||||||
|
[self.view addSubview:keyView];
|
||||||
|
}];*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) viewDidLoad {
|
- (void) viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
profilesManager = [OSCProfilesManager sharedManager];
|
profilesManager = [OSCProfilesManager sharedManager];
|
||||||
|
self.onScreenKeyViewsDict = [[NSMutableDictionary alloc] init]; // will be revised to read persisted data , somewhere else
|
||||||
|
[OSCProfilesManager setOnScreenKeyViewsDict:self.onScreenKeyViewsDict]; // pass the keyboard button dict to profiles manager
|
||||||
|
|
||||||
isToolbarHidden = NO; // keeps track if the toolbar is hidden up above the screen so that we know whether to hide or show it when the user taps the toolbar's hide/show button
|
isToolbarHidden = NO; // keeps track if the toolbar is hidden up above the screen so that we know whether to hide or show it when the user taps the toolbar's hide/show button
|
||||||
|
|
||||||
@@ -80,6 +126,14 @@
|
|||||||
name:@"OscLayoutTableViewCloseNotification"
|
name:@"OscLayoutTableViewCloseNotification"
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(reloadOnScreenKeyboardButtons)
|
||||||
|
name:@"OscLayoutProfileSelctedInTableView" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
|
||||||
|
object:nil];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OSCLayoutChanged) name:@"OSCLayoutChanged" object:nil]; // used to notifiy this view controller that the user made a change to the OSC layout so that the VC can either fade in or out its 'Undo button' which will signify to the user whether there are any OSC layout changes to undo
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OSCLayoutChanged) name:@"OSCLayoutChanged" object:nil]; // used to notifiy this view controller that the user made a change to the OSC layout so that the VC can either fade in or out its 'Undo button' which will signify to the user whether there are any OSC layout changes to undo
|
||||||
|
|
||||||
/* This will animate the toolbar with a subtle up and down motion intended to telegraph to the user that they can hide the toolbar if they wish*/
|
/* This will animate the toolbar with a subtle up and down motion intended to telegraph to the user that they can hide the toolbar if they wish*/
|
||||||
@@ -108,7 +162,10 @@
|
|||||||
[self profileRefresh];
|
[self profileRefresh];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- (void) viewDidAppear:(BOOL)animated {
|
- (void) viewDidAppear:(BOOL)animated {
|
||||||
|
OnScreenKeyView.editMode = true;
|
||||||
[super viewWillAppear:animated];
|
[super viewWillAppear:animated];
|
||||||
[self profileRefresh];
|
[self profileRefresh];
|
||||||
}
|
}
|
||||||
@@ -224,10 +281,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction) addTapped:(id)sender{
|
||||||
|
OnScreenKeyView* keyView = [[OnScreenKeyView alloc] initWithKeyString:@"ALT" keyLabel:@"test"];
|
||||||
|
keyView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
|
||||||
|
|
||||||
|
keyView.timestamp = CACurrentMediaTime(); // will be set as key in in the dict.
|
||||||
|
[self.onScreenKeyViewsDict setObject:keyView forKey:@(keyView.timestamp)];
|
||||||
|
// Add the KeyView to the view controller's view
|
||||||
|
[self.view addSubview:keyView];
|
||||||
|
[keyView setKeyLocationWithXOffset:50 yOffset:50];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* show pop up notification that lets users choose to save the current OSC layout configuration as a profile they can load when they want. User can also choose to cancel out of this pop up */
|
/* show pop up notification that lets users choose to save the current OSC layout configuration as a profile they can load when they want. User can also choose to cancel out of this pop up */
|
||||||
- (IBAction) saveTapped:(id)sender {
|
- (IBAction) saveTapped:(id)sender {
|
||||||
|
|
||||||
if([self->profilesManager updateSelectedProfileSucceedWithButtonLayers:self.layoutOSC.OSCButtonLayers]){
|
if([self->profilesManager updateSelectedProfile:self.layoutOSC.OSCButtonLayers]){
|
||||||
UIAlertController * savedAlertController = [UIAlertController alertControllerWithTitle: [NSString stringWithFormat:@""] message: [LocalizationHelper localizedStringForKey:@"Current profile updated successfully"] preferredStyle:UIAlertControllerStyleAlert];
|
UIAlertController * savedAlertController = [UIAlertController alertControllerWithTitle: [NSString stringWithFormat:@""] message: [LocalizationHelper localizedStringForKey:@"Current profile updated successfully"] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
[savedAlertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
[savedAlertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
}]];
|
}]];
|
||||||
@@ -298,17 +368,17 @@
|
|||||||
self->_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"];
|
self->_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"];
|
||||||
|
|
||||||
//this part is just for registration, will not be immediately executed.
|
//this part is just for registration, will not be immediately executed.
|
||||||
self->_oscProfilesTableViewController.didDismissOSCProfilesTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC profile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
self->_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC profile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
||||||
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
||||||
[self addInnerAnalogSticksToOuterAnalogLayers];
|
[self addInnerAnalogSticksToOuterAnalogLayers];
|
||||||
[self.layoutOSC.layoutChanges removeAllObjects]; // since a new OSC profile is being loaded, this will remove all previous layout changes made from the array
|
[self.layoutOSC.layoutChanges removeAllObjects]; // since a new OSC profile is being loaded, this will remove all previous layout changes made from the array
|
||||||
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
||||||
self->_oscProfilesTableViewController.currentOSCButtonLayers = self.layoutOSC.OSCButtonLayers; //pass updated OSCLayout to OSCProfileTableView again
|
self->_oscProfilesTableViewController.currentOSCButtonLayers = self.layoutOSC.OSCButtonLayers; //pass updated OSCLayout to OSCProfileTableView again
|
||||||
|
//[self reloadOnScreenKeyboardButtons];
|
||||||
};
|
};
|
||||||
|
|
||||||
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
|
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
|
||||||
|
[self reloadOnScreenKeyboardButtons];
|
||||||
|
|
||||||
|
|
||||||
// [self presentViewController:vc animated:YES completion:nil];
|
// [self presentViewController:vc animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
@@ -327,7 +397,7 @@
|
|||||||
|
|
||||||
_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"] ;
|
_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"] ;
|
||||||
|
|
||||||
_oscProfilesTableViewController.didDismissOSCProfilesTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC ofile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC ofile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
||||||
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
||||||
|
|
||||||
[self addInnerAnalogSticksToOuterAnalogLayers];
|
[self addInnerAnalogSticksToOuterAnalogLayers];
|
||||||
@@ -363,8 +433,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
[self.layoutOSC touchesMoved:touches withEvent:event];
|
|
||||||
|
|
||||||
|
// -------- for OSC buttons
|
||||||
|
[self.layoutOSC touchesMoved:touches withEvent:event];
|
||||||
if ([self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged
|
if ([self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged
|
||||||
hoveringOverButton:trashCanButton]) { // check if user is dragging around a button and hovering it over the trash can button
|
hoveringOverButton:trashCanButton]) { // check if user is dragging around a button and hovering it over the trash can button
|
||||||
trashCanButton.tintColor = [UIColor redColor];
|
trashCanButton.tintColor = [UIColor redColor];
|
||||||
@@ -372,11 +443,44 @@
|
|||||||
else {
|
else {
|
||||||
trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------- for keyboard Buttons
|
||||||
|
UITouch *touch = [touches anyObject]; // Get the first touch in the set
|
||||||
|
if([self touchWithinTashcanButton:touch]){
|
||||||
|
trashCanButton.tintColor = [UIColor redColor];
|
||||||
|
}
|
||||||
|
else trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)touchWithinTashcanButton:(UITouch* )touch {
|
||||||
|
CGPoint locationInView = [touch locationInView:self.view];
|
||||||
|
|
||||||
|
// Convert the location to the button's coordinate system
|
||||||
|
CGPoint locationInButton = [self.view convertPoint:locationInView toView:trashCanButton];
|
||||||
|
bool ret = CGRectContainsPoint(trashCanButton.bounds, locationInButton);
|
||||||
|
NSLog(@"within button: %d", ret);
|
||||||
|
// Check if the location is within the button's bounds
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
|
||||||
|
// removing keyboard buttons objs
|
||||||
|
UITouch *touch = [touches anyObject]; // Get the first touch in the set
|
||||||
|
if([self touchWithinTashcanButton:touch]){
|
||||||
|
[self.onScreenKeyViewsDict[@(OnScreenKeyView.timestampOfButtonBeingDragged)] removeFromSuperview];
|
||||||
|
[self.onScreenKeyViewsDict removeObjectForKey:@(OnScreenKeyView.timestampOfButtonBeingDragged)];
|
||||||
|
OnScreenKeyView.timestampOfButtonBeingDragged = 0; //reset thie timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//removing OSC buttons
|
||||||
if (self.layoutOSC.layerBeingDragged != nil &&
|
if (self.layoutOSC.layerBeingDragged != nil &&
|
||||||
[self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged hoveringOverButton:trashCanButton]) { // check if user wants to throw OSC button into the trash can
|
[self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged hoveringOverButton:trashCanButton]) { // check if user wants to throw OSC button into the trash can
|
||||||
|
// here we're going to delete something
|
||||||
|
|
||||||
self.layoutOSC.layerBeingDragged.hidden = YES;
|
self.layoutOSC.layerBeingDragged.hidden = YES;
|
||||||
|
|
||||||
@@ -394,8 +498,6 @@
|
|||||||
if ([self.layoutOSC.layerBeingDragged.name isEqualToString:@"rightStickBackground"]) {
|
if ([self.layoutOSC.layerBeingDragged.name isEqualToString:@"rightStickBackground"]) {
|
||||||
self.layoutOSC._rightStick.hidden = YES;
|
self.layoutOSC._rightStick.hidden = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
|
||||||
}
|
}
|
||||||
[self.layoutOSC touchesEnded:touches withEvent:event];
|
[self.layoutOSC touchesEnded:touches withEvent:event];
|
||||||
|
|
||||||
@@ -407,6 +509,9 @@
|
|||||||
}]];
|
}]];
|
||||||
[self presentViewController:movedAlertController animated:YES completion:nil];
|
[self presentViewController:movedAlertController animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UITableView *tableView;
|
@property (weak, nonatomic) IBOutlet UITableView *tableView;
|
||||||
@property (nonatomic, copy) void (^didDismissOSCProfilesTVC)(void);
|
@property (nonatomic, copy) void (^needToUpdateOscLayoutTVC)(void);
|
||||||
@property (nonatomic, assign) NSMutableArray *currentOSCButtonLayers;
|
@property (nonatomic, assign) NSMutableArray *currentOSCButtonLayers;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const double NAV_BAR_HEIGHT = 50;
|
|||||||
|
|
||||||
@implementation OSCProfilesTableViewController {
|
@implementation OSCProfilesTableViewController {
|
||||||
OSCProfilesManager *profilesManager;
|
OSCProfilesManager *profilesManager;
|
||||||
LayoutOnScreenControlsViewController *parentLayoutOSCViewController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize tableView;
|
@synthesize tableView;
|
||||||
@@ -139,9 +138,11 @@ const double NAV_BAR_HEIGHT = 50;
|
|||||||
//[self dismissViewControllerAnimated:YES completion:nil];
|
//[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
//[selfparentLayoutOSCViewController]
|
//[selfparentLayoutOSCViewController]
|
||||||
[self.tableView reloadData]; // table view will be refreshed by calling reloadData
|
[self.tableView reloadData]; // table view will be refreshed by calling reloadData
|
||||||
if (self.didDismissOSCProfilesTVC) { // tells the presenting view controller to lay out the on screen buttons according to the selected profile's instructions
|
|
||||||
self.didDismissOSCProfilesTVC();
|
if (self.needToUpdateOscLayoutTVC) { // tells the presenting view controller to lay out the on screen buttons according to the selected profile's instructions
|
||||||
|
self.needToUpdateOscLayoutTVC();
|
||||||
}
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutProfileSelctedInTableView" object:self]; // notify other view that oscLayoutManager is closing
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction) deleteTapped:(id)sender{// delete can be executed simply by calling this 2 methods.
|
- (IBAction) deleteTapped:(id)sender{// delete can be executed simply by calling this 2 methods.
|
||||||
|
|||||||
@@ -179,8 +179,8 @@
|
|||||||
CGFloat spacing = 10.0;
|
CGFloat spacing = 10.0;
|
||||||
|
|
||||||
[keyView setKeyLocationWithXOffset:500 yOffset:(CGFloat)550];
|
[keyView setKeyLocationWithXOffset:500 yOffset:(CGFloat)550];
|
||||||
*/
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -385,6 +385,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bMH-Yb-sb6.normalTitle" : {
|
||||||
|
"comment" : "Class = \"UIButton\"; normalTitle = \"+\"; ObjectID = \"bMH-Yb-sb6\";",
|
||||||
|
"extractionState" : "extracted_with_value",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "new",
|
||||||
|
"value" : "+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"byH-Qz-Nbw.segmentTitles[0]" : {
|
"byH-Qz-Nbw.segmentTitles[0]" : {
|
||||||
"comment" : "Class = \"UISegmentedControl\"; byH-Qz-Nbw.segmentTitles[0] = \"No\"; ObjectID = \"byH-Qz-Nbw\";",
|
"comment" : "Class = \"UISegmentedControl\"; byH-Qz-Nbw.segmentTitles[0] = \"No\"; ObjectID = \"byH-Qz-Nbw\";",
|
||||||
"extractionState" : "extracted_with_value",
|
"extractionState" : "extracted_with_value",
|
||||||
|
|||||||
Reference in new issue
Block a user