From a86040d20c17e160d2b3c5c3d98afac18c5e37eb Mon Sep 17 00:00:00 2001 From: danomatika Date: Mon, 13 Nov 2023 23:41:23 +0100 Subject: [PATCH 1/9] whoops, fixed potential crash when loading tgl or bng due if atom line is < 19 in length --- src/gui/iem/Bang.m | 4 ++-- src/gui/iem/Toggle.m | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/iem/Bang.m b/src/gui/iem/Bang.m index 95b00476..a2cc8049 100644 --- a/src/gui/iem/Bang.m +++ b/src/gui/iem/Bang.m @@ -27,8 +27,8 @@ - (void)resumeFlash:(NSTimer *)timer; @implementation Bang - (id)initWithAtomLine:(NSArray *)line andGui:(Gui *)gui { - if(line.count < 18) { // sanity check - LogWarn(@"Bang: cannot create, atom line length < 18"); + if(line.count < 19) { // sanity check + LogWarn(@"Bang: cannot create, atom line length < 19"); return nil; } self = [super initWithAtomLine:line andGui:gui]; diff --git a/src/gui/iem/Toggle.m b/src/gui/iem/Toggle.m index 5c70f1b6..a8e87863 100644 --- a/src/gui/iem/Toggle.m +++ b/src/gui/iem/Toggle.m @@ -17,8 +17,8 @@ @implementation Toggle - (id)initWithAtomLine:(NSArray *)line andGui:(Gui *)gui { - if(line.count < 18) { // sanity check - LogWarn(@"Toggle: cannot create, atom line length < 18"); + if(line.count < 19) { // sanity check + LogWarn(@"Toggle: cannot create, atom line length < 19"); return nil; } self = [super initWithAtomLine:line andGui:gui]; @@ -47,7 +47,7 @@ - (id)initWithAtomLine:(NSArray *)line andGui:(Gui *)gui { self.fillColor = [IEMWidget colorFromAtomColor:line[14]]; self.controlColor = [IEMWidget colorFromAtomColor:line[15]]; self.label.textColor = [IEMWidget colorFromAtomColor:line[16]]; - + self.nonZeroValue = [line[18] floatValue]; if(self.inits) { self.value = [line[17] floatValue]; From 2cda234fc3cbcf54decf1fd217b3371806ed338b Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 00:14:22 +0100 Subject: [PATCH 2/9] fixed accel orientation when switching between rotated and non-rotated scenes (rjdj and scenes using accel orientation) --- src/PatchViewController.m | 12 +++--------- src/modules/Sensors.m | 1 - 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/PatchViewController.m b/src/PatchViewController.m index 588863d0..994fef65 100644 --- a/src/PatchViewController.m +++ b/src/PatchViewController.m @@ -150,15 +150,6 @@ - (void)viewDidLayoutSubviews { [self.view layoutSubviews]; } -- (void)viewWillTransitionToSize:(CGSize)size - withTransitionCoordinator:(id)coordinator { - [coordinator animateAlongsideTransition:^(id context) {} - completion:^(id context) { - self.sceneManager.currentOrientation = UIApplication.sharedApplication.statusBarOrientation; - }]; - [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; -} - // lock orientation based on scene's preferred orientation mask - (UIInterfaceOrientationMask)supportedInterfaceOrientations { if(self.sceneManager.scene && !self.sceneManager.isRotated) { @@ -364,6 +355,7 @@ - (void)updateOrientation { if((self.sceneManager.scene.preferredOrientations == UIInterfaceOrientationMaskAll) || (self.sceneManager.scene.preferredOrientations == UIInterfaceOrientationMaskAllButUpsideDown)) { [(PatchView *)self.view setRotation:0]; + self.sceneManager.currentOrientation = UIApplication.sharedApplication.statusBarOrientation; } else if(UIInterfaceOrientationIsLandscape(currentOrientation)) { if(self.sceneManager.scene.preferredOrientations & (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationPortraitUpsideDown)) { @@ -379,6 +371,7 @@ - (void)updateOrientation { } else { [(PatchView *)self.view setRotation:0]; + self.sceneManager.currentOrientation = UIApplication.sharedApplication.statusBarOrientation; } } else { // default is portrait @@ -395,6 +388,7 @@ - (void)updateOrientation { } else { [(PatchView *)self.view setRotation:0]; + self.sceneManager.currentOrientation = UIApplication.sharedApplication.statusBarOrientation; } } self.sceneManager.isRotated = ([(PatchView *)self.view rotation] != 0); diff --git a/src/modules/Sensors.m b/src/modules/Sensors.m index 90604210..a8e37910 100644 --- a/src/modules/Sensors.m +++ b/src/modules/Sensors.m @@ -575,7 +575,6 @@ - (void)sendAccel:(CMAccelerometerData *)accel { [self.osc sendAccel:x y:y z:z]; } -// reorient gryo data to current orientation - (void)sendGyro:(CMGyroData *)gyro { #ifdef DEBUG_SENSORS LogVerbose(@"gyro %f %f %f", gyro.rotationRate.x, gyro.rotationRate.y, gyro.rotationRate.z); From 3b165d4a859c5d33e4b41cc850304074f961e7a2 Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 00:21:59 +0100 Subject: [PATCH 3/9] updated changelog --- CHANGES.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 4608f3a9..d035f3a8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,10 @@ +1.4.1: 2023-11-14 + +* fixed accel orientation when switching between rotated and non-rotated scenes, + bug only affected rjdj scenes and pdparty scenes using accel orientation +* fixed potential crash when loading tgl or bng if atom line is < 19 in length + (tangentially reported by Coti Kappa) + 1.4.0: 2023-11-10 * updated to libpd 0.14.0 (pd 0.54-1) From 6412b016ebd604e25c1bb58cd3cc4dee3f36b944 Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 00:23:32 +0100 Subject: [PATCH 4/9] bump to version 1.4.1 --- PdParty.xcodeproj/project.pbxproj | 8 ++++---- res/about/about.html | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PdParty.xcodeproj/project.pbxproj b/PdParty.xcodeproj/project.pbxproj index f1734a6e..985f7d5c 100644 --- a/PdParty.xcodeproj/project.pbxproj +++ b/PdParty.xcodeproj/project.pbxproj @@ -1357,7 +1357,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 3567T5L8KK; EXCLUDED_ARCHS = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -1383,7 +1383,7 @@ "$(inherited)", "$(PROJECT_DIR)/libs/liblo", ); - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = 1.4.1; OTHER_CFLAGS = ( "-DPD", "-DHAVE_UNISTD_H", @@ -1411,7 +1411,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 3567T5L8KK; EXCLUDED_ARCHS = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -1436,7 +1436,7 @@ "$(inherited)", "$(PROJECT_DIR)/libs/liblo", ); - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = 1.4.1; OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", "-DPD", diff --git a/res/about/about.html b/res/about/about.html index 0b2b7a81..b804aa5f 100644 --- a/res/about/about.html +++ b/res/about/about.html @@ -11,7 +11,7 @@ -

PdParty 1.4.0

+

PdParty 1.4.1

Copyright (c) Dan Wilcox 2011-2023

BSD Simplified License

From 8fab4957a2e24a567a15dcf1bfd3d70af7377625 Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 00:32:35 +0100 Subject: [PATCH 5/9] updated changelog --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index d035f3a8..313fc2ec 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,7 +3,7 @@ * fixed accel orientation when switching between rotated and non-rotated scenes, bug only affected rjdj scenes and pdparty scenes using accel orientation * fixed potential crash when loading tgl or bng if atom line is < 19 in length - (tangentially reported by Coti Kappa) + aka malformed patch file (tangentially reported by Coti Kappa) 1.4.0: 2023-11-10 From d3df7a23572e2cbfe95bd0d8ac33cf508804b40a Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 09:03:50 +0100 Subject: [PATCH 6/9] bump user guide version --- doc/guide/PdParty_User_Guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/guide/PdParty_User_Guide.md b/doc/guide/PdParty_User_Guide.md index 235a1a4d..a4d53a91 100644 --- a/doc/guide/PdParty_User_Guide.md +++ b/doc/guide/PdParty_User_Guide.md @@ -1,8 +1,8 @@ PdParty User Guide ================== -Version: **1.4.0** -Date: 2023-11-10 +Version: **1.4.1** +Date: 2023-11-14 PdParty is an iOS app that allows you to run [Pure Data](http://puredata.info/) patches on Apple mobile devices using libpd. It is directly inspired by Chris McCormick's [PdDroidParty](http://droidparty.net/) and the original RjDj app by [Reality Jockey](http://rjdj.me/). It takes a step further by supporting OSC and MIDI and by implementing the native Pd gui objects for a WYSIWYG patch -> mobile device experience: From a55bfe8374f509b4bf557e579e30afa2fce73736 Mon Sep 17 00:00:00 2001 From: danomatika Date: Tue, 14 Nov 2023 09:08:19 +0100 Subject: [PATCH 7/9] small edit --- doc/guide/PdParty_User_Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide/PdParty_User_Guide.md b/doc/guide/PdParty_User_Guide.md index a4d53a91..8e397a06 100644 --- a/doc/guide/PdParty_User_Guide.md +++ b/doc/guide/PdParty_User_Guide.md @@ -889,7 +889,7 @@ The selected viewport area will be rescaled in order to fill the screen of the d See the DroidParty `pure-widgets-demo` sample and the PdParty `ViewPort` test. -As of PdParty 1.4.0+, the ViewPort canvas is *not* drawn in PdParty. This matches behavior in DroidParty. If you need a background color, you will can use additional cnv objects. +As of PdParty 1.4.0+, the ViewPort canvas is *not* drawn in PdParty. This matches behavior in DroidParty. If you need a background color, you can use additional cnv objects. ### Dynamic Background From 5a8f713628f76ffead9784d9491e6b5339957ea0 Mon Sep 17 00:00:00 2001 From: Reinissance Date: Thu, 4 Jul 2024 13:38:09 +0200 Subject: [PATCH 8/9] doubleTabWidgetsInput --- src/gui/Widget.m | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/gui/Widget.m b/src/gui/Widget.m index c0d4fb73..9632ab2d 100644 --- a/src/gui/Widget.m +++ b/src/gui/Widget.m @@ -70,6 +70,14 @@ - (id)initWithAtomLine:(NSArray *)line andGui:(Gui *)gui { if(self) { [self _init]; self.gui = gui; + if ([self.type isEqual:@"Symbol"] || + [self.type isEqual:@"List"] || + [self.type isEqual:@"Knob"] || + [self.type hasPrefix:@"Number"] || + [self.type hasSuffix:@"Radio"] || + [self.type hasSuffix:@"Slider"]) { + [self addDoubleTabInputToWidget:self]; + } } return self; } @@ -337,4 +345,54 @@ + (NSString *)stringFromFloat:(double)f withWidth:(int)width { return string; } +- (void) addDoubleTabInputToWidget:(Widget*)w { + UITapGestureRecognizer *tab = [[UITapGestureRecognizer alloc] + initWithTarget:self + action:@selector(handleWidgetTap:)]; + tab.numberOfTapsRequired = 2; + [w addGestureRecognizer:tab]; +} + +- (void)handleWidgetTap:(UITapGestureRecognizer *)gestureRecognizer { + Widget *control = (Widget *)gestureRecognizer.view; + if (control) { + [self showInputDialogForWidget:control withNumberPad:!([control.type isEqual:@"Symbol"] || [control.type isEqual:@"List"])]; + } +} + +- (void) showInputDialogForWidget: (Widget*)w withNumberPad: (BOOL) pad { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil + message:@"set value:" + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + if (pad) { + textField.keyboardType = UIKeyboardTypeDecimalPad; + } + [textField becomeFirstResponder]; + }]; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleCancel + handler:nil]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Set" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + UITextField *textField = alertController.textFields.firstObject; + if (textField) { + if (![textField.text isEqual: @""] && ![textField.text isEqual: @"-"]) { + if (pad) { + NSNumber *value = [NSNumber numberWithFloat:[[textField.text stringByReplacingOccurrencesOfString:@"," withString:@"."] floatValue]]; + [w receiveFloat:[value floatValue] fromSource:@"user"]; // source has no effect here + } + else { + [w receiveSymbol:textField.text fromSource:@"user"]; // source has no effect here + } + } + } + }]; + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; + [rootViewController presentViewController:alertController animated:YES completion:nil]; +} + @end From 86243722c17a8e16bc6f0bc0c3628f0a1d529ce5 Mon Sep 17 00:00:00 2001 From: Reinissance Date: Thu, 4 Jul 2024 14:32:17 +0200 Subject: [PATCH 9/9] tabInputsImproved --- src/gui/Widget.m | 80 ++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/gui/Widget.m b/src/gui/Widget.m index 9632ab2d..793fbe83 100644 --- a/src/gui/Widget.m +++ b/src/gui/Widget.m @@ -361,38 +361,58 @@ - (void)handleWidgetTap:(UITapGestureRecognizer *)gestureRecognizer { } - (void) showInputDialogForWidget: (Widget*)w withNumberPad: (BOOL) pad { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil - message:@"set value:" - preferredStyle:UIAlertControllerStyleAlert]; - [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { - if (pad) { - textField.keyboardType = UIKeyboardTypeDecimalPad; - } - [textField becomeFirstResponder]; - }]; - UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" - style:UIAlertActionStyleCancel - handler:nil]; - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Set" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * _Nonnull action) { - UITextField *textField = alertController.textFields.firstObject; - if (textField) { - if (![textField.text isEqual: @""] && ![textField.text isEqual: @"-"]) { - if (pad) { - NSNumber *value = [NSNumber numberWithFloat:[[textField.text stringByReplacingOccurrencesOfString:@"," withString:@"."] floatValue]]; - [w receiveFloat:[value floatValue] fromSource:@"user"]; // source has no effect here - } - else { - [w receiveSymbol:textField.text fromSource:@"user"]; // source has no effect here + dispatch_async(dispatch_get_main_queue(), ^{ // make shure we dont affect audio + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil + message:@"set value:" + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + if (pad) { + textField.keyboardType = UIKeyboardTypeDecimalPad; + // add button to toggle positive/negative + UIButton *minusBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [minusBtn addTarget:self action:@selector(toggleNegative:) forControlEvents:UIControlEventTouchUpInside]; + [minusBtn setTitle:@"-/+" forState:UIControlStateNormal]; + + textField.leftView = minusBtn; + textField.leftViewMode = UITextFieldViewModeAlways; + } + textField.textAlignment = NSTextAlignmentCenter; + [textField becomeFirstResponder]; + }]; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleCancel + handler:nil]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Set" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + UITextField *textField = alertController.textFields.firstObject; + if (textField) { + if (![textField.text isEqual: @""] && ![textField.text isEqual: @"-"]) { + if (pad) { + float value = [[textField.text stringByReplacingOccurrencesOfString:@"," withString:@"."] floatValue]; + // in case the widget's min and max range is set + if ((w.minValue != 0) && (w.maxValue != 0)) { + // reflect the widget's min/max range + value = ((value >= w.minValue) && (value <= w.maxValue)) ? value : (value >= w.minValue) ? w.maxValue : w.minValue; + } + [w receiveFloat:value fromSource:@"user"]; // source has no effect here + } + else { + [w receiveSymbol:textField.text fromSource:@"user"]; // source has no effect here + } } } - } - }]; - [alertController addAction:cancelAction]; - [alertController addAction:okAction]; - UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; - [rootViewController presentViewController:alertController animated:YES completion:nil]; + }]; + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; + [rootViewController presentViewController:alertController animated:YES completion:nil]; + }); +} + +- (void) toggleNegative: (UIButton*) btn { + UITextField *tf = (UITextField*) [btn superview]; + tf.text = ([tf.text hasPrefix:@"-"]) ? [tf.text substringFromIndex:1] : [@"-" stringByAppendingString:tf.text]; } @end