view MessageOrganiser.h @ 17:2a7320a8cbed

explore mode shows stuff, can go thru saving various presets.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Tue, 21 Oct 2014 18:58:25 +0100
parents 2da0350a4aa2
children 36cdb73691da
line wrap: on
line source
//
//  MessageOrganiser.h
//  tweakathlon
//
//  Created by Robert Tubb on 10/12/2013.
//
// This object handles the mapping from GUI to params
//
// and sends their messages to PD and eventLogger
#pragma once
#include "eventLogger.h"
#include <map.h>
#include <vector>
#include <string>
#include "boost/bind.hpp"
#include "boost/function.hpp"

#include <UIElement.h>
#include <Buttron.h>
#include <ButtronSlider.h>
#include <ButtronXY.h>
#include "TestController.h"
#include "timeController.h"
#include "PDSynthWrapper.h"
#include "ofxTimer.h"
#include "sliderPanel.h"
//#include "testApp.h"
#include "targetSymbol.h"
#include "3Dbox.h"
#include "TextPanel.h"
#include "CountdownText.h"
#include "buttonPanel.h"
#include "ExplorePresetManager.h"
#include "IconPanel.h"

// should be called TIMED TEST MESSAGE ORGANISER ?

// event logger needs to know
// which controls were showing in what mode
// which controls were mapped to what param
// what was the target sound params
// all the updates of control movements, submit, quit etc

// this is the bit that handles mapping from UI elements to synth i.e testApp DOESNT DO THAT

// has links to panel sliders can show hide them

// controls flow of stuff

//---------------------------------------------------------------------
//---------------------------------------------------------------------
extern TimeController timeController;

extern EventLogger eventLogger;

extern ExplorePresetManager expPresetManager;

//typedef boost::function<void(void)> AppModeChangeFunction;

class MessageOrganiser {
    
public:
    void init(PDSynthWrapper& cs, PDSynthWrapper& ts){
        candidateSynth = cs;
        targetSynth = ts;
        
        onlyChangeCandidateOnTrigger = true;
    }
    // could template for ui element type??
    void mapButtonToAction(UIElement* control, int mappingID){
        UICallbackFunction callbackF;
        callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2);
        control->addHandler(callbackF, mappingID);
        currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
    }
    
    
    void setControlPanel(SliderPanel* p){ // a bit specific?? 
        panel = p;
        
    };
    void setBottomPanel(ButtonPanel * ntb){
        bottomPanel = ntb;
    };
    
    
    void setIconPanel(IconPanel * ip){
        presetIconPanel = ip;
    }
    void setInstructionPanel(TextPanel * ip){
        instructionPanel = ip;
        instructionPanel->show();
    }

    
    //-----------------------------------------------------------------------------
    void hideMyPanels(){
        presetIconPanel->hide();
        instructionPanel->hide();
        bottomPanel->hide();
        panel->hide();
    }
    void showMyPanels(){
        presetIconPanel->show();
        instructionPanel->show();
        bottomPanel->show();
        panel->show();
    }
protected:

    PDSynthWrapper candidateSynth;
    PDSynthWrapper targetSynth;
    ButtonPanel* bottomPanel; // shows during test : play buttons and submit
    SliderPanel* panel;
    
    IconPanel* presetIconPanel;
    TextPanel* instructionPanel;
    
    map<int,UIElement*> currentMapping; // could get more sophisticated if not 1-1 ?
    

    void triggerCandidateSound(){
        // log event
        sendSynthValuesAgain();
        candidateSynth.trigger();
        eventLogger.logEvent(CANDIDATE_PLAYED);
        // flash panel?
        panel->flash();
    }
    
    void paramChangeCallback(int mappingID, int value){
        
        if(onlyChangeCandidateOnTrigger){
            candidateSynth.paramChangeCallback(mappingID, value, false);
        }else{
            candidateSynth.paramChangeCallback(mappingID, value, true);
        }
    
        vector<int> evtData;
        evtData.push_back(mappingID); // or just index?
        evtData.push_back(value);
        
        eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
    };

    void sendSynthValuesAgain(){
        candidateSynth.sendAllParams();
        targetSynth.sendAllParams();
    };
 
    
    void setAllSlidersToValues(vector<int> values){
        for(int i = 0; i < values.size(); i++){
            setUIToParam(i, values[i]);
        }
    }
    // we want to set UI object
    void setUIToParam(int index, int value){ // e.g. from MIDI incoming, will handle both box and sliders...
        // theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
        UIElement* elem;
        // get the element
        if(panel->subElements.size() <= index){
            cout << "ERROR: index out of range for num sliders" << endl;
            return;
        }
        elem = panel->subElements[index];
        if ( elem->getType() == SLIDER){
            ButtronSlider* theSlider = (ButtronSlider*)elem;
            theSlider->setValueAndScale(value);
            
        }else{
            cout << "ERROR ERROR: ui type not handled by setUIToParam!" << endl;
        }
        
    };
    
    
    void mapControlToParam(UIElement* control, int mappingID){
        
        UICallbackFunction callbackF;
        callbackF = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
        control->addHandler(callbackF, mappingID);
        // put in our map so we can send param values to gui
        currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
        cout << " Mapped control to ID: " << mappingID << "Name: " << candidateSynth.getNameForMappingID(mappingID) << endl;
        control->setLabel(candidateSynth.getNameForMappingID(mappingID));
    };
    
    //-----------------------------------------------------------------------------
    
    void mapSlidersToParams(vector<UIElement*> elems, vector<int> mids){
        
        vector<UIElement*>::iterator elit;
        vector<int> typeListLog;
        int i = 0;
        for(elit=elems.begin(); elit<elems.end();elit++){
            if ( (*elit)->getType() == SLIDER){
                if(i >= mids.size()){
                    
                    cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl;
                }
                
                ButtronSlider* theSlider = (ButtronSlider*)(*elit);
                mapControlToParam((*elit), mids[i]);
                theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i]));
                cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl;
                theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])));
                i++;
                typeListLog.push_back(int(SLIDER));
                
            }else{
                cout << "ERROR ERROR: ui type not handled my mapping function !" << endl;
            }
        }
        
        eventLogger.logEvent(CONTROL_LIST,typeListLog);
    };
    
    void mapXYToParams(ButtronXY* control, int mappingIDX, int mappingIDY){
        UICallbackFunction callback;
        
        callback = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
        
        control->addHandler(callback, mappingIDX, mappingIDY);
        
        // put in our map so we can send param values to gui
        //currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
        
        
        cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl;
        cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl;
        control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY));
        
    };

    
    void mapControlToParam(UIElement* control, string paramName){
        // get mapping ID from synth
        int mappingID = candidateSynth.getMappingIDForName(paramName);
        mapControlToParam(control, mappingID);
        control->setLabel(paramName);
    };

    virtual void buttonPressCallback(int mappingID, int value){
        
    };

    
    void setSlidersToTarget(){
        // this will actually show sliders with target vals - for "memorisation" purposes mwa heh heh
        // get target values
        // set ui
        vector<int> vals = targetSynth.getAllParamValues();
        for(int i=1; i < vals.size(); i++){
            setUIToParam(i, vals[i]);
        }
    }
    void setSlidersToDefault(){
        for(int i=1; i < targetSynth.getNumParams(); i++){
            setUIToParam(i, 0);
        }
    }
    
    bool onlyChangeCandidateOnTrigger;

};