void ofxTLKeyframes::mouseDragged(ofMouseEventArgs& args, long millis){

	if(keysAreStretchable){
		//cast the stretch anchor to long so that it can be signed
		float stretchRatio = 1.0*(millis-long(stretchAnchor)) / (1.0*stretchSelectPoint-stretchAnchor);

        for(int k = 0; k < selectedKeyframes.size(); k++){
            setKeyframeTime(selectedKeyframes[k], ofClamp(stretchAnchor + (selectedKeyframes[k]->grabTimeOffset * stretchRatio),
														  0, timeline->getDurationInMilliseconds()));
            selectedKeyframes[k]->screenPosition = screenPositionForKeyframe(selectedKeyframes[k]);
		}
        timeline->flagUserChangedValue();
        keysDidDrag = true;
        updateKeyframeSort();
	}

    if(keysAreDraggable && selectedKeyframes.size() != 0){
        ofVec2f screenpoint(args.x,args.y);
        for(int k = 0; k < selectedKeyframes.size(); k++){
            ofVec2f newScreenPosition;
            setKeyframeTime(selectedKeyframes[k], ofClamp(millis - selectedKeyframes[k]->grabTimeOffset,
														  screenXToMillis(bounds.getMinX()), screenXToMillis(bounds.getMaxX())));
            selectedKeyframes[k]->value = screenYToValue(args.y - selectedKeyframes[k]->grabValueOffset);
            selectedKeyframes[k]->screenPosition = screenPositionForKeyframe(selectedKeyframes[k]);
        }
        if(selectedKeyframe != NULL && timeline->getMovePlayheadOnDrag()){
            timeline->setCurrentTimeMillis(selectedKeyframe->time);
        }
        timeline->flagUserChangedValue();
        keysDidDrag = true;
        updateKeyframeSort();
    }
	createNewOnMouseup = false;
}
void ofxTLKeyframes::deleteSelectedKeyframes(){
	//vector<ofxTLKeyframe*>::iterator selectedIt = selectedKeyframes.end();
	for(int i = keyframes.size() - 1; i >= 0; i--){
		if(isKeyframeSelected(keyframes[i])){
			if(keyframes[i] != selectedKeyframes[selectedKeyframes.size()-1]){
				ofLogError("ofxTLKeyframes::deleteSelectedKeyframes") << "keyframe delete inconsistency";
			}
			willDeleteKeyframe(keyframes[i]);
			if(keyframes[i] == hoverKeyframe){
				hoverKeyframe = NULL;
			}
			delete keyframes[i];
			keyframes.erase(keyframes.begin()+i);
			//if(selectedIt != selectedKeyframes.begin()){
//				selectedIt--;
				selectedKeyframes.erase(--selectedKeyframes.end());
			//}
		}
	}
	
	selectedKeyframes.clear();
	updateKeyframeSort();
    
    timeline->flagTrackModified(this);
}
void ofxTLKeyframer::load() {
    ofxXmlSettings savedkeyframes;

    cout << "Loading keyframe file " << xmlFileName << endl;

    if(!savedkeyframes.loadFile(xmlFileName)) {
        ofLog(OF_LOG_ERROR, "ofxTLKeyframer --- couldn't load xml file " + xmlFileName);
        reset();
        return;
    }

    clear();

    savedkeyframes.pushTag("keyframes");
    int numKeyTags = savedkeyframes.getNumTags("key");

    for(int i = 0; i < numKeyTags; i++) {
        savedkeyframes.pushTag("key", i);
        ofxTLKeyframe* key = newKeyframe(ofVec2f(savedkeyframes.getValue("x", 0.0),
                                         savedkeyframes.getValue("y", 0.0)));

        key->easeFunc = easingFunctions[ofClamp(savedkeyframes.getValue("easefunc", 0), 0, easingFunctions.size()-1)];
        key->easeType = easingTypes[ofClamp(savedkeyframes.getValue("easetype", 0), 0, easingTypes.size()-1)];

        savedkeyframes.popTag(); //key

    }

    savedkeyframes.popTag();//keyframes

    updateKeyframeSort();
}
void ofxTLKeyframes::pasteSent(string pasteboard){
	vector<ofxTLKeyframe*> keyContainer;
	ofxXmlSettings pastedKeys;
	
	if(pastedKeys.loadFromBuffer(pasteboard)){
		createKeyframesFromXML(pastedKeys, keyContainer);
		if(keyContainer.size() != 0){
			timeline->unselectAll();
			int numKeyframesPasted = 0;
			//normalize and add at playhead
			//for(int i = 0; i < keyContainer.size(); i++){
			for(int i = keyContainer.size()-1; i >= 0; i--){
				keyContainer[i]->time -= keyContainer[0]->time;
				keyContainer[i]->time += timeline->getCurrentTimeMillis();
				if(keyContainer[i]->time <= timeline->getDurationInMilliseconds()){
					selectedKeyframes.push_back(keyContainer[i]);
					keyframes.push_back(keyContainer[i]);
					numKeyframesPasted++;
				}
				else{
					delete keyContainer[i];
				}
			}

			if(numKeyframesPasted > 0){
				updateKeyframeSort();
				timeline->flagTrackModified(this);
			}
			
//			if(timeline->getMovePlayheadOnPaste()){
//				timeline->setCurrentTimeMillis( keyContainer[keyContainer.size()-1]->time );
//			}
		}
	}
}
示例#5
0
void ofxTLKeyframes::nudgeBy(ofVec2f nudgePercent){
	for(int i = 0; i < selectedKeyframes.size(); i++){
		selectedKeyframes[i]->time  = ofClamp(selectedKeyframes[i]->time + timeline->getDurationInMilliseconds()*nudgePercent.x, 0, timeline->getDurationInMilliseconds());
		selectedKeyframes[i]->value = ofClamp(selectedKeyframes[i]->value + nudgePercent.y, 0, 1.0);
	}	
	updateKeyframeSort();
    timeline->flagTrackModified(this);
}
void ofxTLKeyframes::loadFromXMLRepresentation(string rep){
    clear();
    ofxXmlSettings buffer;
    buffer.loadFromBuffer(rep);
    createKeyframesFromXML(buffer, keyframes);
    updateKeyframeSort();
    timeline->flagUserChangedValue();    //because this is only called in Undo we don't flag track modified
}
void ofxTLKeyframes::regionSelected(ofLongRange timeRange, ofRange valueRange){
    for(int i = 0; i < keyframes.size(); i++){
        if(timeRange.contains(keyframes[i]->time) && valueRange.contains(1.-keyframes[i]->value)){
            selectKeyframe(keyframes[i]);
        }
	}
	updateKeyframeSort();
}
void ofxTLFlags::addFlagAtTime(string key, unsigned long long time){
	ofxTLKeyframe* keyFrame = newKeyframe();
	ofxTLFlag* flag = (ofxTLFlag*)keyFrame;
	setKeyframeTime(keyFrame, time);
	flag->textField.text = key;
	keyframes.push_back(keyFrame);
	updateKeyframeSort();
	timeline->flagTrackModified(this);
}
void ofxTLKeyframes::clear(){

	for(int i = 0; i < keyframes.size(); i++){
		willDeleteKeyframe(keyframes[i]);
		delete keyframes[i];
	}
	keyframes.clear();
    selectedKeyframes.clear();
	updateKeyframeSort();
}
void ofxTLKeyframes::addKeyframeAtMillis(float value, unsigned long long millis){
	ofxTLKeyframe* key = newKeyframe();
	key->time = key->previousTime = millis;
	key->value = ofMap(value, valueRange.min, valueRange.max, 0, 1.0, true);
	keyframes.push_back(key);
	//smart sort, only sort if not added to end
	if(keyframes.size() > 2 && keyframes[keyframes.size()-2]->time > keyframes[keyframes.size()-1]->time){
		updateKeyframeSort();
	}
	lastKeyframeIndex = 1;
	timeline->flagTrackModified(this);
	shouldRecomputePreviews = true;
}
示例#11
0
void ofxTLFlags::addFlagAtTime(string key, unsigned long long time){
//	cout << "***ADDING FLAG WITH TIME " << time << endl;
	if(time > 2000000){
		cout << "***UNITITED VAR " << time << endl;
		return;
	}
	ofxTLKeyframe* keyFrame = newKeyframe();
	ofxTLFlag* flag = (ofxTLFlag*)keyFrame;
	setKeyframeTime(keyFrame, time);
	flag->textField.text = key;
	keyframes.push_back(keyFrame);
	updateKeyframeSort();
	timeline->flagTrackModified(this);
}
void ofxTLKeyframes::load(){
    clear();
	if(useBinarySave){
		loadFromBinaryFile();
	}
	else{
		ofxXmlSettings savedkeyframes;
		if(!savedkeyframes.loadFile(xmlFileName)){
			ofLog(OF_LOG_NOTICE, "ofxTLKeyframes --- couldn't load xml file " + xmlFileName);
			return;
		}
		
		createKeyframesFromXML(savedkeyframes, keyframes);
	}
	updateKeyframeSort();
	timeline->flagTrackModified(this);
}
示例#13
0
void ofxTLKeyframes::mouseDragged(ofMouseEventArgs& args, long millis){

    if(keysAreDraggable && selectedKeyframes.size() != 0){
        ofVec2f screenpoint(args.x,args.y);
        for(int k = 0; k < selectedKeyframes.size(); k++){
            ofVec2f newScreenPosition;
            selectedKeyframes[k]->time = millis - selectedKeyframes[k]->grabTimeOffset;
            selectedKeyframes[k]->value = screenYToValue(args.y - selectedKeyframes[k]->grabValueOffset);
            selectedKeyframes[k]->screenPosition = screenPositionForKeyframe(selectedKeyframes[k]);
        }
        if(selectedKeyframe != NULL && timeline->getMovePlayheadOnDrag()){
            timeline->setCurrentTimeMillis(selectedKeyframe->time);
        }
        timeline->flagUserChangedValue();
        keysDidDrag = true;
        updateKeyframeSort();
    }
	createNewOnMouseup = false;
}
示例#14
0
void ofxTLNotes::addKeyframeAtMillis(int pitch, float velocity, unsigned long millis, bool isGrowing){
	ofxTLNote* key = (ofxTLNote*)newKeyframe();
	key->time = key->previousTime = millis;
    key->timeRange.min = millis;
    key->timeRange.max = millis + 100;
    key->pitch = pitch;
    key->velocity = velocity;
    cout << "added keyframe with velocity " << key->velocity << endl;
	key->value = ofMap(pitch, valueRange.min, valueRange.max, 0, 1, true);
    key->growing = isGrowing;
	keyframes.push_back(key);
	//smart sort, only sort if not added to end
	if(keyframes.size() > 2 && keyframes[keyframes.size()-2]->time > keyframes[keyframes.size()-1]->time){
		updateKeyframeSort();
	}
    trimToPitches();
	lastKeyframeIndex = 1;
	timeline->flagTrackModified(this);
	shouldRecomputePreviews = true;
}
void ofxTLKeyframes::mouseReleased(ofMouseEventArgs& args, long millis){
	keysAreDraggable = false;
    if(keysDidDrag){
		//reset these caches because they may no longer be valid
		lastKeyframeIndex = 1;
		lastSampleTime = 0;
        timeline->flagTrackModified(this);
    }
	
	if(createNewOnMouseup){
		//add a new one
		selectedKeyframe = newKeyframe();
		setKeyframeTime(selectedKeyframe,millis);
		selectedKeyframe->value = screenYToValue(args.y);
		keyframes.push_back(selectedKeyframe);
		selectedKeyframes.push_back(selectedKeyframe);
		updateKeyframeSort();
		timeline->flagTrackModified(this);
	}
	createNewOnMouseup = false;
}
示例#16
0
void ofxTLKeyframer::mousePressed(ofMouseEventArgs& args) {
    if(!enabled) return;

    ofVec2f screenpoint = ofVec2f(args.x, args.y);
    if(drawingEasingWindow) {
        //see if we clicked on an
        drawingEasingWindow = false;

        for(int i = 0; i < easingFunctions.size(); i++) {
            if(easingFunctions[i]->bounds.inside(screenpoint-easingWindowPosition)) {
                selectedKeyframe->easeFunc = easingFunctions[i];
                if(autosave) save();
                return;
            }
        }
        for(int i = 0; i < easingTypes.size(); i++) {
            if(easingTypes[i]->bounds.inside(screenpoint-easingWindowPosition)) {
                selectedKeyframe->easeType = easingTypes[i];
                if(autosave) save();
                return;
            }
        }
    }

    bool clickIsInRect = screenpointIsInBounds(screenpoint);
    if(!focused) {
        focused = clickIsInRect;
        if(!focused) {
            selectedKeyframe = NULL;
            drawingEasingWindow = false;
        }
        return;
    }

    if(!clickIsInRect) {
        focused = false;
        selectedKeyframe = NULL;
        drawingEasingWindow = false;
        return;
    }

    selectedKeyframe = keyframeAtScreenpoint(screenpoint, selectedKeyframeIndex);
    //cout << "selected index is " << selectedKeyframeIndex << endl;
    if(selectedKeyframe == NULL) {
        //add a new one
        selectedKeyframe = newKeyframe( keyframePointForCoord(screenpoint) );

        grabOffset = ofVec2f(0,0);
        updateKeyframeSort();
        //find bounds
        for(int i = 0; i < keyframes.size(); i++) {
            if(keyframes[i] == selectedKeyframe) {
                selectedKeyframeIndex = i;
            }
        }
    }

    //grabbed a keyframe
    if(selectedKeyframe != NULL) {
        timeline->setPercentComplete(selectedKeyframe->position.x);

        if(args.button == 0) {
            grabOffset = screenpoint - coordForKeyframePoint(selectedKeyframe->position);
            if(keyframes.size() == 1) {
                minBound = 0.0;
                maxBound = 1.0;
            }
            else if(selectedKeyframeIndex == 0) {
                minBound = 0.0;
                maxBound = keyframes[selectedKeyframeIndex+1]->position.x;
            }
            else if(selectedKeyframeIndex == keyframes.size()-1) {
                minBound = keyframes[selectedKeyframeIndex-1]->position.x;
                maxBound = 1.0;
            }
            else {
                minBound = keyframes[selectedKeyframeIndex-1]->position.x;
                maxBound = keyframes[selectedKeyframeIndex+1]->position.x;
                //cout << "keyframe point is " << selectedKeyframe->position.x << " min bound is " << minBound << " max bound is " << maxBound << endl;
            }
        }
        else if(args.button == 2) {
            easingWindowPosition = screenpoint;
            drawingEasingWindow = true;
        }
    }
}
bool ofxTLKeyframes::mousePressed(ofMouseEventArgs& args, long millis){
	
	ofVec2f screenpoint = ofVec2f(args.x, args.y);
	keysAreStretchable = ofGetModifierShiftPressed() && ofGetModifierControlPressed();
    keysDidDrag = false;
	if(keysAreStretchable && timeline->getTotalSelectedItems() > 1){
		unsigned long long minSelected = timeline->getEarliestSelectedTime();
		unsigned long long maxSelected = timeline->getLatestSelectedTime();
		if(minSelected == maxSelected){
			keysAreStretchable = false;
		}
		else {
			unsigned long long midSelection = (maxSelected-minSelected)/2 + minSelected;
			//the anchor is the selected key opposite to where we are stretching
			stretchAnchor = midSelection <= millis ? minSelected : maxSelected;
//			cout << "Min selected " << ofxTimecode::timecodeForMillis(minSelected) << " Mid Selected " << ofxTimecode::timecodeForMillis(midSelection) << " Max selected " << ofxTimecode::timecodeForMillis(maxSelected) << " anchor "  << ofxTimecode::timecodeForMillis(stretchAnchor) << " millis down " << ofxTimecode::timecodeForMillis(millis) << endl;
			stretchSelectPoint = millis;
			//don't do anything else, like create or deselect keyframes
			updateStretchOffsets(screenpoint, millis);
		}
		return true;
	}
	
    keysAreDraggable = !ofGetModifierShiftPressed();
	selectedKeyframe =  keyframeAtScreenpoint(screenpoint);
    //if we clicked OFF of a keyframe OR...
    //if we clicked on a keyframe outside of the current selection and we aren't holding down shift, clear all
    if(!ofGetModifierSelection() && (isActive() || selectedKeyframe != NULL) ){
        bool didJustDeselect = false;
	    if( selectedKeyframe == NULL || !isKeyframeSelected(selectedKeyframe)){
            //settings this to true causes the first click off of the timeline to deselct rather than create a new keyframe
            didJustDeselect = timeline->getTotalSelectedItems() > 1;
    	    timeline->unselectAll();
        }

        //if we didn't just deselect everything and clicked in an empty space add a new keyframe there
        if(selectedKeyframe == NULL && !didJustDeselect){
			createNewOnMouseup = args.button == 0 && !ofGetModifierControlPressed();
        }
    }

	if(selectedKeyframe != NULL){
         //add the keyframe to the selection, whether it was just generated or not
    	if(!isKeyframeSelected(selectedKeyframe)){
			selectedKeyframes.push_back(selectedKeyframe);
			updateKeyframeSort();
//			selectKeyframe(selectedKeyframe);
        }
        //unselect it if it's selected and we clicked the key with shift pressed
        else if(ofGetModifierSelection()){
        	deselectKeyframe(selectedKeyframe);
			selectedKeyframe = NULL;
        }
	}
	
    //if we have any keyframes selected update the grab offsets and check for showing the modal window
	if(selectedKeyframes.size() != 0){
        updateDragOffsets(screenpoint, millis);
		if(selectedKeyframe != NULL){

			if(args.button == 0 && !ofGetModifierSelection() && !ofGetModifierControlPressed()){

	            timeline->setDragTimeOffset(selectedKeyframe->grabTimeOffset);
				//move the playhead
				if(timeline->getMovePlayheadOnDrag()){
					timeline->setCurrentTimeMillis(selectedKeyframe->time);
				}
			}
			if(args.button == 2 || ofGetModifierControlPressed()){
				selectedKeySecondaryClick(args);
			}
		}
	}
	return selectedKeyframe != NULL;
}