#include "chainImageSet.h" void chainImageSet::drawOutput(){ //movment and rotation are working on their own but not together. float camera_throw= (float)outputSize.y/(float)outputSize.x; //the ratio of z distance to x width camera_throw*=fitFactor; //fudge factor to allow tweening, //printf("Drawing chain: %i images\n",images.size()); if (images.size()){ /* glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-ofGetWidth()/2, ofGetWidth()/2, ofGetHeight()/2, -ofGetHeight()/2, 0.0f, 5000.0f); */ glMatrixMode ( GL_MODELVIEW ); glLoadIdentity ( ); /* is not what we want glOrtho( 0, (*currentImage)->getTransform().x*2, 0, (*currentImage)->getTransform().y*2, -100, (*currentImage)->getTransform().x*4 ); */ glScalef(8,8,8); //easy way to avoid camera cutoff gluLookAt( (*currentImage)->getTransform().x, (*currentImage)->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), (*currentImage)->getWidth()*camera_throw*(*currentImage)->getScale(), (*currentImage)->getTransform().x, (*currentImage)->getTransform().y, // i1.linkPos.y+(xform.y*intervalpoint), 0, sin(-(*currentImage)->getRotation()*(PI/180)), cos(-(*currentImage)->getRotation()*(PI/180)), 0); (*currentImage)->drawChain(DEFAULT_FADEIN,additive,intensity); } } void chainImageSet::drawGui(int x,int y,bool is_selected){ float t_xoffs=0.0; float borderwidth=THUMB_SIZE*0.1; //ofGetWindowHeight()*(1.0-THUMB_BORDER_RATIO)*0.5; /* float relscale=((float)ofGetWindowHeight())/THUMB_SIZE; glScalef(relscale,relscale,relscale); //scale view by distance betweeen thumnail size and window size: doesn't work */ //draw each image, outlined glPushMatrix(); glTranslatef(x,y,0); for(auto ii=images.begin(); ii != images.end(); ii++){ ofSetColor(255,255,255); float thumbx=(*ii)->thumbnail.getWidth()/2; float thumby=(*ii)->thumbnail.getHeight()/2; float thumbscale=(*ii)->thumbnail.getWidth()/(*ii)->getWidth(); //why do I have to set this every time?? (*ii)->thumbnail.setAnchorPercent(0.5,0.5); if ((*ii)->thumbnail.isAllocated()){ (*ii)->thumbnail.setUseTexture(true); (*ii)->thumbnail.draw( t_xoffs+borderwidth+thumbx, borderwidth+thumby, (*ii)->thumbnail.getWidth(), (*ii)->thumbnail.getHeight() ); } ofSetColor(255,255,255); if (ii==selected) ofSetColor(255,0,0); if (ii==currentImage) ofSetColor(0,255,0); ofDrawLine(t_xoffs+borderwidth,borderwidth, t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth); ofDrawLine(t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth, t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth+(*ii)->thumbnail.getHeight()); ofDrawLine(t_xoffs+borderwidth+(*ii)->thumbnail.getWidth(),borderwidth+(*ii)->thumbnail.getHeight(), t_xoffs+borderwidth,borderwidth+(*ii)->thumbnail.getHeight()); ofDrawLine(t_xoffs+borderwidth,borderwidth+(*ii)->thumbnail.getHeight(), t_xoffs+borderwidth,borderwidth); ofSetColor(255,255,255); if ((*ii)->link){ ofPoint lp=(*ii)->linkPos; if (ii==selected){ lp+=dragPoint; } float subpictx=t_xoffs+borderwidth+thumbx+(lp.x*thumbscale); float subpicty=borderwidth+thumby+(lp.y*thumbscale); ofDrawLine( subpictx, subpicty, t_xoffs+(borderwidth*3)+(*ii)->thumbnail.getWidth(), borderwidth+thumby ); glPushMatrix(); glTranslatef(subpictx,subpicty,0); float r=(*ii)->linkRot; if (ii==selected) r+=dragRotate; glRotatef(r,0,0,1); //printf("Sub image: centre at %f,%f \n",ii->link->thumbnail.getAnchorPoint().x,ii->link->thumbnail.getAnchorPoint().y); (*ii)->link->thumbnail.setAnchorPercent(0.5,0.5); float thescale=(*ii)->linkScale; if (ii==selected){ thescale*=(1.0f+dragScale); } if ((*ii)->link->thumbnail.isAllocated()){ (*ii)->link->thumbnail.draw( 0, 0, (*ii)->link->thumbnail.getWidth()*thescale, (*ii)->link->thumbnail.getHeight()*thescale ); } ofPoint p1=ofPoint( -((*ii)->link->thumbnail.getWidth()*thescale*0.5), -((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p2=ofPoint( ((*ii)->link->thumbnail.getWidth()*thescale*0.5), -((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p3=ofPoint( ((*ii)->link->thumbnail.getWidth()*thescale*0.5), ((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofPoint p4=ofPoint( -((*ii)->link->thumbnail.getWidth()*thescale*0.5), ((*ii)->link->thumbnail.getHeight()*thescale*0.5)); ofDrawLine(p1,p2); ofDrawLine(p2,p3); ofDrawLine(p3,p4); ofDrawLine(p4,p1); glPopMatrix(); } t_xoffs+=(*ii)->thumbnail.getWidth()+(borderwidth*2); } if (is_selected) { ofSetColor(0,0,255); ofPolyline box; box.addVertex(ofPoint(5,5)); box.addVertex(ofPoint(t_xoffs-5,5)); box.addVertex(ofPoint(t_xoffs-5,(THUMB_SIZE/THUMB_BORDER_RATIO)-10)); box.addVertex(ofPoint(5,(THUMB_SIZE/THUMB_BORDER_RATIO)-10)); box.addVertex(ofPoint(5,5)); box.draw(); } glPopMatrix(); } bool chainImageSet::add(std::string filename,glm::vec2 pos){ printf("Dropped file: %s at %f,%f \n",filename.c_str(),pos.x,pos.y); /* attempt to add file to chain. find if file exists in data folder if not make a symbolic link */ auto image=std::make_unique(); image->init(ofPoint(0,0), 0.3, //currentDefaultImageRatio, 0 //default rotation ); printf("Loading file: %s linkscale %f\n", filename.c_str(), image->linkScale); loader.loadFromDisk(*image,filename); loadingImages.push_back(std::move(image)); //if (image.load(filename)){ //loadingImages.push_back(image); return true; //} //printf("Could not load file: %s \n",filename.c_str()); //return false; } void chainImageSet::keyPressed(ofKeyEventArgs &keyargs){ //printf("Got key %i, modifiers:%i\n",keyargs.key,keyargs.modifiers); switch(keyargs.key){ case '[': if (selected==images.begin()){ selected=--images.end(); } else --selected; break; case ']': ++selected; if (selected==images.end()){ selected=images.begin(); } break; case OF_KEY_UP: (*selected)->linkPos.y--; break; case OF_KEY_DOWN: (*selected)->linkPos.y++; break; case OF_KEY_LEFT: (*selected)->linkPos.x--; break; case OF_KEY_RIGHT: (*selected)->linkPos.x++; break; case OF_KEY_BACKSPACE:{ if (images.size()==1||keyargs.modifiers==2){ //ctrl-backspace to delete whole bank //also OF_KEY_DEL ? images.clear(); filename.clear(); break; } bool setCurrent=false; if (currentImage==selected){ //we are deleting the playing image setCurrent=true; } auto previous=selected; if (previous==images.begin()){ previous=images.end(); previous--; } else { previous--; } (*previous)->link=(*selected)->link; images.erase(selected); selected=previous; selected++; if (selected==images.end()){ selected=images.begin(); } if (setCurrent){ //we have just deleted the playing image currentImage=selected; } break; } case 's': case 83: { //printf("Saving... keyargs modifiers:%i\n",keyargs.modifiers); //saves over last filename or use control to choose a new one if (!filename.length()||keyargs.hasModifier(OF_KEY_CONTROL)){ ofFileDialogResult saveFileResult = ofSystemSaveDialog(ofGetTimestampString() + ".json" , "Save your file"); if (saveFileResult.bSuccess){ filename=saveFileResult.filePath; //printf("Got filename: %s\n",filename.c_str()); } //else printf("ofSystemSaveDialog failed.\n"); } if (filename.length()){ //printf("Saving %s\n",filename.c_str()); saveJson(filename); } break; } case 'l':{ //load_chain(); ofFileDialogResult openFileResult= ofSystemLoadDialog("Select a json preset"); //Check if the user opened a file if (openFileResult.bSuccess){ bool success=loadJson(openFileResult.fileName); ofLogVerbose("Load %s %s\n", openFileResult.filePath.c_str(), success?"succeeded":"failed"); }else { ofLogVerbose("User hit cancel"); } break; } } } //-------------------------------------------------------------- void chainImageSet::mouseDragged(int x, int y, int button){ switch (button){ case OF_MOUSE_BUTTON_1: dragPoint=ofPoint(x-clickPoint.x,y-clickPoint.y)*((*selected)->getHeight()/ofGetWindowHeight()); break; case OF_MOUSE_BUTTON_2: //alt-click dragRotate=((clickPoint.x-x)/((*selected)->thumbnail.getWidth()))*180.0f; break; case OF_MOUSE_BUTTON_3: //control-click dragScale=(y-clickPoint.y)/((*selected)->thumbnail.getHeight()); //if (dragScale*selected->linkScale<0.15){ // dragScale=0.15/selected->linkScale; //} break; } } //-------------------------------------------------------------- void chainImageSet::mousePressed(int x, int y, int button){ //todo: select clickPoint=ofPoint(x,y); } //-------------------------------------------------------------- void chainImageSet::mouseReleased(int x, int y, int button){ if (images.size()){ (*selected)->linkPos+=dragPoint; dragPoint=ofPoint(0,0); (*selected)->linkScale*=(1.0f+dragScale); dragScale=0.0f; (*selected)->linkRot+=dragRotate; dragRotate=0.0f; } } bool chainImageSet::saveJson(std::string filename){ ofxJSON json; json["images"] = Json::Value(Json::arrayValue); for(auto ii=images.begin(); ii != images.end(); ii++){ json["images"].append((*ii)->toJson()); } json.save(filename, true); } bool chainImageSet::loadJson(std::string _filename){ ofxJSON json; bool parsingSuccessful = json.open(_filename); if (parsingSuccessful) { images.clear(); for (int i=0;i(); if (image->fromJson(json["images"][i])){ images.push_back(std::move(image)); } } for (auto ii=images.begin(); ii != images.end(); ii++){ auto li=ii; li++; if (li==images.end()) { li=images.begin(); } (*ii)->link=&(*(*li)); } selected=images.begin(); currentImage=images.begin(); (*currentImage)->start(); filename=_filename; return true; } ofLogVerbose("JSON load: parsing unsuccesful\n"); return false; } void chainImageSet::updateOutput(){ for (auto i=loadingImages.begin();i!=loadingImages.end();){ //printf("Checking loadingImage: %s\n",(*i)->filename.c_str()); if ((*i)->isLoaded){ printf("Finished loadingImage: %s, linkscale %f\n", (*i)->filename.c_str(), (*i)->linkScale ); images.push_back(std::move(*i)); (*images.rbegin())->link=&(*(*images.begin())); (*images.rbegin())->setUseTexture(true); printf("Linked: %s to %s\n", (*images.rbegin())->filename.c_str(), (*images.rbegin())->link->filename.c_str()); if (images.size()>1){ (*(++images.rbegin()))->link=&(*(*images.rbegin())); printf("Linked: %s to %s\n", (*(++images.rbegin()))->filename.c_str(), (*(++images.rbegin()))->link->filename.c_str()); } else { selected=images.begin(); currentImage=images.begin(); (*currentImage)->start(); } loadingImages.erase(i); printf("Images: %i loadingImages %i\n", images.size(), loadingImages.size()); } else i++; } if (images.size()){ int switchResponse=(*currentImage)->updateOutput(decayFactor); switch(switchResponse){ case SWITCH_FORWARD:{ currentImage++; if (currentImage==images.end()){ currentImage=images.begin(); } ofLogNotice() << "Switched image forward to " << (*currentImage)->filename; (*currentImage)->start(false); (*currentImage)->updateOutput(decayFactor); break; } case SWITCH_NONE: break; case SWITCH_REVERSE:{ if (currentImage==images.begin()){ currentImage=images.end(); } currentImage--; (*currentImage)->start(true); ofLogNotice() << "Switched images backward to " << (*currentImage)->filename; (*currentImage)->updateOutput(decayFactor); break; } } } }