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