1//----------------------------------------------------------------------------- 2// Project : VST SDK 3// 4// Category : Helpers 5// Filename : public.sdk/source/vst/interappaudio/PresetSaveViewController.mm 6// Created by : Steinberg, 09/2013 7// Description : VST 3 InterAppAudio 8// Flags : clang-format SMTGSequencer 9// 10//----------------------------------------------------------------------------- 11// LICENSE 12// (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved 13//----------------------------------------------------------------------------- 14// Redistribution and use in source and binary forms, with or without modification, 15// are permitted provided that the following conditions are met: 16// 17// * Redistributions of source code must retain the above copyright notice, 18// this list of conditions and the following disclaimer. 19// * Redistributions in binary form must reproduce the above copyright notice, 20// this list of conditions and the following disclaimer in the documentation 21// and/or other materials provided with the distribution. 22// * Neither the name of the Steinberg Media Technologies nor the names of its 23// contributors may be used to endorse or promote products derived from this 24// software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 27// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 34// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 35// OF THE POSSIBILITY OF SUCH DAMAGE. 36//----------------------------------------------------------------------------- 37 38#import "PresetSaveViewController.h" 39#import "pluginterfaces/base/funknown.h" 40 41//------------------------------------------------------------------------ 42@interface PresetSaveViewController () 43//------------------------------------------------------------------------ 44{ 45 IBOutlet UIView* containerView; 46 IBOutlet UITextField* presetName; 47 48 std::function<void (const char* presetPath)> callback; 49 Steinberg::FUID uid; 50} 51@end 52 53//------------------------------------------------------------------------ 54@implementation PresetSaveViewController 55//------------------------------------------------------------------------ 56 57//------------------------------------------------------------------------ 58- (id)initWithCallback:(std::function<void (const char* presetPath)>)_callback 59{ 60 self = [super initWithNibName:@"PresetSaveView" bundle:nil]; 61 if (self) 62 { 63 callback = _callback; 64 65 self.modalPresentationStyle = UIModalPresentationOverCurrentContext; 66 self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; 67 68 UIViewController* rootViewController = 69 [[UIApplication sharedApplication].windows[0] rootViewController]; 70 71 [rootViewController presentViewController:self 72 animated:YES 73 completion:^{ [self showKeyboard]; }]; 74 } 75 return self; 76} 77 78//------------------------------------------------------------------------ 79- (void)viewDidLoad 80{ 81 [super viewDidLoad]; 82 83 containerView.layer.shadowOpacity = 0.5; 84 containerView.layer.shadowOffset = CGSizeMake (5, 5); 85 containerView.layer.shadowRadius = 5; 86} 87 88//------------------------------------------------------------------------ 89- (void)showKeyboard 90{ 91 [presetName becomeFirstResponder]; 92} 93 94//------------------------------------------------------------------------ 95- (void)removeSelf 96{ 97 [self dismissViewControllerAnimated:YES completion:^{}]; 98} 99 100//------------------------------------------------------------------------ 101- (NSURL*)presetURL 102{ 103 NSFileManager* fs = [NSFileManager defaultManager]; 104 NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory 105 inDomain:NSUserDomainMask 106 appropriateForURL:Nil 107 create:YES 108 error:NULL]; 109 if (documentsUrl) 110 { 111 NSURL* presetPath = [[documentsUrl URLByAppendingPathComponent:presetName.text] 112 URLByAppendingPathExtension:@"vstpreset"]; 113 return presetPath; 114 } 115 return nil; 116} 117 118//------------------------------------------------------------------------ 119- (BOOL)textFieldShouldReturn:(UITextField*)textField 120{ 121 if ([textField.text length] > 0) 122 { 123 [self save:textField]; 124 return YES; 125 } 126 return NO; 127} 128 129//------------------------------------------------------------------------ 130- (IBAction)save:(id)sender 131{ 132 if (callback) 133 { 134 NSURL* presetPath = [self presetURL]; 135 NSFileManager* fs = [NSFileManager defaultManager]; 136 if ([fs fileExistsAtPath:[presetPath path]]) 137 { 138 // alert for overwrite 139 auto alertController = [UIAlertController 140 alertControllerWithTitle:NSLocalizedString ( 141 @"A Preset with this name already exists", 142 "Alert title") 143 message:NSLocalizedString (@"Save it anyway ?", "Alert message") 144 preferredStyle:UIAlertControllerStyleAlert]; 145 [alertController 146 addAction:[UIAlertAction 147 actionWithTitle:NSLocalizedString (@"Save", "Alert Save Button") 148 style:UIAlertActionStyleDefault 149 handler:^(UIAlertAction* _Nonnull action) { 150 callback ([[[self presetURL] path] UTF8String]); 151 [self removeSelf]; 152 }]]; 153 [alertController 154 addAction:[UIAlertAction 155 actionWithTitle:NSLocalizedString (@"Cancel", "Alert Cancel Button") 156 style:UIAlertActionStyleCancel 157 handler:^(UIAlertAction* _Nonnull action) {}]]; 158 [self presentViewController:alertController animated:YES completion:nil]; 159 return; 160 } 161 callback ([[presetPath path] UTF8String]); 162 } 163 [self removeSelf]; 164} 165 166//------------------------------------------------------------------------ 167- (IBAction)cancel:(id)sender 168{ 169 if (callback) 170 { 171 callback (nullptr); 172 } 173 [self removeSelf]; 174} 175 176//------------------------------------------------------------------------ 177- (BOOL)prefersStatusBarHidden 178{ 179 return YES; 180} 181 182@end 183