diff --git a/CHANGES.txt b/CHANGES.txt
index 4608f3a..313fc2e 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
+ aka malformed patch file (tangentially reported by Coti Kappa)
+
1.4.0: 2023-11-10
* updated to libpd 0.14.0 (pd 0.54-1)
diff --git a/PdParty.xcodeproj/project.pbxproj b/PdParty.xcodeproj/project.pbxproj
index f1734a6..985f7d5 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/doc/guide/PdParty_User_Guide.md b/doc/guide/PdParty_User_Guide.md
index 235a1a4..8e397a0 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:
@@ -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
diff --git a/res/about/about.html b/res/about/about.html
index 0b2b7a8..b804aa5 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
diff --git a/src/PatchViewController.m b/src/PatchViewController.m
index 588863d..994fef6 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/gui/Widget.m b/src/gui/Widget.m
index c0d4fb7..793fbe8 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,74 @@ + (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 {
+ 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];
+ });
+}
+
+- (void) toggleNegative: (UIButton*) btn {
+ UITextField *tf = (UITextField*) [btn superview];
+ tf.text = ([tf.text hasPrefix:@"-"]) ? [tf.text substringFromIndex:1] : [@"-" stringByAppendingString:tf.text];
+}
+
@end
diff --git a/src/gui/iem/Bang.m b/src/gui/iem/Bang.m
index 95b0047..a2cc804 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 5c70f1b..a8e8786 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];
diff --git a/src/modules/Sensors.m b/src/modules/Sensors.m
index 9060421..a8e3791 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);