block::block(ofTag & cur,ofColor col, int _y):ofInterObj(300,100,150,45) { //********* This is the method by which all of the blocks are first generated from the xml files in the data root. //-------- TODO: get rid of the garbage with the color triples. blech. //-------- load the font for the arialHeader, at 10 pt. arialHeader.loadFont(defaultFont); arialHeader.setSize(14); //-------- color initialization if(cur.getAttribute("color").length()) color=ofColor(strtol(cur.getAttribute("color").c_str(),NULL,0)); else color=col; //-------- load name from the name of the xmlNode title=cur.getAttribute("name"); cout << title << endl; //-------- init some variables, to prevent garbage from happening cond=0; numBlock=ddOpen=deleteMe=false; titleDisp=10; y=_y; numHolder=false; placeHolder=false; bBase=false; bSeq=false; //-------- declare the vector for splitting the title string, and the map used for the switch vector<string> titleSplit; map<string,int> list; list["seq"]=0; list["cond"]=1; list["wid"]=2; list["hgt"]=3; list["ifblock"]=4; list["file"]=5; list["part"]=6; list["num"]=7; list["dropdown"]=8; list["blocksIn"]=9; for(int i=0;i<cur.size();i++){ string node[2]={cur[i].getLabel(),cur[i].getValue()}; //-- node[0] is the label, node[1] is the value switch (list.find(node[0])->second) { case 0: // indicates whether or not a block is a sequence of other blocks bSeq=true; break; case 1: //-- cond //-------- set cond=true, and change size cond=atoi(node[1].c_str()); h=105; w=200; titleDisp=30; break; case 2: //wid, deprecated, handled with routines below switch w=atoi(node[1].c_str()); break; case 3: // hgt, deprecated, same as above h=atoi(node[1].c_str()); break; case 4: //ifblock //-- sets the flag for being a numHolder //-- deprecated, i think, by %n in the title numHolder=true; break; case 5: // file //-- definitely not deprecated, used to store value of which file to write from filename=node[1]; break; case 6: // part //-- stores the name of the complement blocks part.push_back(node[1]); break; case 7: // num //-- set the statement block flag numBlock=true; titleDisp=0; h=20; w=90; break; case 8: // dropdown //-- add a new dropdown menu to the block ddGroup.push_back(ofDropDown(cur[i])); break; case 9: for (unsigned int j=0; j<cur[i].size(); j++) { if (cur[i][j].getLabel()=="block") { blocksIn.push_back(block(cur[i][j],color,0)); } } break; default: break; } } int ddNum=0; //-------- assign a default value to the xdis of each dd for (unsigned int i=0; i<ddGroup.size(); i++) { ddGroup[i].xdis=titleDisp; } //-------- change the font size if it is a statement block if(numBlock) arialHeader.setSize(7); //-------- split the title into words by looking for " ", and establish a baseline for the width with "." titleSplit = ofSplitString(title, " "); int sp=1; int spSize=arialHeader.stringWidth("."); int totalwidth=0; //-------- set the displacement for each object in the title, statement blocks and dropdowns for (unsigned int i=0; i<titleSplit.size(); i++) { if(!titleSplit[i].compare("%d")){ if(ddNum<ddGroup.size()){ //-------- augment the orginal positon with the current total width ddGroup[ddNum].xdis+=totalwidth+spSize; //-------- update total width totalwidth+=ddGroup[ddNum].w+spSize*2; //-------- if you have two dropdowns in a row, make sure they don't overlap if(i==titleSplit.size()-1||(i==titleSplit.size()-2&&!titleSplit[i+1].compare("%d"))){ ddGroup[ddNum].xdis+=spSize; } ddNum++; } } else if(!titleSplit[i].compare("%b")){ //-------- if we find a statement block, init it as a placeholder numHolder=true; int cur=numBlocks.size(); numBlocks.push_back(block()); numBlocks[cur].x=totalwidth+titleDisp; numBlocks[cur].xo=numBlocks[cur].x; numBlocks[cur].w=50; numBlocks[cur].h=20; if(h<=5+numBlocks[cur].h) h=5+numBlocks[cur].h; totalwidth+=50+spSize; } else { totalwidth+=arialHeader.stringWidth(titleSplit[i]); } } title=""; ddNum=0; for (unsigned int i=0; i<titleSplit.size(); i++) { if(!titleSplit[i].compare("%d")){ if(ddNum<ddGroup.size()){ sp=0; int origWid = arialHeader.stringWidth(title); while (arialHeader.stringWidth(title)+spSize*sp-origWid<ddGroup[ddNum].w) { sp++; title.append(" "); } ddNum++; } } else if(!titleSplit[i].compare("%b")){ sp=0; int origWid = arialHeader.stringWidth(title); while (arialHeader.stringWidth(title)+spSize*sp-origWid<50) { sp++; title.append(" "); } } else { title.append(titleSplit[i].c_str()); for (int k=0; k<sp; k++) { title.append(" "); } } } double newWid=totalwidth+20; if(!numBlock) w=max(w,newWid); else { w=newWid-10; } for(int i=0; i<ddGroup.size(); i++) ddGroup[i].changeSize(ddGroup[i].w, (ddGroup[i].arial.stringHeight("1")+4)); oH=h; }
block::block(ofTag & cur,ofColor col):ofInterObj(-200,-200,150,TITLE_HEIGHT) { //********* This is the method by which all of the blocks are first generated from the xml files in the data root. //-------- TODO: get rid of the garbage with the color triples. blech. //-------- load the font for the arialHeader, at 10 pt. origTag=cur; arialHeader.loadFont(defaultFont); arialHeader.setMode(OF_FONT_MID); arialHeader.setSize(14); insertSpace=0; bGrabbed=false; //-------- color initialization if(cur.getAttribute("color").length()) color=ofColor(strtol(cur.getAttribute("color").c_str(),NULL,0)); else color=col; //-------- load name from the name of the xmlNode title=cur.getAttribute("name"); ttlSize.x=w; ttlSize.y=TITLE_HEIGHT; ddSelected=false; //cout << title << endl; //-------- init some variables, to prevent garbage from happening ddOpen=false; titlePos.x=10; type=BLK_DEFAULT; placeHolder=false; //-------- declare the map used for the switch map<string,int> list; list["seq"]=0; list["bracket"]=1; list["action"]=4; list["file"]=5; list["sibling"]=6; list["num"]=7; list["dropdown"]=8; list["blocksIn"]=9; list["blocksOn"]=10; for(int i=0;i<cur.size();i++){ string node[2]={cur[i].getLabel(),cur[i].getValue()}; //-- node[0] is the label, node[1] is the value if(list.find(node[0])!=list.end()){ switch (list.find(node[0])->second) { case 1: //-- bracket //-------- set type to bracket, and change size type=BLK_BRACKET; h=105; w=200; titlePos.x=30; break; case 5: // file //-- definitely not deprecated, used to store value of which file to write from filename=node[1]; break; case 6: // sibling //-- stores the name of the complement blocks sibling.push_back(node[1]); break; case 7: // num //-- set the statement block flag type=BLK_VAL; titlePos.x=0; ttlSize.x=w=90; ttlSize.y=h=20; break; case 8: // dropdown //-- add a new dropdown menu to the block ddGroup.push_back(dallasDrop(cur[i])); break; case 9: for (unsigned int j=0; j<cur[i].size(); j++) { if (cur[i][j].getLabel()=="block") { blocksIn.push_back(block(cur[i][j],color)); } } break; case 10: for (unsigned int j=0; j<cur[i].size(); j++) { if (cur[i][j].getLabel()=="block") { blocksOn.push_back(block(cur[i][j],color)); } } break; default: break; } } } parseTitle(); }
void demoAnim::handleAnimStep(ofTag tag) { //------- set the default event type to "end" vMouseType vType=OF_VMOUSE_END; //------- variable declarations ofInterObj * object=0; double duration=0; double speed=0; int xint=0, yint=0; string type=tag.getAttribute("type"); if(type.length()){ if(type=="move") vType=OF_VMOUSE_MOVE_TO; else if(type=="clickDown") vType=OF_VMOUSE_CLICK_DOWN,xint=anim.x,yint=anim.y; else if(type=="clickUp") vType=OF_VMOUSE_CLICK_UP,xint=anim.x,yint=anim.y; else if(type=="select"){ } } //------- if we have a time attribute, set the duration var to that attribute string time=tag.getAttribute("time"); if(time.length()){ duration=ofToFloat(time); } //-------otherwise, we need to look for the speed at which we want to move, to be used later to determine time else { string spd=tag.getAttribute("speed"); if(spd.length()){ speed=ofToFloat(spd); } } //------- if there is a pos tag inside the current tag, push into it if(tag.getNumTags("pos")){ ofTag & tg=tag.getNode("pos"); //------- and look at the type of position tag it is string typ=tg.getAttribute("type"); if(typ=="obj") //-- if it is an object tag, search for the specified object using the searchForObject function object = searchForObject(tg,xint,yint); else if(typ=="coord"){ //-------if it is a coordinate, set xint and yint to the x and y attributes. xint=ofToInt(tg.getAttribute("x")); yint=ofToInt(tg.getAttribute("y")); } //-------if it is a mouse tag, set the xint and yint to the mouse coordinates else if(typ=="mouse") xint=ofGetAppPtr()->mouseX,yint=ofGetAppPtr()->mouseY; if(!duration){ //-- if we haven't yet set the duration, use the speed to determine duration int xtmp=((object)?object->x+xint:xint); int ytmp=((object)?object->y+yint:yint); double dist= sqrt(double((xtmp-anim.x)*(xtmp-anim.x)+(ytmp-anim.y)*(ytmp-anim.y))); duration=dist/speed; } //-- if we are following an object, the next event is called, referencing that object if(object) anim.nextEvent(vType,(*object),xint, yint,duration); else anim.nextEvent(vType,xint, yint,duration); //-- otherwise, it is called using only x and y } else { //-- if there is not a position tag inside, the next event takes place where the vMouse is currently located anim.nextEvent(vType,xint, yint,duration); } }