1/************************************************************************
2 ************************************************************************
3 FAUST Architecture File
4 Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6
7 This is sample code. This file is provided as an example of minimal
8 FAUST architecture file. Redistribution and use in source and binary
9 forms, with or without modification, in part or in full are permitted.
10 In particular you can create a derived work of this FAUST architecture
11 and distribute that work under terms of your choice.
12
13 This sample code is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 ************************************************************************
17 ************************************************************************/
18
19#import "FITextField.h"
20
21#define kAccViewHeight          40.0
22
23@implementation FITextField
24
25@synthesize cornerRadius;
26@synthesize backgroundColor = _backgroundColor;
27@synthesize textColor = _textColor;
28@synthesize fMenuItemNames;
29@synthesize fMenuItemValues;
30
31#pragma mark -
32#pragma mark Init
33
34- (id)initWithDelegate:(id)aDelegate
35{
36	if ((self = [super initWithDelegate:aDelegate]))
37	{
38        _valueBeforeCancel = 0.f;
39
40        // UI parameters
41		self.cornerRadius = 3.0;
42
43        // Message text view creation
44        _messageTextView = [[UITextView alloc] initWithFrame:self.bounds];
45        [_messageTextView setAutocorrectionType:UITextAutocorrectionTypeNo];
46        [_messageTextView setReturnKeyType:UIReturnKeyGo];
47        _backgroundColor = [UIColor whiteColor];
48        _textColor = [UIColor blackColor];
49        _messageTextView.textColor = [UIColor whiteColor];
50        _messageTextView.backgroundColor = [UIColor darkGrayColor];
51        _messageTextView.delegate = self;
52        _messageTextView.font = [UIFont boldSystemFontOfSize:14];
53        _messageTextView.textAlignment = NSTextAlignmentCenter;
54        [self addSubview:_messageTextView];
55
56        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
57        {
58            _messageTextView.keyboardType = UIKeyboardTypeDecimalPad;
59        }
60        else
61        {
62            _messageTextView.keyboardType = UIKeyboardTypeNumberPad;
63        }
64
65        // Input accessory view
66        [self createInputAccessoryView];
67        _messageTextView.inputAccessoryView = _inputAccView;
68
69        // Number formatter
70        _numberFormatter = [[NSNumberFormatter alloc] init];
71        [_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
72        [_numberFormatter setRoundingMode:NSNumberFormatterRoundDown];
73
74        UIPanGestureRecognizer *panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)] autorelease];
75        panGesture.delegate = self;
76		[self addGestureRecognizer:panGesture];
77	}
78
79	return self;
80}
81
82// to setup handle size
83- (void)setFrame:(CGRect)frame
84{
85    /*
86    2017/10/27 : finally values need to be edited, so deactivate this case
87
88    // Edition is deactivated if medata 'menu' is used
89    if (self.fMenuItemValues.size() > 0) {
90        _messageTextView.editable = NO;
91    }
92    */
93
94    [super setFrame:frame];
95}
96
97- (void)dealloc
98{
99    [_messageTextView release];
100    [_inputAccView release];
101    [_doneButton release];
102    [_rangeLabel release];
103
104    [super dealloc];
105}
106
107#pragma mark -
108#pragma mark Drawing
109
110- (void)drawRect:(CGRect)rect
111{
112    if (self.hideOnGUI) return;
113
114    _messageTextView.frame = CGRectMake(rect.origin.x,
115                                        rect.origin.y,
116                                        rect.size.width,
117                                        rect.size.height);
118
119    // In menu items, displays them instead of the value
120    if (self.fMenuItemValues.size() > 0) {
121
122        for (int i = 0; i < self.fMenuItemValues.size(); i++) {
123            if (floor(self.value) == self.fMenuItemValues[i]) {
124                _messageTextView.text = [NSString stringWithCString:self.fMenuItemNames[i].c_str() encoding:NSUTF8StringEncoding];
125            }
126        }
127
128    } else {
129
130        if (self.step < 0.01) _messageTextView.text = [NSString stringWithFormat:@"%2.3f%@", self.value, self.suffixe];
131        else if (self.step < 0.1) _messageTextView.text = [NSString stringWithFormat:@"%2.2f%@", self.value, self.suffixe];
132        else _messageTextView.text = [NSString stringWithFormat:@"%2.1f%@", self.value, self.suffixe];
133
134    }
135}
136
137#pragma mark - UITextView Delegate Methods
138
139-(void)textViewDidBeginEditing:(UITextView *)textView
140{
141    _valueBeforeCancel = self.value;
142    [((FIMainViewController*)self.delegate) zoomToWidget:self];
143    if (self.step < 0.01) _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.3f - %2.3f", self.min, self.max];
144    else if (self.step < 0.1) _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.2f - %2.2f", self.min, self.max];
145    else _rangeLabel.text = [NSString stringWithFormat:@"Range : %2.1f - %2.1f", self.min, self.max];
146    [_messageTextView setText:@""];
147}
148
149- (void)minus
150{
151    if ([_messageTextView.text length] == 0)
152    {
153        _messageTextView.text = @"-";
154    }
155    else if ([_messageTextView.text characterAtIndex:0] != 45) //45 for minus
156    {
157        _messageTextView.text = [NSString stringWithFormat:@"-%@", _messageTextView.text];
158    }
159    else
160    {
161        _messageTextView.text = [_messageTextView.text substringFromIndex:1];
162    }
163}
164
165- (void)doneTyping
166{
167    float value;
168
169    // Hide the keyboard
170    [_messageTextView resignFirstResponder];
171    value = [[_numberFormatter numberFromString:_messageTextView.text] floatValue];
172    if (value < self.min) value = self.min;
173    else if (value > self.max) value = self.max;
174
175    [self setValue:value];
176
177    [self setNeedsDisplay];
178}
179
180- (void)cancel
181{
182    // Hide the keyboard
183    [_messageTextView resignFirstResponder];
184
185    [self setValue:_valueBeforeCancel];
186
187    [self setNeedsDisplay];
188}
189
190- (void)createInputAccessoryView
191{
192    float viewWidth = _messageTextView.inputView.frame.size.width;
193
194    _inputAccView = [[UIView alloc] initWithFrame:CGRectMake(10.0, 0.0, viewWidth, kAccViewHeight)];
195    _inputAccView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
196
197    viewWidth = _inputAccView.frame.size.width;
198    _inputAccView.backgroundColor = [UIColor blackColor];
199
200    _rangeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, kAccViewHeight)];
201    _rangeLabel.backgroundColor = [UIColor blackColor];
202    _rangeLabel.textColor = [UIColor whiteColor];
203    _rangeLabel.textAlignment = NSTextAlignmentLeft;
204    [_inputAccView addSubview:_rangeLabel];
205
206    _minusButton =[UIButton buttonWithType:UIButtonTypeCustom];
207    [_minusButton setFrame:CGRectMake(viewWidth - 120.f, 0.0f, 40.0f, kAccViewHeight)];
208    _minusButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
209    [_minusButton setTitle:@"-" forState:UIControlStateNormal];
210    [_minusButton setBackgroundColor:[UIColor blueColor]];
211    [_minusButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
212    [_minusButton addTarget:self action:@selector(minus) forControlEvents:UIControlEventTouchUpInside];
213    [_inputAccView addSubview:_minusButton];
214
215    _cancelButton =[UIButton buttonWithType:UIButtonTypeCustom];
216    [_cancelButton setFrame:CGRectMake(viewWidth - 80.f, 0.0f, 40.0f, kAccViewHeight)];
217    _cancelButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
218    [_cancelButton setTitle:@"X" forState:UIControlStateNormal];
219    [_cancelButton setBackgroundColor:[UIColor blueColor]];
220    [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
221    [_cancelButton addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
222    [_inputAccView addSubview:_cancelButton];
223
224    _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
225    [_doneButton setFrame:CGRectMake(viewWidth - 40.f, 0.0f, 40.0f, kAccViewHeight)];
226    _doneButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
227    [_doneButton setTitle:@"OK" forState:UIControlStateNormal];
228    [_doneButton setBackgroundColor:[UIColor blueColor]];
229    [_doneButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
230    [_doneButton addTarget:self action:@selector(doneTyping) forControlEvents:UIControlEventTouchUpInside];
231    [_inputAccView addSubview:_doneButton];
232}
233
234#pragma mark -
235#pragma mark Touch Handling
236
237- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
238{
239    UIScrollView* scrollView = (UIScrollView*)self.superview.superview;
240
241    scrollView.scrollEnabled = NO;
242
243    return YES;
244}
245
246- (void)pan:(UIPanGestureRecognizer *)gesture
247{
248    UIScrollView* scrollView = (UIScrollView*)self.superview.superview;
249    float value = 0.f - [gesture velocityInView:scrollView].y;
250    value = value / 200.;
251
252    if ([gesture velocityInView:scrollView].y < 0)
253    {
254        [self setValue:self.value + (floor(value) + 1.) * self.step];
255    }
256    else
257    {
258        [self setValue:self.value + floor(value) * self.step];
259    }
260
261    scrollView.scrollEnabled = YES;
262}
263
264@end
265