rt300@16: // rt300@16: // QuestionnaireViewController.m rt300@16: // oscSenderExample rt300@16: // rt300@16: // Created by Robert Tubb on 16/01/2013. rt300@16: // rt300@16: // rt300@16: rt300@16: #import "QuestionnaireViewController.h" rt300@16: rt300@47: #import "testApp.h" rt300@21: rt300@21: #pragma mark - rt300@21: #pragma mark QuestionnaireViewController rt300@21: rt300@16: @interface QuestionnaireViewController () rt300@22: // the "model" is an array of questions rt300@21: @property (strong, nonatomic) NSArray * questionArray; rt300@21: @property (nonatomic) NSInteger currentQuestionIndex; rt300@21: @property (nonatomic, assign) id theOFAppRef; rt300@21: rt300@16: /* rt300@16: rt300@16: rt300@16: */ rt300@16: rt300@16: @end rt300@16: rt300@16: @implementation QuestionnaireViewController rt300@16: rt300@21: @synthesize picker; rt300@16: @synthesize nextButton = _nextButton; rt300@43: @synthesize questionArray = _questionArray; rt300@22: rt300@16: rt300@16: //---------------------------------------------------------------- rt300@16: - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil rt300@16: { rt300@16: self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; rt300@16: if (self) { rt300@16: // Custom initialization rt300@16: rt300@16: [self populateQuestionArray ]; rt300@16: rt300@16: } rt300@16: return self; rt300@16: } rt300@16: - (void)setAppRef:(id)theOFApp{ rt300@16: self.theOFAppRef = theOFApp; rt300@16: rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: - (void)viewDidLoad rt300@16: { rt300@16: [super viewDidLoad]; rt300@16: // Do any additional setup after loading the view from its nib. rt300@16: self.currentQuestionIndex = 0; rt300@21: rt300@22: // load question 1 rt300@22: [self loadQuestion:self.currentQuestionIndex]; rt300@21: rt300@33: self.previousButton.hidden = NO; // bother rt300@28: self.commentText.hidden = YES; rt300@28: self.finishButton.hidden = YES; rt300@31: self.nextButton.hidden = YES; rt300@31: rt300@31: self.lickertOptions.hidden = NO; rt300@31: self.interfacePreferenceOptions.hidden = YES; rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: - (void)didReceiveMemoryWarning rt300@16: { rt300@16: [super didReceiveMemoryWarning]; rt300@16: // Dispose of any resources that can be recreated. rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: - (void)dealloc { rt300@16: rt300@16: [super dealloc]; rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: - (void)viewDidUnload { rt300@44: [self.questionArray release]; rt300@16: [self setQuestionText:nil]; rt300@16: [self setTitleText:nil]; rt300@16: [self setFinishButton:nil]; rt300@16: [self setNextButton:nil]; rt300@22: [self setPreviousButton:nil]; rt300@28: [self setCommentText:nil]; rt300@31: [self setNumberChooser:nil]; rt300@31: [self setInterfacePreferenceOptions:nil]; rt300@31: [self setLickertOptions:nil]; rt300@31: [self setPleaseAnswer:nil]; rt300@16: [super viewDidUnload]; rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@22: -(IBAction)hide:(id)sender{ rt300@22: // called when finish button hit rt300@22: // c++ call with NSArray argument?? rt300@22: // load answers into a c++ vector; rt300@22: vector answersArray; rt300@22: rt300@22: Question *q; rt300@16: rt300@43: for(int i=0;i<[self.questionArray count];i++){ rt300@43: q = [self.questionArray objectAtIndex:i]; rt300@22: answersArray.push_back(q.answer); rt300@22: rt300@22: } rt300@28: const char *userComments = [self.commentText.text cStringUsingEncoding: NSUTF8StringEncoding]; rt300@28: [self.commentText resignFirstResponder]; rt300@28: rt300@16: self.view.hidden = YES; rt300@29: ((testApp *)self.theOFAppRef)->questionnaireHidden(answersArray, userComments); rt300@29: rt300@16: } rt300@28: rt300@16: //---------------------------------------------------------------- rt300@16: -(IBAction)show:(id)sender{ rt300@16: self.view.hidden = NO; rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: rt300@16: - (IBAction)nextQuestionPressed:(id)sender { rt300@16: // save answer ? no button did that hopefully rt300@16: rt300@16: // if last question show thanks rt300@16: // else go to next rt300@16: self.currentQuestionIndex++; rt300@16: if(self.currentQuestionIndex >= [self.questionArray count]){ rt300@16: [self showThanks]; rt300@16: }else{ rt300@16: [self loadQuestion:self.currentQuestionIndex]; rt300@16: rt300@16: } rt300@16: } rt300@16: //---------------------------------------------------------------- rt300@16: - (IBAction)previousQuestionPressed:(id)sender { rt300@16: self.currentQuestionIndex--; rt300@16: if(self.currentQuestionIndex < 0){ rt300@16: // nothing rt300@16: self.currentQuestionIndex = 0; rt300@16: }else{ rt300@16: [self loadQuestion:self.currentQuestionIndex]; rt300@16: } rt300@16: } rt300@16: rt300@16: //---------------------------------------------------------------- rt300@16: rt300@16: - (void)showThanks{ rt300@16: // hide next question button rt300@16: self.nextButton.hidden = YES; rt300@16: // hide selector rt300@22: self.picker.hidden = YES; rt300@22: self.previousButton.hidden = YES; rt300@28: self.finishButton.hidden = NO; rt300@16: rt300@31: self.lickertOptions.hidden = YES; rt300@31: self.interfacePreferenceOptions.hidden = YES; rt300@31: rt300@16: self.titleText.text = @"Thank you!"; rt300@31: self.numberChooser.hidden = YES; rt300@28: self.commentText.hidden = NO; rt300@28: rt300@33: self.questionText.text = @"Thanks for helping science help you. Feel free to add further comments in the text box below, and then press 'finish' to go back and use the app."; rt300@16: } rt300@16: rt300@16: //---------------------------------------------------------------- rt300@16: - (void)loadQuestion:(NSInteger)questionIndex { rt300@16: // populate text fields with question rt300@16: NSString *qtitle; rt300@43: qtitle = [@"Question " stringByAppendingFormat:@"%d / %d",questionIndex+1, [self.questionArray count]]; rt300@16: self.titleText.text = qtitle; rt300@16: rt300@43: Question *curQ = [self.questionArray objectAtIndex:self.currentQuestionIndex]; rt300@16: rt300@22: self.questionText.text = curQ.questionText; rt300@21: rt300@22: rt300@22: // refresh picker view content rt300@33: //[picker reloadComponent:0]; rt300@21: rt300@31: // show correct option number labels rt300@31: if(curQ.questionType == AGREE_DISAGREE){ rt300@31: self.lickertOptions.hidden = NO; rt300@31: self.interfacePreferenceOptions.hidden = YES; rt300@31: }else if(curQ.questionType == SLIDERS_ZOOMER){ rt300@31: self.lickertOptions.hidden = YES; rt300@31: self.interfacePreferenceOptions.hidden = NO; rt300@31: } rt300@31: rt300@31: //NSLog(@"Prev answer answerInt %d", curQ.answer); rt300@33: //[picker selectRow:2 inComponent:0 animated:YES]; rt300@33: rt300@33: // what about unselecting segment? rt300@22: rt300@16: } rt300@32: // 1/3/13 removed q 6 and 15. now only 15 qs rt300@16: //---------------------------------------------------------------- rt300@16: - (void)populateQuestionArray{ rt300@36: // potential leak rt300@22: self.questionArray = [NSArray arrayWithObjects: rt300@22: [[Question alloc] initWithTextAndType:@"I am familiar with music software and sound synthesis.":AGREE_DISAGREE], rt300@44: [[Question alloc] initWithTextAndType:@"The ability to retrace my steps using the history path was useful...":AGREE_DISAGREE], rt300@27: [[Question alloc] initWithTextAndType:@"The best interface for discovering interesting sounds quickly was...":SLIDERS_ZOOMER], rt300@27: [[Question alloc] initWithTextAndType:@"The best interface for fine tuning a sound was...":SLIDERS_ZOOMER], rt300@22: [[Question alloc] initWithTextAndType:@"The correspondence between the sliders and the grid was understandable.":AGREE_DISAGREE], rt300@27: [[Question alloc] initWithTextAndType:@"Scrolling a greater distance on the grid seemed to correspond to larger difference in the sound.":AGREE_DISAGREE], rt300@27: [[Question alloc] initWithTextAndType:@"The interface that I felt more in control using was...":SLIDERS_ZOOMER], rt300@32: [[Question alloc] initWithTextAndType:@"Being able to see previously saved presets laid on the grid is useful.":AGREE_DISAGREE], // rt300@27: [[Question alloc] initWithTextAndType:@"The interface that felt more creative was...":SLIDERS_ZOOMER], rt300@32: [[Question alloc] initWithTextAndType:@"The range of sounds was too limited to be able to judge the eventual usefulness of the interface.":AGREE_DISAGREE], rt300@27: [[Question alloc] initWithTextAndType:@"The interface better for generating new ideas was...":SLIDERS_ZOOMER], rt300@27: [[Question alloc] initWithTextAndType:@"The interface better for performing live would be...":SLIDERS_ZOOMER], rt300@22: [[Question alloc] initWithTextAndType:@"The Zoomer was an improvement on just using a randomiser.":AGREE_DISAGREE], rt300@22: [[Question alloc] initWithTextAndType:@"The combination of Zoomer and Sliders was better than either individually.":AGREE_DISAGREE], rt300@44: [[Question alloc] initWithTextAndType:@"I enjoy 'happy accidents' in the creative process.":AGREE_DISAGREE], rt300@27: [[Question alloc] initWithTextAndType:@"Overall, the interface I preferred using was...":SLIDERS_ZOOMER], // ?????? rt300@16: nil]; rt300@32: // The zoomer seemed more appropriate to explore the synth sound controls (red) than the note sequence controls (blue) rt300@32: // I enjoyed the sounds produced rt300@32: rt300@16: } rt300@16: rt300@21: //---------------------------------------------------------------- rt300@21: #pragma mark - rt300@21: #pragma mark PickerView DataSource rt300@16: rt300@21: - (NSInteger)numberOfComponentsInPickerView: rt300@21: (UIPickerView *)pickerView rt300@21: { rt300@21: return 1; rt300@21: } rt300@22: //---------------------------------------------------------------- rt300@21: - (NSInteger)pickerView:(UIPickerView *)pickerView rt300@21: numberOfRowsInComponent:(NSInteger)component rt300@21: { rt300@27: rt300@27: return NUM_CHOICES; // always 6 rt300@21: } rt300@22: //---------------------------------------------------------------- rt300@21: - (NSString *)pickerView:(UIPickerView *)pickerView rt300@21: titleForRow:(NSInteger)row rt300@21: forComponent:(NSInteger)component rt300@21: { rt300@43: Question *curQ = [self.questionArray objectAtIndex:self.currentQuestionIndex]; rt300@22: rt300@22: // get array of answers from Question class rt300@22: NSArray * answers = [Question answersWithType:curQ.questionType]; rt300@22: return [answers objectAtIndex:row]; rt300@22: rt300@21: } rt300@22: //---------------------------------------------------------------- rt300@21: #pragma mark - rt300@21: #pragma mark PickerView Delegate rt300@21: -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row rt300@21: inComponent:(NSInteger)component rt300@21: { rt300@43: Question *curQ = [self.questionArray objectAtIndex:self.currentQuestionIndex]; rt300@21: // set question answerArray rt300@22: curQ.answer = row; rt300@21: rt300@21: // chek wot we just rote rt300@21: rt300@22: NSLog(@"Answer: %d",curQ.answer); rt300@22: rt300@21: } rt300@28: //---------------------------------------------------------------- rt300@28: #pragma mark UITextViewDelegate functions rt300@28: /* rt300@28: This answer was useful to me, but I was also looking for the callback function from the "Go" button, which I found is: rt300@28: - (BOOL) textFieldShouldReturn:(UITextField *)textField { // Customer code return YES; } rt300@28: rt300@28: You will need to send the UITextField delegate to your view controller for that to work. rt300@28: rt300@28: */ rt300@28: - (BOOL) textFieldShouldReturn:(UITextField *)textField { rt300@28: // Customer code rt300@28: NSLog(@"RETURN DELEGATE"); rt300@28: [self hide:self ]; rt300@28: return NO; rt300@28: } rt300@31: - (IBAction)answerChosen:(id)sender { rt300@31: self.pleaseAnswer.hidden = YES; rt300@31: UISegmentedControl *seg = (UISegmentedControl *)sender; rt300@43: Question *curQ = [self.questionArray objectAtIndex:self.currentQuestionIndex]; rt300@31: // set question answerArray rt300@31: curQ.answer = seg.selectedSegmentIndex; rt300@31: rt300@31: // chek wot we just rote rt300@31: rt300@31: NSLog(@"Answer: %d",curQ.answer); rt300@31: rt300@31: // automatically go next q rt300@31: self.currentQuestionIndex++; rt300@31: if(self.currentQuestionIndex >= [self.questionArray count]){ rt300@31: [self showThanks]; rt300@31: }else{ rt300@31: [self loadQuestion:self.currentQuestionIndex]; rt300@31: rt300@31: } rt300@31: rt300@31: } rt300@21: @end // end implementation rt300@21: //---------------------------------------------------------------- rt300@21: //----------------------------------------------------------------