Mercurial > hg > tweakathon2ios
view testApp.mm @ 7:4e00f92567d9
separated GUI setup stuff
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Fri, 17 Oct 2014 15:13:35 +0100 |
parents | 92850a2b099c |
children | d59de9fd3496 |
line wrap: on
line source
#include "testApp.h" #include "ofAppiOSWindow.h" #include "ExplorePresetManager.h" extern EventLogger eventLogger; extern ExplorePresetManager expPresetManager; // static members inited here. not my choice. int SynthParam::mappingUID = 88000; //-------------------------------------------------------------- void testApp::setup(){ ofxiPhoneSetOrientation( OF_ORIENTATION_90_LEFT ); //ofxiPhoneExternalDisplay::mirrorOn(); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; // initilaise initialiseVariables(); testController = new TestController; expPresetManager.onAppLoad(); //presetManager.startLoadAll(); messageOrganiser.init(&core, testController); timeController.init(); initialiseGUIs(); initialiseMIDI(); setupUIElements(); light.setSpotlight(45. , 1.); light.enable(); ofEnableSeparateSpecularLight(); ofEnableDepthTest(); ofEnableAlphaBlending(); // in setup: myfont.loadFont("NewMedia Fett.ttf", 32); verdBig.loadFont("verdana.ttf", 18, true, true); verdBig.setLineHeight(18.0f); verdBig.setLetterSpacing(1.037); //-------------------------------------- eventLogger.startLoadAll(); //-------------------------------------- // now do things that will affect the start up state of the app // initialise PD int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512 core.setup(2, 2, 44100, ticksPerBuffer); // setup OF sound stream bufSize = ofxPd::blockSize()*ticksPerBuffer; wavetableNew = (float *) malloc(bufSize * sizeof(float)); ofSoundStreamSetup(2, 2, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3); if(true){ // force start startTheTests(); }else{ if(eventLogger.questionnaireCompleted){ // then show play again dialog, and log the test number }else{ // then we're in timed session mode showIntro(); } } paused = false; eventLogger.logEvent(APP_LOADED); ofSoundStreamStart(); } //----------------------------------------------------------------------------- //DeviceID3523537000 void testApp::initialiseVariables(){ paused = true; ofBackground( 0, 0, 0 ); //ofEnableAlphaBlending(); //ofEnableSmoothing(); // open an outgoing connection to HOST:PORT for OSC // sender.setup( OSC_HOST, OSC_PORT ); ofSetFrameRate(60); } //--------------------------------------------------------- void testApp::initialiseGUIs(){ // set up iOS gui stuff helpViewController = [[HelpViewController alloc] initWithNibName:@"HelpViewController" bundle:nil]; [ofxiPhoneGetGLParentView() addSubview:helpViewController.view]; [helpViewController setAppRef:(__bridge id)this]; helpViewController.view.hidden = YES; usernameAlertViewController = [[UsernameAlertViewController alloc] init]; [usernameAlertViewController setAppRef:(__bridge id)this]; } //-------------------------------------------------------------- // GUI for finding and saving presets to express concepts void testApp::setupExpressViewPanels(){ } //-------------------------------------------------------------- // gui for the main training stage void testApp::setupTrainingViewPanels(){ } //-------------------------------------------------------------- // gui for the old style tweakathlon stage void testApp::setupSearchViewPanels(){ UIProps p; ButtonPanel* bottomButtonPanel = new ButtonPanel(1,160+p.sliderPanelHeight,ofGetWidth(),250,p); Buttron* playTargetButton = new Buttron(p.buttonWidth*0.2,680, p); playTargetButton->setLabel("Target"); messageOrganiser.mapButtonToAction(playTargetButton, TRIGGER_TARGET_ID); bottomButtonPanel->addButton(playTargetButton); messageOrganiser.setTargetButton(playTargetButton); Buttron * playCandidateButton = new Buttron(p.buttonWidth*1.4,680, p); playCandidateButton->setLabel("Current"); messageOrganiser.mapButtonToAction(playCandidateButton, TRIGGER_CANDIDATE_ID); bottomButtonPanel->addButton(playCandidateButton); // submit button - only one for now Buttron * submitButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p); submitButton->setLabel("Submit"); messageOrganiser.mapButtonToAction(submitButton, SUBMIT_CANDIDATE); bottomButtonPanel->addButton(submitButton); // button - just for spacing pruposes Buttron * saveButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p); saveButton->setLabel("SAVE"); messageOrganiser.mapButtonToAction(saveButton, SAVE_PRESET_HIT); bottomButtonPanel->addButton(saveButton); saveButton->hide(); Buttron * recallButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p); recallButton->setLabel("RECALL"); messageOrganiser.mapButtonToAction(recallButton, RECALL_PRESET_HIT); bottomButtonPanel->addButton(recallButton); recallButton->hide(); messageOrganiser.setBottomPanel(bottomButtonPanel); UIElements.push_back(bottomButtonPanel); bottomButtonPanel->showBorder(false); // - - - - - -- - - OTHER BITS CountdownText * countDownBox = new CountdownText("5" , 500, 380, 455, 455, p); UIElements.push_back(countDownBox); messageOrganiser.setCountdownPanel(countDownBox); countDownBox->hide(); TextPanel * scoreFeedback = new TextPanel("Feedback panel", ofGetWidth()*0.5 - p.buttonWidth*0.5, 666, 400,100,p); scoreFeedback->setFontSize(SMALLFONT); UIElements.push_back(scoreFeedback); messageOrganiser.setScorePanel(scoreFeedback); scoreFeedback->hide(); TextPanel * finishPanel = new TextPanel("Finish txt panel", 250, 250, 1000,400,p); finishPanel->setFontSize(LARGEFONT); finishPanel->setText("Experiment completed"); messageOrganiser.setFinishPanel(finishPanel); UIElements.push_back(finishPanel); finishPanel->hide(); Buttron * newTestButton = new Buttron(ofGetWidth()-300,690, p); newTestButton->setLabel("Next Test"); UIElements.push_back(newTestButton); messageOrganiser.mapButtonToAction(newTestButton, NEW_TEST_ID); newTestButton->hide(); messageOrganiser.setNewTestButton(newTestButton); TargetSymbol* targetSymbol = new TargetSymbol(ofGetWidth()*0.5,160,30,p); messageOrganiser.setTargetSymbol(targetSymbol); UIElements.push_back(targetSymbol); } //-------------------------------------------------------------- void testApp::setupSliderPanel(){ UIProps p; vector<controllerType> sl2; sl2.push_back(SLIDER); SliderPanel * controlPanel = new SliderPanel(1, 160, ofGetWidth(), p.sliderPanelHeight, p, sl2); UIElements.push_back(controlPanel); messageOrganiser.setControlPanel(controlPanel); controlPanel->showBorder(true); } //-------------------------------------------------------------- void testApp::setupUIElements(){ UIProps p; ofBackground(p.generalBackground); setupSearchViewPanels(); setupSliderPanel(); } //-------------------------------------------------------------------------- void testApp::initialiseMIDI(){ ///////////////////////// // MIDI midiChannel = 8; midiOffset = 0; // enables the network midi session between iOS and Mac OSX on a // local wifi network // // in ofxMidi: open the input/outport network ports named "Session 1" // // on OSX: use the Audio MIDI Setup Utility to connect to the iOS device // ofxMidi::enableNetworking(); // list the number of available input & output ports ofxMidiIn::listPorts(); ofxMidiOut::listPorts(); // create and open input ports for(int i = 0; i < ofxMidiIn::getNumPorts(); ++i) { // new object inputs.push_back(new ofxMidiIn); // set this class to receive incoming midi events inputs[i]->addListener(this); // open input port via port number inputs[i]->openPort(i); } // create and open output ports for(int i = 0; i < ofxMidiOut::getNumPorts(); ++i) { // new object outputs.push_back(new ofxMidiOut); // open input port via port number outputs[i]->openPort(i); } // set this class to receieve midi device (dis)connection events ofxMidi::setConnectionListener(this); // END MIDI } //-------------------------------------------------------------- template <class T> void deleteVectorOfPointers( T * inVectorOfPointers ) { typename T::iterator i; for ( i = inVectorOfPointers->begin() ; i < inVectorOfPointers->end(); i++ ) { delete * i; } //delete inVectorOfPointers; } //-------------------------------------------------------------- void testApp::exit(){ eventLogger.logEvent(APP_EXITED); eventLogger.exitAndSave(); core.exit(); // are these handled automatically? //[introViewController release]; //[topButtonViewController release]; //[bottomTabViewController release]; // clean up MIDI for(int i = 0; i < inputs.size(); ++i) { inputs[i]->closePort(); inputs[i]->removeListener(this); delete inputs[i]; } for(int i = 0; i < outputs.size(); ++i) { outputs[i]->closePort(); delete outputs[i]; } deleteVectorOfPointers(&UIElements); // TODO this crashes?? delete testController; cout << "exit done \n"; } #pragma mark GUI //////////////////////////// // These functions called from iOS toolbars //-------------------------------------------------------------- //-------------------------------------------------------------- void testApp::showQuestionnaire(){ questionnaireViewController = [[QuestionnaireViewController alloc] initWithNibName:@"QuestionnaireViewController" bundle:nil]; [ofxiPhoneGetGLParentView() addSubview:questionnaireViewController.view]; [questionnaireViewController setAppRef:(__bridge id)this]; [questionnaireViewController show:(__bridge id)this]; whichInterfaceShowing = QUESTIONNAIRE; } //-------------------------------------------------------------- void testApp::questionnaireHidden(vector<int> answers, const char* userComments){ // send answers to server as json eventLogger.questionnaireAnswersObtained(answers, userComments); } //-------------------------------------------------------------- void testApp::showIntro(){ cout << "SHOW INTRO\n"; introViewController = [[IntroViewController alloc] initWithNibName:@"IntroViewController" bundle:nil]; [ofxiPhoneGetGLParentView() addSubview:introViewController.view]; [introViewController setAppRef:(__bridge id)this]; [introViewController show:(__bridge id)this]; whichInterfaceShowing = INTRO; } //-------------------------------------------------------------- void testApp::introHidden(){ eventLogger.consentGiven = true; eventLogger.logEvent(INTRO_CONSENTED); [usernameAlertViewController showUserNamePrompt]; // after prompt goes it calls usernameEntered() } void testApp::usernameEntered(){ // display a thing that gives us an option as to which stage to start // EXPLORE, PERFORMANCE TRAINING, SEARCH } //-------------------------------------------------------------- void testApp::startTheTests(){ eventLogger.logEvent(START_THE_TESTS); whichInterfaceShowing = COUNT_DOWN; // do countdown etc messageOrganiser.countdownToNewTest(); // TODO how is testApp going to kknow whichInterfaceShowing ??? } //-------------------------------------------------------------- //-------------------------------------------------------------- void testApp::showHelp(){ // stop clock etc previousInterface = whichInterfaceShowing; whichInterfaceShowing = HELP; helpViewController.view.hidden = NO; eventLogger.logEvent(HELP_PRESSED); } void testApp::helpHidden(){ whichInterfaceShowing = previousInterface; } //-------------------------------------------------------------- //-------------------------------------------------------------- //-------------------------------------------------------------- #pragma mark sending to pd and midi void testApp::sendParametersToPD(){ } //-------------------------------------------------------------- void testApp::sendMidiParam(int which){ int midiChannel = 8; int offset = 0; for(int i = 0; i < outputs.size(); ++i) { outputs[i]->sendControlChange(midiChannel, offset+which, 66); } } //-------------------------------------------------------------- //void testApp::sendOSCParams(){ // // ofxOscMessage m; // m.setAddress( "Template" ); // // m.addFloatArg(9.9999); // // sender.sendMessage( m ); //} //-------------------------------------------------------------- void testApp::setupNewUser(){ // this function is for supervised trials with my ipad eventLogger.newUser(); } //-------------------------------------------------------------- #pragma mark STANDARD OF FUNCTIONS //-------------------------------------------------------------- void testApp::update(){ if(paused) return; // run timer check here // look at time, work out difference timeController.tick(); // test mutex crash thing //eventLogger.logEvent(CANDIDATE_PLAYED); } //-------------------------------------------------------------- void testApp::appModeChange(interfaceType mode){ whichInterfaceShowing = mode; } //------------------------------------------------------------------------ void testApp::draw(){ switch (whichInterfaceShowing){ case QUESTIONNAIRE: break; case INTRO: break; case TEST_IN_PROGRESS: break; case SCORE_AND_HINT: break; case COUNT_DOWN: break; case READY_FOR_NEXT: break; default: break; } drawUIElements(); //ofSetColor(234, 234, 234); //ofLine(0,150,1024,150); //drawWaveform(); drawScore(); } //------------------------------------------------------------------------ void testApp::drawUIElements(){ vector<UIElement *>::iterator UIitr; for(UIitr = UIElements.begin(); UIitr < UIElements.end(); UIitr++){ (*UIitr)->draw(); } } //------------------------------------------------------------------------ void testApp::drawScore(){ ofColor txtCol = ofColor(150,235,200,255); int score = messageOrganiser.getScore(); stringstream msg; msg << "Test: " << testController->getCurrentTestLetter(); ofSetColor(txtCol); verdBig.drawString(msg.str(), 40, 140); msg.str(std::string()); msg << "Score: " << score; verdBig.drawString(msg.str(), 240, 140); msg.str(std::string()); pair<int,int> time; time = messageOrganiser.getTime(); msg << "Time taken: " << time.first << ":" << time.second << endl; verdBig.drawString(msg.str(), 600, 140); } //------------------------------------------------------------------------ //-------------------------------------------------------------- // passes touch to UI elements //-------------------------------------------------------------- void testApp::touchToUIElements(int x, int y, touchType ttype, int tid){ vector<UIElement *>::iterator UIitr; for(UIitr = UIElements.begin(); UIitr < UIElements.end(); UIitr++){ (*UIitr)->touch(x,y,ttype, tid); } } //-------------------------------------------------------------- void testApp::touchDown(ofTouchEventArgs &touch){ //touch = transformTouchCoords(touch); touchToUIElements(touch.x, touch.y, TOUCH_DOWN, touch.id); } //-------------------------------------------------------------- void testApp::touchMoved(ofTouchEventArgs &touch){ touchToUIElements(touch.x, touch.y, TOUCH_MOVED, touch.id); } //-------------------------------------------------------------- void testApp::touchUp(ofTouchEventArgs &touch){ touchToUIElements(touch.x, touch.y, TOUCH_UP, touch.id); } //-------------------------------------------------------------- void testApp::touchDoubleTap(ofTouchEventArgs &touch){ } //-------------------------------------------------------------- void testApp::lostFocus(){ //exit(); } //-------------------------------------------------------------- void testApp::gotFocus(){ } //-------------------------------------------------------------- void testApp::gotMemoryWarning(){ } //-------------------------------------------------------------- void testApp::deviceOrientationChanged(int newOrientation){ cout << "orientation: " << newOrientation; // do something here? } //-------------------------------------------------------------- void testApp::touchCancelled(ofTouchEventArgs& args){ } //--------------------------------------------------------------- // AUDIO STUFF //--------------------------------------------------------------- #pragma mark AUDIO STREAMS //-------------------------------------------------------------- void testApp::audioReceived(float * input, int bufferSize, int nChannels) { //core.audioReceived(input, bufferSize, nChannels); } void testApp::audioRequested(float * output, int bufferSize, int nChannels) { core.audioRequested(output, bufferSize, nChannels); // for(int i=0;i<bufferSize/2;i++){ // output[i] = 0.2; // } // // pass buffer to drawable thing // for(int i=0;i<bufferSize;i++){ // wavetableNew[i] = output[i]; // } } void testApp::drawWaveform(){ // draw the actual waveform in the corner int width = 768; int height = 128; double sampval = 0.0; int leftsampnum = 0; int rightsampnum = 0; float sampscale = 0.0, prevsampscale = 0.0, interp = 0.0; ofSetColor(256, 0, 0); double step = double(bufSize)/width; // how much we are stepping thru wave per pixel for(int i = 0; i < width; i++){ leftsampnum = floor(i * step); // basic nearest neighbour interpolation rightsampnum = ceil(i*step); interp = (i*step)-leftsampnum; if(rightsampnum < bufSize){ sampval = (1 - interp)*wavetableNew[leftsampnum] + interp*wavetableNew[rightsampnum]; } sampscale = (sampval * 700) + height/2.0; // centre and scale ofSetLineWidth(2); ofLine(sampscale, i, prevsampscale, i-1); // draw a line from pixel to pixel (?) prevsampscale = sampscale; } } //--------------------------------------------------------------- #pragma mark UTILITIES //------------------------------------------------------------------------- //-------------------------------------------------------------- #pragma mark MIDI void testApp::addMessage(string msg) { cout << msg << endl; messages.push_back(msg); while(messages.size() > maxMessages) messages.pop_front(); } //-------------------------------------------------------------- void testApp::newMidiMessage(ofxMidiMessage& msg) { // looks out for: 30 31 32... on channel 8 if(msg.channel == midiChannel && msg.status == MIDI_CONTROL_CHANGE){ int ctl_num = msg.control - 30; int ctl_val = msg.value; // TODO route control change message here //cout << " ctrl : " << ctl_num << " : " << ctl_val << endl; messageOrganiser.midiFromLeap(ctl_num, ctl_val); } } //-------------------------------------------------------------- void testApp::midiInputAdded(string name, bool isNetwork) { stringstream msg; msg << "ofxMidi: input added: " << name << " network: " << isNetwork; cout << msg.str(); addMessage(msg.str()); // create and open a new input port ofxMidiIn * newInput = new ofxMidiIn; newInput->openPort(name); newInput->addListener(this); inputs.push_back(newInput); } //-------------------------------------------------------------- void testApp::midiInputRemoved(string name, bool isNetwork) { stringstream msg; msg << "ofxMidi: input removed: " << name << " network: " << isNetwork << endl; cout << msg.str(); addMessage(msg.str()); // close and remove input port vector<ofxMidiIn*>::iterator iter; for(iter = inputs.begin(); iter != inputs.end(); ++iter) { ofxMidiIn * input = (*iter); if(input->getName() == name) { input->closePort(); input->removeListener(this); delete input; inputs.erase(iter); break; } } } //-------------------------------------------------------------- void testApp::midiOutputAdded(string name, bool isNetwork) { stringstream msg; msg << "ofxMidi: output added: " << name << " network: " << isNetwork << endl; cout << msg.str(); addMessage(msg.str()); // create and open new output port ofxMidiOut * newOutput = new ofxMidiOut; newOutput->openPort(name); outputs.push_back(newOutput); } //-------------------------------------------------------------- void testApp::midiOutputRemoved(string name, bool isNetwork) { stringstream msg; msg << "ofxMidi: output removed: " << name << " network: " << isNetwork << endl; cout << msg.str(); addMessage(msg.str()); // close and remove output port vector<ofxMidiOut*>::iterator iter; for(iter = outputs.begin(); iter != outputs.end(); ++iter) { ofxMidiOut * output = (*iter); if(output->getName() == name) { output->closePort(); delete output; outputs.erase(iter); break; } } }