From fc19e16e4f5e8a5e7077fbe4a2fe4931865821bc Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh Date: Thu, 22 Apr 2021 17:46:18 +0700 Subject: [PATCH] Custom controls implementation changes - Fallback to default control if custom control data size is over 100kb. - Implemented dynamic position. - Renamed folder from `customcontrols` to `controlmap` to match Android. --- Natives/JavaLauncher.c | 2 +- Natives/SurfaceViewController.m | 18 +++--- Natives/customcontrols/ControlButton.h | 1 - Natives/customcontrols/ControlButton.m | 90 +++++++++++++++++++++----- 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/Natives/JavaLauncher.c b/Natives/JavaLauncher.c index 70b82366..f1b3f234 100644 --- a/Natives/JavaLauncher.c +++ b/Natives/JavaLauncher.c @@ -109,7 +109,7 @@ int launchJVM(int argc, char *argv[]) { init_loadCustomEnv(); - mkdir("/var/mobile/Documents/.pojavlauncher/customcontrols", S_IRWXU | S_IRWXG | S_IRWXO); + mkdir("/var/mobile/Documents/.pojavlauncher/controlmap", S_IRWXU | S_IRWXG | S_IRWXO); chdir("/var/mobile/Documents/minecraft"); char classpath[10000]; diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index f7fc0cff..cb9b7392 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -130,12 +130,11 @@ int notchOffset; // Custom button // ADD_BUTTON(@"F1", f1, CGRectMake(5, 5, width, height)); - - - // Temporary custom controls + + // Temporary fallback controls BOOL cc_fallback = YES; - FILE *cc_file = fopen("/var/mobile/Documents/.pojavlauncher/customcontrols/default.json", "r"); + FILE *cc_file = fopen("/var/mobile/Documents/.pojavlauncher/controlmap/default.json", "r"); // 100kb (might not safe) char cc_data[102400]; @@ -147,12 +146,14 @@ int notchOffset; } NSError *cc_error; - if (!cc_file || !fread(cc_data, cc_size, 1, cc_file)) { - NSLog(@"Error: could not read \"default.json\", fallbacking to default control.\n%s", strerror(errno)); + if (cc_size > 102400) { + NSLog(@"Error: control data is too big (over 100kb)."); + fclose(cc_file); + } else if (!cc_file || !fread(cc_data, cc_size, 1, cc_file)) { + NSLog(@"Error: could not read \"default.json\", falling back to default control, error: %s", strerror(errno)); fclose(cc_file); } else { fclose(cc_file); - NSLog(@"%s", cc_data); NSData* cc_objc_data = [@(cc_data) dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:kNilOptions error:&cc_error]; if (cc_error != nil) { @@ -233,7 +234,8 @@ int notchOffset; [self setupGL]; } -- (BOOL)prefersHomeIndicatorAutoHidden { +- (BOOL)prefersHomeIndicatorAutoHidden +{ return YES; } diff --git a/Natives/customcontrols/ControlButton.h b/Natives/customcontrols/ControlButton.h index 02f40719..b01aefa2 100644 --- a/Natives/customcontrols/ControlButton.h +++ b/Natives/customcontrols/ControlButton.h @@ -9,7 +9,6 @@ */ @interface ControlButton : UIButton { - NSMutableDictionary* properties; } @property (nonatomic, retain) NSMutableDictionary* properties; diff --git a/Natives/customcontrols/ControlButton.m b/Natives/customcontrols/ControlButton.m index 17e4bb5d..c64d070e 100644 --- a/Natives/customcontrols/ControlButton.m +++ b/Natives/customcontrols/ControlButton.m @@ -1,5 +1,8 @@ #import "ControlButton.h" +#define INSERT_VALUE(KEY, VALUE) \ + string = [string stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"${%@}", @(KEY)] withString:VALUE]; + #define NUM2F(x) [(NSNumber *)x floatValue] @implementation ControlButton @@ -10,36 +13,26 @@ * will store the scaled values. * * TODO implement: - * - dynamicX - * - dynamicY - * - isDynamicBtn + * - isDynamicBtn (???) * - scaledAt * - (maybe more) */ - + + (id)initWithProperties:(NSMutableDictionary *)propArray { - float screenScale = (float) [[UIScreen mainScreen] scale]; - - float propX = NUM2F([propArray valueForKey:@"x"]) / screenScale; - float propY = NUM2F([propArray valueForKey:@"y"]) / screenScale; - float propW = NUM2F([propArray valueForKey:@"width"]) / screenScale; - float propH = NUM2F([propArray valueForKey:@"height"]) / screenScale; ControlButton *instance = [ControlButton buttonWithType:UIButtonTypeRoundedRect]; [instance setTitle:[propArray valueForKey:@"name"] forState:UIControlStateNormal]; - instance.frame = CGRectMake(propX, propY, propW, propH); instance.autoresizingMask = UIViewAutoresizingFlexibleWidth; - - instance.alpha = 1.0f - NUM2F([propArray valueForKey:@"transparency"]) / 100.0f; - instance.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.3f]; instance.tintColor = [UIColor whiteColor]; instance.properties = propArray; + [instance update]; + return instance; } + (id)initWithName:(NSString *)name keycode:(int)keycode rect:(CGRect)rect transparency:(float)transparency { - float screenScale = (float) [[UIScreen mainScreen] scale]; + float screenScale = (float) 2.0; //[[UIScreen mainScreen] scale]; NSMutableDictionary *properties = [[NSMutableDictionary alloc] init]; [properties setObject:name forKey:@"name"]; @@ -53,4 +46,71 @@ return [ControlButton initWithProperties:properties]; } +- (float)insertDynamicPos:(NSString*)string { + CGRect screenBounds = [[UIScreen mainScreen] bounds]; + CGFloat screenScale = 2.0; // [[UIScreen mainScreen] scale]; + UIEdgeInsets insets = [[[UIApplication sharedApplication] keyWindow] safeAreaInsets]; + + // width: offset the notch parts + int screenWidth = (int) roundf((screenBounds.size.width - insets.left - insets.right) * screenScale); + int screenHeight = (int) roundf(screenBounds.size.height * screenScale); + + float width = NUM2F([self.properties valueForKey:@"width"]); + float height = NUM2F([self.properties valueForKey:@"height"]); + + // Insert value to ${variable} + INSERT_VALUE("top", @"0"); + INSERT_VALUE("left", @"0"); + INSERT_VALUE("right", ([NSString stringWithFormat:@"%f", screenWidth - width])); + INSERT_VALUE("bottom", ([NSString stringWithFormat:@"%f", screenHeight - height])); + INSERT_VALUE("width", ([NSString stringWithFormat:@"%f", width])); + INSERT_VALUE("height", ([NSString stringWithFormat:@"%f", height])); + INSERT_VALUE("screen_width", ([NSString stringWithFormat:@"%d", screenWidth])); + INSERT_VALUE("screen_height", ([NSString stringWithFormat:@"%d", screenHeight])); + INSERT_VALUE("margin", ([NSString stringWithFormat:@"%f", 2.0 * screenScale])); // FIXME is this correct? + + NSLog(@"Final math: %@", string); + + // Calculate, because the dynamic position contains some math equations + NSExpression *expression = [NSExpression expressionWithFormat:string]; + return [[expression expressionValueWithObject:nil context:nil] floatValue]; +} + +- (void)update { + // net/kdt/pojavlaunch/customcontrols/ControlData.update() + + float screenScale = (float) 2.0; // [[UIScreen mainScreen] scale]; + UIEdgeInsets insets = [[[UIApplication sharedApplication] keyWindow] safeAreaInsets]; + + NSString *propDynamicX = (NSString *) [self.properties valueForKey:@"dynamicX"]; + NSString *propDynamicY = (NSString *) [self.properties valueForKey:@"dynamicY"]; + float propX = NUM2F([self.properties valueForKey:@"x"]); + float propY = NUM2F([self.properties valueForKey:@"y"]); + float propW = NUM2F([self.properties valueForKey:@"width"]); + float propH = NUM2F([self.properties valueForKey:@"height"]); + + // If dynamic position is null, set value to fixed position + if (propDynamicX == nil) { + propDynamicX = [NSString stringWithFormat:@"%f", propX]; + [self.properties setObject:propDynamicX forKey:@"dynamicX"]; + } if (propDynamicY == nil) { + propDynamicY = [NSString stringWithFormat:@"%f", propY]; + [self.properties setObject:propDynamicY forKey:@"dynamicY"]; + } + + // Calculate dynamic position + propX = [self insertDynamicPos:propDynamicX]; + propY = [self insertDynamicPos:propDynamicY]; + // Set back to fixed position +/* + [self.properties setObject:@(propX) forKey:@"x"]; + [self.properties setObject:@(propY) forKey:@"y"]; +*/ + + // Update other properties + self.frame = CGRectMake(propX / screenScale + insets.left, propY / screenScale, propW / screenScale, propH / screenScale); + self.alpha = 1.0f - NUM2F([properties valueForKey:@"transparency"]) / 100.0f; + self.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.3f]; +} + @end