void butt_cb(Fl_Widget *butt, void *data) { // Deactivate the button butt->deactivate(); // prevent button from being pressed again Fl::check(); // give fltk some cpu to gray out button // Make the progress bar Fl_Window *w = (Fl_Window*)data; // access parent window w->begin(); // add progress bar to it.. Fl_Progress *progress = new Fl_Progress(10,50,200,30); progress->minimum(0); // set progress range to be 0.0 ~ 1.0 progress->maximum(1); progress->color(0x88888800); // background color progress->selection_color(0x4444ff00); // progress bar color progress->labelcolor(FL_WHITE); // percent text color w->end(); // end adding to window // Computation loop.. for ( int t=1; t<=500; t++ ) { progress->value(t/500.0); // update progress bar with 0.0 ~ 1.0 value char percent[10]; sprintf(percent, "%d%%", int((t/500.0)*100.0)); progress->label(percent); // update progress bar's label Fl::check(); // give fltk some cpu to update the screen Sleep(1000); // 'your stuff' that's compute intensive } // Cleanup w->remove(progress); // remove progress bar from window delete(progress); // deallocate it butt->activate(); // reactivate button w->redraw(); // tell window to redraw now that progress removed }
void sprites::importSpriteSheet(const char*fname){ if(!fname){ if(!load_file_generic("Load image")) return; fname=the_file.c_str(); } if(fname){ Fl_Shared_Image * loaded_image=Fl_Shared_Image::get(fname); if(!loaded_image){ fl_alert("Error loading image"); return; } unsigned depth=loaded_image->d(); if (unlikely(depth != 3 && depth != 4 && depth!=1)){ fl_alert("Please use color depth of 1,3 or 4\nYou Used %d",depth); loaded_image->release(); return; }else printf("Image depth %d\n",depth); uint32_t w,h; w=loaded_image->w(); h=loaded_image->h(); bool grayscale; uint8_t*palMap; uint8_t*imgptr; unsigned remap[256]; if(depth==1){ grayscale=handle1byteImg(loaded_image,remap); if(!grayscale){ palMap=(uint8_t*)loaded_image->data()[1]; imgptr=(uint8_t*)loaded_image->data()[2]; } } uint8_t mask[3]; bool useAlpha; if(getMaskColorImg(loaded_image,grayscale,remap,palMap,mask,useAlpha)){ std::vector<int> rects;//x0,x1,y0,y1 Fl_Window *winP; Fl_Progress *progress; mkProgress(&winP,&progress); time_t lasttime=time(NULL); progress->maximum(h); Fl::check(); for(int y=0;y<h;++y){ for(int x=0;x<w;++x){ if(!isMask(x,y,loaded_image,grayscale,useAlpha,mask)){ rects.push_back(x); while(!isMask(x+1,y,loaded_image,grayscale,useAlpha,mask)) ++x; rects.push_back(x); rects.push_back(y); rects.push_back(y); } } if((time(NULL)-lasttime)>=1){ lasttime=time(NULL); progress->value(h); Fl::check(); } } progress->maximum(rects.size()); progress->value(0); //Now combine the rectangles //Start by combining rectangles by that touch with y values bool canEnd; int pass=0; char txtbufstage[1024]; char txtbuf[1024]; do{ canEnd=true; snprintf(txtbufstage,1024,"Stage 1 pass %d",pass++); winP->label(txtbufstage); Fl::check(); for(int i=0;i<rects.size();i+=4){ for(int j=0;j<rects.size();j+=4){ if(i==j) continue; //See if rectangles are touching or overlap //if((inRange(rects[j+2],rects[i+2]-1,rects[i+3]+1)||inRange(rects[i+2],rects[j+2]-1,rects[j+3]+1))&&(!((rects[i+2]==rects[j+2])||(rects[i+3]==rects[j+3])))){//Is rectange j directly above or below i if((rects[j+3]-rects[i+2])==1){ if((inRange(rects[j],rects[i]-1,rects[i+1]+1)||inRange(rects[i],rects[j]-1,rects[j+1]+1))){ canEnd=false; //Merge the two squares obtaining maximum size //Now try and find the combination that results in the largest rectangle rects[i]=std::min(rects[i],rects[j]); rects[i+1]=std::max(rects[i+1],rects[j+1]); rects[i+2]=std::min(rects[i+2],rects[j+2]); rects[i+3]=std::max(rects[i+3],rects[j+3]); rects.erase(rects.begin()+j,rects.begin()+j+4); //Now try to find next in sequence bool foundit; do{ foundit=false; for(int a=0;a<rects.size();a+=4){ int look=rects[i+3]+1; if(rects[a+2]==look){ if((inRange(rects[a],rects[i]-1,rects[i+1]+1)||inRange(rects[i],rects[a]-1,rects[a+1]+1))){ foundit=true; rects[i]=std::min(rects[i],rects[a]); rects[i+1]=std::max(rects[i+1],rects[a+1]); rects[i+2]=std::min(rects[i+2],rects[a+2]); rects[i+3]=std::max(rects[i+3],rects[a+3]); rects.erase(rects.begin()+a,rects.begin()+a+4); } } } }while(foundit); } } } if((time(NULL)-lasttime)>=1){ lasttime=time(NULL); progress->maximum(rects.size()); progress->value(i); snprintf(txtbuf,1024,"Rectangles: %d",rects.size()); progress->label(txtbuf); Fl::check(); } } }while(!canEnd); pass=0; do{ canEnd=true; snprintf(txtbufstage,1024,"Stage 2 pass %d",pass++); winP->label(txtbufstage); progress->maximum(rects.size()); progress->value(0); Fl::check(); for(int i=0;i<rects.size();i+=4){ for(int j=0;j<rects.size();j+=4){ if(i==j) continue; //Merge overlapping rectangles if((rects[i]<=rects[j+1])&&(rects[i+1]>=rects[j])&&(rects[i+2]<=rects[j+3])&&(rects[i+3]>=rects[j+2])){ canEnd=false; rects[i]=std::min(rects[i],rects[j]); rects[i+1]=std::max(rects[i+1],rects[j+1]); rects[i+2]=std::min(rects[i+2],rects[j+2]); rects[i+3]=std::max(rects[i+3],rects[j+3]); rects.erase(rects.begin()+j,rects.begin()+j+4); } //Merge touching rectangles if(abs(rects[i+1]-rects[j])==1){ if((inRange(rects[j+2],rects[i+2]-1,rects[i+3]+1)||inRange(rects[i+2],rects[j+2]-1,rects[j+3]+1))){ canEnd=false; rects[i]=std::min(rects[i],rects[j]); rects[i+1]=std::max(rects[i+1],rects[j+1]); rects[i+2]=std::min(rects[i+2],rects[j+2]); rects[i+3]=std::max(rects[i+3],rects[j+3]); rects.erase(rects.begin()+j,rects.begin()+j+4); } } } if((time(NULL)-lasttime)>=1){ lasttime=time(NULL); progress->maximum(rects.size()); progress->value(i); snprintf(txtbuf,1024,"Rectangles: %d",rects.size()); progress->label(txtbuf); Fl::check(); } } }while(!canEnd); winP->remove(progress);// remove progress bar from window delete(progress);// deallocate it delete winP; std::vector<bool> deleted; deleted.resize(rects.size()/4); //Now show the window allowing user to adjust sprite settings if(window){ win=new Fl_Double_Window(640,480,"Sprite selection"); win->begin(); win->resizable(win); Fl_Button * Ok=new Fl_Button(256,448,64,24,"Okay"); Ok->callback(RetCB,(void*)1); Fl_Button * Cancel=new Fl_Button(320,448,64,24,"Cancel"); Cancel->callback(RetCB,0); Fl_Scroll*scroll=new Fl_Scroll(8,8,624,440); box=new RectBox(8,8,w,h); box->scroll=scroll; box->rects=&rects; box->deleted=&deleted; box->image(loaded_image); scroll->end(); win->end(); win->set_modal(); win->show(); Fl::check(); while(win->shown()) Fl::wait(); delete win; }else retOkay=true; if(retOkay){ for(unsigned i=0;i<rects.size();i+=4){ recttoSprite(rects[i],rects[i+1],rects[i+2],rects[i+3],-1,loaded_image,grayscale,remap,palMap,mask,true,useAlpha); } updateTileSelectAmt(); } deleted.clear(); rects.clear(); } loaded_image->release(); } }