bool ofxTLKeyframes::mousePressed(ofMouseEventArgs& args, long millis){ ofVec2f screenpoint = ofVec2f(args.x, args.y); keysAreDraggable = !ofGetModifierShiftPressed(); keysDidDrag = false; 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); } //unselect it if it's selected and we clicked the key with shift pressed else if(ofGetModifierSelection()){ deselectKeyframe(selectedKeyframe); selectedKeyframe = NULL; } } // if(isActive()){ // cout << "MOUSE PRESSED args button " << args.button << " control pressed? " << (ofGetModifierControlPressed() ? "YES":"NO") << " shift/cmd pressed? " << (ofGetModifierSelection() ? "YES":"NO") << endl; // } //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; }
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 ofxTLKeyframes::getSnappingPoints(set<unsigned long long>& points){ for(int i = 0; i < keyframes.size(); i++){ if (isKeyframeIsInBounds(keyframes[i]) && !isKeyframeSelected(keyframes[i])) { points.insert(keyframes[i]->time); } } }
//draw your keyframes into bounds void ofxTLEmptyKeyframes::draw(){ ofPushStyle(); ofFill(); //show the current color as background based on the playhead position ofSetColor(getCurrentColor(), 100); ofDrawRectangle(bounds); for(int i = 0; i < keyframes.size(); i++){ //make sure it's on screen if(isKeyframeIsInBounds(keyframes[i])){ //we know the type because we created it in newKeyframe() //so we can safely cast ofxTLEmptyKeyframe* emptyKeyframe = (ofxTLEmptyKeyframe*)keyframes[i]; if(hoverKeyframe == emptyKeyframe){ ofSetColor(timeline->getColors().highlightColor); } else if(isKeyframeSelected(emptyKeyframe)){ ofSetColor(timeline->getColors().textColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofVec2f screenPoint = screenPositionForKeyframe(emptyKeyframe); ofDrawCircle(screenPoint, 7); ofSetColor(emptyKeyframe->color); ofDrawCircle(screenPoint, 5); } } ofPopStyle(); }
void ofxTLCameraTrack::draw(){ //draw your keyframes into bounds ofPushStyle(); if(lockCameraToTrack){ ofSetColor(timeline->getColors().keyColor, 40*(sin(ofGetElapsedTimef()*5)*.5+.5)+25); ofFill(); ofRect(bounds); } ofSetColor(timeline->getColors().keyColor); ofNoFill(); // for(int i = 0; i < track.getSamples().size(); i++){ for(int i = 0; i < keyframes.size(); i++){ if(!isKeyframeIsInBounds(keyframes[i])){ continue; } ofxTLCameraFrame* sample =(ofxTLCameraFrame*)keyframes[i]; float screenX = millisToScreenX(keyframes[i]->time); float screenY = bounds.y; ofPoint screenPoint = ofPoint(screenX,screenY); // if(keyframes[i] == selectedKeyframe){ if(isKeyframeSelected(sample)){ if(sample->easeInSelected){ ofSetColor(timeline->getColors().highlightColor); draweEase(sample->easeIn, screenPoint, true); ofSetColor(timeline->getColors().keyColor); draweEase(sample->easeOut, screenPoint, false); } else { ofSetColor(timeline->getColors().keyColor); draweEase(sample->easeIn, screenPoint, true); ofSetColor(timeline->getColors().highlightColor); draweEase(sample->easeOut,screenPoint, false); } } else{ ofSetColor(timeline->getColors().keyColor); draweEase(sample->easeIn, screenPoint, true); draweEase(sample->easeOut, screenPoint, false); } } ofFill(); ofSetColor(timeline->getColors().highlightColor); for(int i = 0; i < selectedKeyframes.size(); i++){ float screenX = millisToScreenX( selectedKeyframes[i]->time ); float screenY = bounds.y+bounds.height/2; ofCircle(screenX, screenY, 4); } ofPopStyle(); }
void ofxTLSwitches::getSnappingPoints(set<unsigned long>& points){ for(int i = 0; i < keyframes.size(); i++){ ofxTLSwitch* switchKey = (ofxTLSwitch*)keyframes[i]; if (isKeyframeIsInBounds(switchKey) && !isKeyframeSelected(switchKey) && !switchKey->startSelected && !switchKey->endSelected) { points.insert(switchKey->timeRange.min); points.insert(switchKey->timeRange.max); } } }
//draw your keyframes into bounds void ofxTLLFO::draw(){ //we draw keys our own way //ofxTLKeyframes::draw(); if(bounds.width == 0 || bounds.height < 2){ return; } if(shouldRecomputePreviews || viewIsDirty){ recomputePreviews(); } ofSetColor(timeline->getColors().disabledColor, 30); float currentPercent = sampleAtTime(currentTrackTime()); ofFill(); ofRect(bounds.x, bounds.getMaxY(), bounds.width, -bounds.height*currentPercent); ofPushStyle(); ofSetColor(timeline->getColors().keyColor); preview.draw(); for(int i = 0; i < keyframes.size(); i++){ //make sure it's on screen if(isKeyframeIsInBounds(keyframes[i])){ //we know the type because we created it in newKeyframe() //so we can safely cast ofxTLLFOKey* lfoKey = (ofxTLLFOKey*)keyframes[i]; if(isKeyframeSelected(keyframes[i])){ ofSetLineWidth(2); ofSetColor(timeline->getColors().textColor); } else if(keyframes[i] == hoverKeyframe){ ofSetLineWidth(4); ofSetColor(timeline->getColors().highlightColor); } else{ ofSetLineWidth(4); ofSetColor(timeline->getColors().keyColor); } float screenX = millisToScreenX(keyframes[i]->time); ofLine(screenX, bounds.y, screenX, bounds.y+bounds.height); } } ofPopStyle(); }
void ofxTLBangs::draw(){ if(bounds.height < 2){ return; } ofPushStyle(); ofFill(); //float currentPercent = powf(MIN(ofGetElapsedTimef() - lastBangTime, .5), 2); float currentPercent = powf(ofMap(ofGetElapsedTimef() - lastBangTime, 0, .5, 1.0, 0,true), 2); if(currentPercent > 0){ ofSetColor(timeline->getColors().disabledColor, 100*(currentPercent)); ofFill(); ofRect(bounds.x, bounds.y, bounds.width, bounds.height); } for(int i = keyframes.size()-1; i >= 0; i--){ if(!isKeyframeIsInBounds(keyframes[i])){ continue; } //int screenX = normalizedXtoScreenX(keyframes[i]->position.x); int screenX = millisToScreenX(keyframes[i]->time); if(isKeyframeSelected(keyframes[i])){ ofSetLineWidth(2); ofSetColor(timeline->getColors().textColor); } else if(keyframes[i] == hoverKeyframe){ ofSetLineWidth(4); ofSetColor(timeline->getColors().highlightColor); } else{ ofSetLineWidth(4); ofSetColor(timeline->getColors().keyColor); } ofLine(screenX, bounds.y, screenX, bounds.y+bounds.height); } ofPopStyle(); }
void ofxTLSwitches::draw(){ ofPushStyle(); ofFill(); //draw a little wobble if its on //if(isOnAtMillis(timeline->getCurrentTimeMillis())){ //play solo change if(isOn()){ ofSetColor(timeline->getColors().disabledColor, 20+(1-powf(sin(ofGetElapsedTimef()*5)*.5+.5,2))*20); ofRect(bounds); } for(int i = 0; i < keyframes.size(); i++){ ofxTLSwitch* switchKey = (ofxTLSwitch*)keyframes[i]; float startScreenX = millisToScreenX(switchKey->timeRange.min); float endScreenX = millisToScreenX(switchKey->timeRange.max); switchKey->display = ofRectangle(startScreenX, bounds.y, endScreenX-startScreenX, bounds.height); //draw handles ofSetLineWidth(2); bool keyIsSelected = isKeyframeSelected(switchKey); if(keyIsSelected || switchKey->startSelected){ ofSetColor(timeline->getColors().textColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofLine(switchKey->display.x, bounds.y, switchKey->display.x, bounds.y+bounds.height); if(keyIsSelected || switchKey->endSelected){ ofSetColor(timeline->getColors().textColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofLine(switchKey->display.x+switchKey->display.width, bounds.y, switchKey->display.x+switchKey->display.width, bounds.y+bounds.height); //draw region if(keyIsSelected){ ofSetColor(timeline->getColors().textColor, 100); } else{ ofSetColor(timeline->getColors().keyColor, 100); } //set overlay colors, this will override the colors above if(hoverKeyframe == switchKey){ if(startHover){ ofPushStyle(); if(switchKey->startSelected){ ofSetColor(timeline->getColors().highlightColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofRect(switchKey->display.x-2, bounds.y, 4, bounds.height); ofPopStyle(); } else if(endHover){ ofPushStyle(); if(switchKey->endSelected){ ofSetColor(timeline->getColors().highlightColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofRect(switchKey->display.x+switchKey->display.width-2, bounds.y, 4.0, bounds.height); ofPopStyle(); } else { if(keyIsSelected){ ofSetColor(timeline->getColors().highlightColor); }else { ofSetColor(timeline->getColors().keyColor); } } } ofRect(switchKey->display); } ofPopStyle(); }
bool ofxTLSwitches::mousePressed(ofMouseEventArgs& args, long millis){ if(placingSwitch != NULL){ if(isActive() && args.button == 0){ placingSwitch->timeRange.max = millis; updateTimeRanges(); } else { deleteKeyframe(placingSwitch); } placingSwitch = NULL; return false; } keysAreDraggable = !ofGetModifierSelection(); //check to see if we are close to any edges, if so select them bool startSelected = false; bool endSelected = false; int selectedKeyframeIndex; if(isActive() && args.button == 0){ for(int i = 0; i < keyframes.size(); i++){ ofxTLSwitch* switchKey = (ofxTLSwitch*)keyframes[i]; //unselect everything else if we just clicked this edge without shift held down startSelected = abs(switchKey->display.x - args.x) < 10.0; if (startSelected && !switchKey->startSelected && !ofGetModifierSelection()) { timeline->unselectAll(); } //Deselect the key if we clicked it already selected with shift held down if(ofGetModifierSelection() && ((startSelected && switchKey->startSelected) || isKeyframeSelected(switchKey))){ switchKey->startSelected = false; } else { switchKey->startSelected |= startSelected; } float endEdge = switchKey->display.x+switchKey->display.width; endSelected = abs(endEdge - args.x) < 10.0; //don't let them both be selected in one click! if(!startSelected && endSelected && !switchKey->endSelected && !ofGetModifierSelection()){ timeline->unselectAll(); } //Deselect the key if we clicked it already selected with shift held down if(ofGetModifierSelection() && ((endSelected && switchKey->endSelected) || isKeyframeSelected(switchKey))){ switchKey->endSelected = false; } else{ switchKey->endSelected |= endSelected && !startSelected; } if(startSelected || endSelected){ selectedKeyframeIndex = i; break; } } } //update dragging and snapping if we clicked an edge updateEdgeDragOffsets(millis); if(endSelected || startSelected){ ofxTLSwitch* selectedSwitch = (ofxTLSwitch*)keyframes[selectedKeyframeIndex]; timeline->setDragTimeOffset(selectedSwitch->edgeDragOffset); } if(!endSelected && !startSelected){ //normal selection from above ofxTLKeyframes::mousePressed(args, millis); if(isActive()){ timeline->cancelSnapping(); //don't snap when dragging the whole switch } } //move through the keyframes, if both the start and the end have been selected //count it as completely selected and let the super class take care of it //otherwise if just one of the edges are selected make sure it's unselected for(int i = 0; i < keyframes.size(); i++){ ofxTLSwitch* switchKey = (ofxTLSwitch*)keyframes[i]; if (switchKey->startSelected && switchKey->endSelected) { switchKey->startSelected = switchKey->endSelected = false; selectKeyframe(switchKey); } //make sure that if just one of the edges is clicked that the keyframe is *not* selected //also make sure it wasn't *just* selected in the last click by checking that it's not 'the' selected key else if( (switchKey->startSelected || switchKey->endSelected) && isKeyframeSelected(switchKey)){ if(selectedKeyframe == switchKey){ switchKey->startSelected = switchKey->endSelected = false; } else{ deselectKeyframe(switchKey); } } } return false; }
void ofxTLNotes::draw(){ ofPushStyle(); ofFill(); // Draw Row BGs ofFill(); float rowHeight = bounds.height / (valueRange.span()+1); for (int i = 0; i <= valueRange.span(); i++) { // alternate row colors if(i%2 == 1) { ofSetColor(255, 255, 255, 50); } else { ofSetColor(255, 255, 255, 25); } // set row color for active notes int whichRow = ofMap(i, 0, valueRange.span(), valueRange.max, valueRange.min); if(pitchIsOn(whichRow)){ ofSetColor(0, 0, 0, 100); } ofRect(bounds.x, bounds.y + i * rowHeight, bounds.width, rowHeight); } for(int i = 0; i < keyframes.size(); i++){ // Calculate Note Bounds ofxTLNote* switchKey = (ofxTLNote*)keyframes[i]; float startScreenX = MAX(millisToScreenX(switchKey->timeRange.min), 0); float endScreenX = MIN(millisToScreenX(switchKey->timeRange.max), bounds.getMaxX()); if(startScreenX == endScreenX){ continue; } int whichRow = ofMap(switchKey->pitch, valueRange.max, valueRange.min, 0, valueRange.span()); switchKey->display = ofRectangle(startScreenX, bounds.y + whichRow * rowHeight, endScreenX-startScreenX, rowHeight); // Drawing The Handles ofSetLineWidth(2); bool keyIsSelected = isKeyframeSelected(switchKey); if(keyIsSelected || switchKey->startSelected){ ofSetColor(timeline->getColors().textColor); } else{ ofSetColor(timeline->getColors().keyColor); } // Do Left Line ofLine(switchKey->display.x, switchKey->display.y, switchKey->display.x, switchKey->display.y + switchKey->display.height); if(keyIsSelected || switchKey->endSelected){ ofSetColor(timeline->getColors().textColor); } else{ ofSetColor(timeline->getColors().keyColor); } // Do Right Line ofLine(switchKey->display.x+switchKey->display.width, switchKey->display.y, switchKey->display.x+switchKey->display.width, switchKey->display.y + switchKey->display.height); //draw region if(keyIsSelected){ ofSetColor(timeline->getColors().textColor, 100); } else{ ofSetColor(timeline->getColors().keyColor, 100); } //set overlay colors, this will override the colors above if(hoverKeyframe == switchKey){ if(startHover){ ofPushStyle(); if(switchKey->startSelected){ ofSetColor(timeline->getColors().highlightColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofRect(switchKey->display.x-2, bounds.y, 4, bounds.height); ofPopStyle(); } else if(endHover){ ofPushStyle(); if(switchKey->endSelected){ ofSetColor(timeline->getColors().highlightColor); } else{ ofSetColor(timeline->getColors().keyColor); } ofRect(switchKey->display.x+switchKey->display.width-2, bounds.y, 4.0, bounds.height); ofPopStyle(); } else { if(keyIsSelected){ ofSetColor(timeline->getColors().highlightColor); }else { ofSetColor(timeline->getColors().keyColor); } } } ofRect(switchKey->display); } ofPopStyle(); }
void ofxTLKeyframes::selectKeyframe(ofxTLKeyframe* k){ if(!isKeyframeSelected(k)){ selectedKeyframes.push_back(k); } }
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; }
void ofxTLColorTrack::draw() { if(bounds.height == 0) { return; } if(viewIsDirty || shouldRecomputePreviews) { updatePreviewPalette(); } if(keyframes.size() == 0) { ofPushStyle(); ofSetColor(defaultColor); ofFill(); ofRect(bounds); ofPopStyle(); } else if(keyframes.size() == 1) { ofPushStyle(); ofxTLColorSample* s = (ofxTLColorSample*)keyframes[0]; ofSetColor(s->color); ofFill(); ofRect(bounds); ofPopStyle(); } else { previewPalette.draw(bounds); } for(int i = 0; i < keyframes.size(); i++) { if(!isKeyframeIsInBounds(keyframes[i])) { continue; } float screenX = millisToScreenX(keyframes[i]->time); ofPoint a = ofPoint(screenX-10,bounds.y); ofPoint b = ofPoint(screenX+10,bounds.y); ofPoint c = ofPoint(screenX,bounds.y+10); ofPushStyle(); ofFill(); ofxTLColorSample* s = (ofxTLColorSample*)keyframes[i]; ofSetColor(s->color); ofTriangle(a,b,c); ofNoFill(); ofSetColor(s->color.getInverted()); ofSetLineWidth(1); ofTriangle(a,b,c); if(keyframes[i] == hoverKeyframe) { ofSetColor(timeline->getColors().highlightColor); ofSetLineWidth(3); } else if(isKeyframeSelected(keyframes[i])) { ofSetColor(timeline->getColors().textColor); ofSetLineWidth(2); } else { ofSetColor(s->color.getInverted()); } ofLine(c, ofVec2f(screenX, bounds.getMaxY())); ofPopStyle(); } }