# HG changeset patch # User Robert Tubb # Date 1361187905 0 # Node ID e2c62db1e265d4487f7420ce0cd2ec871a7274b9 # Parent ae4d2c3ce5e00882d19e87a613ea88cc83882e3c Started timer stuff diff -r ae4d2c3ce5e0 -r e2c62db1e265 HelpViewController.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HelpViewController.mm Mon Feb 18 11:45:05 2013 +0000 @@ -0,0 +1,53 @@ +// +// HelpViewController.m +// sonicZoom +// +// Created by Robert Tubb on 01/02/2013. +// +// + +#import "HelpViewController.h" +#import "testApp.h" +@interface HelpViewController () + +@end + +@implementation HelpViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)setAppRef:(id)theOFApp{ + self.theOFAppRef = theOFApp; + +} +-(IBAction)show:(id)sender{ + self.view.hidden = NO; +} + +- (IBAction)hide:(id)sender +{ + self.view.hidden = YES; + ((testApp *)self.theOFAppRef)->helpHidden(); + + +} +@end diff -r ae4d2c3ce5e0 -r e2c62db1e265 QuestionnaireViewController.h --- a/QuestionnaireViewController.h Wed Feb 13 17:03:56 2013 +0000 +++ b/QuestionnaireViewController.h Mon Feb 18 11:45:05 2013 +0000 @@ -11,7 +11,7 @@ #import "Question.h" @interface QuestionnaireViewController : UIViewController - + { UIPickerView *picker; @@ -26,6 +26,7 @@ @property (strong, nonatomic) IBOutlet UIPickerView *picker; +@property (retain, nonatomic) IBOutlet UITextView *commentText; //---------------------------------------------------------------- -(IBAction)hide:(id)sender; diff -r ae4d2c3ce5e0 -r e2c62db1e265 QuestionnaireViewController.mm --- a/QuestionnaireViewController.mm Wed Feb 13 17:03:56 2013 +0000 +++ b/QuestionnaireViewController.mm Mon Feb 18 11:45:05 2013 +0000 @@ -60,7 +60,8 @@ [self loadQuestion:self.currentQuestionIndex]; self.previousButton.hidden = YES; // dont bother - + self.commentText.hidden = YES; + self.finishButton.hidden = YES; } //---------------------------------------------------------------- - (void)didReceiveMemoryWarning @@ -76,6 +77,7 @@ [_finishButton release]; [_nextButton release]; [_previousButton release]; + [_commentText release]; [super dealloc]; } //---------------------------------------------------------------- @@ -85,6 +87,7 @@ [self setFinishButton:nil]; [self setNextButton:nil]; [self setPreviousButton:nil]; + [self setCommentText:nil]; [super viewDidUnload]; } //---------------------------------------------------------------- @@ -101,10 +104,14 @@ answersArray.push_back(q.answer); } + const char *userComments = [self.commentText.text cStringUsingEncoding: NSUTF8StringEncoding]; - ((testApp *)self.theOFAppRef)->questionnaireHidden(answersArray); + ((testApp *)self.theOFAppRef)->questionnaireHidden(answersArray, userComments); + [self.commentText resignFirstResponder]; + self.view.hidden = YES; } + //---------------------------------------------------------------- -(IBAction)show:(id)sender{ self.view.hidden = NO; @@ -143,10 +150,13 @@ // hide selector self.picker.hidden = YES; self.previousButton.hidden = YES; + self.finishButton.hidden = NO; self.titleText.text = @"Thank you!"; - self.questionText.text = @"Thanks for helping science help you. Visit the study website to keep abreast of exciting events."; + self.commentText.hidden = NO; + + 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 to the app."; } //---------------------------------------------------------------- @@ -238,7 +248,21 @@ NSLog(@"Answer: %d",curQ.answer); } - +//---------------------------------------------------------------- +#pragma mark UITextViewDelegate functions +/* + This answer was useful to me, but I was also looking for the callback function from the "Go" button, which I found is: + - (BOOL) textFieldShouldReturn:(UITextField *)textField { // Customer code return YES; } + + You will need to send the UITextField delegate to your view controller for that to work. + + */ + - (BOOL) textFieldShouldReturn:(UITextField *)textField { + // Customer code + NSLog(@"RETURN DELEGATE"); + [self hide:self ]; + return NO; + } @end // end implementation //---------------------------------------------------------------- //---------------------------------------------------------------- diff -r ae4d2c3ce5e0 -r e2c62db1e265 QuestionnaireViewController.xib --- a/QuestionnaireViewController.xib Wed Feb 13 17:03:56 2013 +0000 +++ b/QuestionnaireViewController.xib Mon Feb 18 11:45:05 2013 +0000 @@ -15,6 +15,7 @@ IBUIButton IBUILabel IBUIPickerView + IBUITextView IBUIView @@ -40,7 +41,7 @@ 292 - {{627, 933}, {121, 44}} + {{324, 706}, {121, 44}} _NS:9 @@ -141,7 +142,7 @@ 292 - {{436, 706}, {121, 44}} + {{425, 706}, {121, 44}} @@ -164,7 +165,7 @@ 292 - {{218, 706}, {157, 44}} + {{212, 706}, {157, 44}} @@ -191,11 +192,42 @@ {{212, 409}, {334, 216}} - + _NS:9 IBIPadFramework YES + + + 292 + {{212, 409}, {334, 230}} + + + + _NS:9 + + 1 + MSAxIDEAA + + YES + YES + IBIPadFramework + NO + + + 2 + IBCocoaTouchFramework + + + 1 + 14 + + + Helvetica + 14 + 16 + + {768, 1024} @@ -286,6 +318,14 @@ 60 + + commentText + + + + 64 + + nextQuestionPressed: @@ -352,12 +392,13 @@ 2 - + + + - - + @@ -394,6 +435,11 @@ + + 63 + + + @@ -406,6 +452,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -413,7 +460,7 @@ - 61 + 64 @@ -445,6 +492,7 @@ + UITextView UIButton UIButton UIPickerView @@ -453,6 +501,10 @@ UILabel + + commentText + UITextView + finishButton UIButton diff -r ae4d2c3ce5e0 -r e2c62db1e265 eventLogger.h --- a/eventLogger.h Wed Feb 13 17:03:56 2013 +0000 +++ b/eventLogger.h Mon Feb 18 11:45:05 2013 +0000 @@ -28,7 +28,7 @@ - +#define EVENT_THIN_FACTOR 10 #define EVENT_LOG_FILENAME "log.json" #define SERVER_URL "http://127.0.0.1:8080/testservice/" #define UPLOAD_CHUNK_SIZE 500 @@ -75,7 +75,7 @@ val2 = v2; sliderID = sID; - double timemsd = [NSDate timeIntervalSinceReferenceDate]; + double timemsd = [NSDate timeIntervalSinceReferenceDate]; // MILLISECONDS eventTime = (unsigned long long)(timemsd*1000) - APP_CREATION_TIME; } @@ -146,7 +146,7 @@ void setUsername(const char *u); void newUser(); void logEvent(const leventType& evtType,const TwoVector& centre = TwoVector(), const double& scale = 1.0, const int& sliderID = -1, const double& sliderVal = 0.0); - void questionnaireAnswersObtained(vector answers); + void questionnaireAnswersObtained(vector answers, const char* userComments); void urlResponse(ofHttpResponse & response); private: // what we need... @@ -157,11 +157,13 @@ int currentHTTPRequestID; vector theEvents; + void thinnedLogEvent(lEvent nextEvent); // values applicable to all events unsigned int nextUploadQty; + string questionnaireComments; ofxiPhoneDeviceType iOSdeviceType; @@ -169,6 +171,7 @@ vector questionnaireAnswers; bool questionnaireCompleted; bool questionnaireUploaded; + int interfaceOrder; void checkLogFile(); diff -r ae4d2c3ce5e0 -r e2c62db1e265 eventLogger.mm --- a/eventLogger.mm Wed Feb 13 17:03:56 2013 +0000 +++ b/eventLogger.mm Mon Feb 18 11:45:05 2013 +0000 @@ -8,9 +8,10 @@ //--------------------------------------------------------------------------- #include "eventLogger.h" +#include "timer.h" EventLogger eventLogger; - +extern Timer timer; //--------------------------------------------------------------------------- EventLogger::EventLogger(){ //QuestionnaireViewController * questionnaireViewController; @@ -42,11 +43,11 @@ logEvent(APP_STARTED); } //--------------------------------------------------------------------------- -void EventLogger::questionnaireAnswersObtained(vector answers){ +void EventLogger::questionnaireAnswersObtained(vector answers, const char* userComments){ questionnaireCompleted = true; questionnaireAnswers = answers; - + questionnaireComments = userComments; uploadQuestionnaire(); } @@ -168,6 +169,7 @@ cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n"; serverConnectionOK = true; }else{ + serverConnectionOK = false; cout << "server connection ERROR \n"; } } @@ -183,6 +185,8 @@ } //--------------------------------------------------------------------------- +// this reads the persistent log file , checks if we've used the app before and +// if we've answered questionnaire or not void EventLogger::readJsonToLog(const string &jsonFile){ Json::Value root; Json::Reader reader; @@ -224,18 +228,20 @@ savedInteractionTime = root["savedInteractionTime"].asLargestInt(); questionnaireCompleted = root["questionnaireCompleted"].asBool(); questionnaireUploaded = root["questionnaireUploaded"].asBool(); - + interfaceOrder = root["interfaceOrder"].asInt(); if(questionnaireCompleted && !questionnaireUploaded){ // then read it in and upload it - Json::Value JArray = root["questionnaireAnswers"]; + Json::Value JQ = root["questionnaire"]; + Json::Value JArray = JQ["qAnswers"]; if(JArray.size() < 2){ cout << "Error - status of questionnaire is wierd\n"; } for ( unsigned int i = 0; i < JArray.size(); i++ ) { - questionnaireAnswers.push_back(JArray[1].asInt()); + questionnaireAnswers.push_back(JArray[i].asInt()); } + questionnaireComments = JQ["comments"].toStyledString(); uploadQuestionnaire(); } @@ -249,7 +255,9 @@ } // TODO if the total interaction time is greater than a certain amount && no questions answered - questionnaire time! cout << "Total interaction time: " << savedInteractionTime << '\n'; - + + timer.setInteractionTime(savedInteractionTime); + timer.setOrderFromPrevious(interfaceOrder); } @@ -257,6 +265,7 @@ //--------------------------------------------------------------------------- bool EventLogger::uploadEventLog(bool async){ + // show indicator logUploadInProgress = true; cout << "^^^^^^^^ ATTEMPTING TO UPLOAD " << theEvents.size() << " EVENTS ^^^^^^^^ .\n"; @@ -297,11 +306,15 @@ consentGiven = false; } +//--------------------------------------------------------------------------- +// only called when doing supervised tests void EventLogger::newUser(){ cout<<"setup new user\n"; nextUploadNumber = 0; deviceID = ofGetSystemTimeMicros(); savedInteractionTime = 0; + totalInteractionTime = 0; + sessionStartTime = ofGetSystemTime(); questionnaireCompleted = false; questionnaireUploaded = false; consentGiven = true; // other wise we wouldn't be doing this @@ -312,9 +325,41 @@ // called from alertView OK in iViewController void EventLogger::setUsername(const char *u){ userName = u; + // start interaction clock + timer.startInteractionClock(); +} +//--------------------------------------------------------------------------- +void EventLogger::thinnedLogEvent(lEvent newEvent){ + static lEvent previousEvent(APP_STARTED); // initialised as whatever. hopefully won't log + static int eventCounter = 0; + + // if first event then log it. it won't be, but still. + if(theEvents.size() == 0){ + theEvents.push_back(newEvent); + previousEvent = newEvent; + return; + } + + // if previous event is more than 300ms ago, or event type has changed, log both of them + int gap = newEvent.eventTime - previousEvent.eventTime; + if(gap > 300 || newEvent.eventType != previousEvent.eventType){ + // if prev event not logged, log it + if((*theEvents.end()).eventTime != previousEvent.eventTime){ + theEvents.push_back(previousEvent); + } + theEvents.push_back(newEvent); + } + + // otherwise only record every Nth event + if(eventCounter >= EVENT_THIN_FACTOR){ + theEvents.push_back(newEvent); + eventCounter = 0; + + } + eventCounter++; + previousEvent = newEvent; } - //--------------------------------------------------------------------------- // log zoom event void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){ @@ -331,6 +376,17 @@ // thinFactor if(!loggingEnabled) return; switch ( evtType ) { + // data thinning here + case SCROLL: + thinnedLogEvent(lEvent(evtType,centre.x,centre.y)); + break; + case ZOOM: + thinnedLogEvent(lEvent(evtType,scale)); + break; + case CHANGE_SLIDER: + thinnedLogEvent(lEvent(evtType,sliderVal , 0.0 , sliderID)); + break; + case SAVE_PRESET: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); // Code @@ -338,9 +394,7 @@ case SAVE_DESET: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); break; - case SCROLL: - theEvents.push_back(lEvent(evtType,centre.x,centre.y)); - break; + case SCROLL_STOPPED: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); cout << "SCROLL STOPPED EVENT\n"; @@ -349,12 +403,6 @@ theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID)); cout << "SCROLL STOPPED EVENT\n"; break; - case ZOOM: - theEvents.push_back(lEvent(evtType,scale)); - break; - case CHANGE_SLIDER: - theEvents.push_back(lEvent(evtType,sliderVal , 0.0 , sliderID)); - break; case SWAP_VIEW: theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view break; @@ -368,11 +416,8 @@ uploadEventLog(true); } //sessionTime = (ofGetSystemTime() - sessionStartTime); - totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); - if(totalInteractionTime > QUESTIONNAIRE_ENABLE_TIME){ - TopButtonViewController *tbvc = ((testApp *)ofGetAppPtr())->topButtonViewController; - [tbvc enableQuestionButton]; - } + totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); // milliseconds + } //--------------------------------------------------------------------------- @@ -419,7 +464,7 @@ root["questionnaireCompleted"] = questionnaireCompleted; root["questionnaireUploaded"] = questionnaireUploaded; if(questionnaireCompleted && !questionnaireUploaded){ - root["qAnswers"] = questionnaireToJson(); + root["questionnaire"] = questionnaireToJson(); } int i = 0; @@ -446,8 +491,10 @@ questionnaire[i] = (*aIter); i++; } + cout << questionnaireComments << "\n"; root["qAnswers"] = questionnaire; + root["comments"] = questionnaireComments; root["userName"] = userName; root["deviceID"] = deviceID; root["iOSdeviceType"] = iOSdeviceType; diff -r ae4d2c3ce5e0 -r e2c62db1e265 testApp.h --- a/testApp.h Wed Feb 13 17:03:56 2013 +0000 +++ b/testApp.h Mon Feb 18 11:45:05 2013 +0000 @@ -109,7 +109,7 @@ void lockSequencerPressed(bool locked); void showQuestionnaire(); - void questionnaireHidden(vector answers); + void questionnaireHidden(vector answers, const char* userComments); void showIntro(); void introHidden(bool OK); void interfaceSelected(int which); diff -r ae4d2c3ce5e0 -r e2c62db1e265 testApp.mm --- a/testApp.mm Wed Feb 13 17:03:56 2013 +0000 +++ b/testApp.mm Mon Feb 18 11:45:05 2013 +0000 @@ -25,7 +25,7 @@ // open an outgoing connection to HOST:PORT sender.setup( HOST, PORT ); - ofSetFrameRate(30); + ofSetFrameRate(50); // reciever lastMoveTime = ofGetSystemTimeMicros(); prevTouchX = 0; @@ -82,10 +82,9 @@ [ofxiPhoneGetGLParentView() addSubview:bottomTabViewController.view]; [bottomTabViewController setAppRef:(id)this]; - [bottomTabViewController show:(id)this]; - bottomTabViewController.view.frame = CGRectMake(0,getHeight()-44,getWidth(),44); + ///// topButtonViewController = [[TopButtonViewController alloc] initWithNibName:@"TopButtonViewController" bundle:nil]; @@ -115,6 +114,8 @@ presetManager.startupLoadAll(); eventLogger.init(); + // timer.init(); + whichInterfaceShowing = SLIDERS; setAllGUISliders(theGridView.getParams()); // GO @@ -210,16 +211,16 @@ } //-------------------------------------------------------------- -void testApp::questionnaireHidden(vector answers){ +void testApp::questionnaireHidden(vector answers, const char* userComments){ // send answers to server as json - eventLogger.questionnaireAnswersObtained(answers); + eventLogger.questionnaireAnswersObtained(answers, userComments); // set "we've done questionnaire" to true in event logger paused = false; whichInterfaceShowing = BOTH; // tell bottomtabviewcontroller - + [bottomTabViewController show:(id)this]; } //-------------------------------------------------------------- void testApp::showIntro(){ @@ -298,6 +299,7 @@ ofxUISlider *slider; slider = (ofxUISlider *)sliderGUI->addWidgetDown(new ofxUISlider(length,dim,0.0,127,64,sliderParamNames[i-1])); slider->setDrawPadding(true); + slider->setDrawPaddingOutline(true); if(i <= 5){ slider->setColorFill(ofColor(0,0,255)); slider->setColorFillHighlight(ofColor(0,0,255)); @@ -428,7 +430,7 @@ if(moveVel.norm() > 0.3){ if(theGridView.snapped){ - // stop it, send snap event + // stop it (snap check sends snap event) moveVel.setCoord(0.0,0.0); }else{ theGridView.move(moveVel); @@ -449,6 +451,7 @@ } } + // ZOOM MOMENTUM // continiue to zoom at velocity if (numActiveTouches < 2 && abs(zoomVel)>0.001){ theGridView.zoom(zoomVel + 1.0); // +1 because zoomVel factor is + or - , wheras zoom is a multiplier near 1