diff options
Diffstat (limited to 'gui.cpp')
-rw-r--r-- | gui.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
@@ -0,0 +1,166 @@ +#include <iostream> +#include <fstream> +#include <vector> +#include <cstdlib> +#include <sys/time.h> + +#include <FL/Fl.H> +#include <FL/Fl_Box.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_File_Chooser.H> +#include <FL/Fl_Group.H> +#include <FL/Fl_Scroll.H> +#include <FL/Fl_Window.H> + +#include "parse.h" +#include "world.h" + +using namespace std; + + +struct ColourTeam{ + Team *team; + Fl_Color col; +}; + +class BotList{ + struct Item{ + ColourTeam *cteam; + Fl_Box *box; + }; + + Fl_Scroll *listScr; + vector<Item> teams; + +public: + BotList(Fl_Group *parent){ + listScr=new Fl_Scroll(parent->x()+1,parent->y()+25,parent->w()-2,parent->h()-26); + listScr->end(); + } + + void add(ColourTeam *cteam){ + Fl_Box *box=new Fl_Box(listScr->x(),listScr->y()+20*teams.size(),listScr->w(),20); + box->color(cteam->col); + box->label(cteam->team->name.data()); + box->box(FL_FLAT_BOX); + box->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + listScr->add(box); + listScr->redraw(); + teams.push_back({cteam,box}); + } + + void remove(ColourTeam *cteam){ + size_t i; + for(i=0;i<teams.size();i++){ + if(teams[i].cteam==cteam)break; + } + delete teams[i].box; + for(size_t j=i+1;j<teams.size();j++){ + teams[j].box->position(teams[j].box->x(),teams[j].box->y()-20); + } + teams.erase(teams.begin()+i); + } +}; + +class Simulation{ + struct Item{ + ColourTeam cteam; + }; + + vector<Item> teams; + World *world; + BotList *botList; + + Fl_Color genColour(){ + static const int nBase=7; + static const Fl_Color baselist[nBase]={ + FL_RED, FL_GREEN, FL_BLUE, FL_YELLOW, FL_MAGENTA, FL_DARK_RED, FL_DARK_CYAN, + }; + bool taken[nBase]; + memset(taken,0,nBase*sizeof(bool)); + for(const Item &item : teams){ + int i; + for(i=0;i<nBase;i++){ + if(baselist[i]==item.cteam.col)break; + } + if(i<nBase)taken[i]=true; + } + for(int i=0;i<nBase;i++){ + if(!taken[i])return baselist[i]; + } + return baselist[rand()%nBase]; + } + +public: + Simulation(World *world,BotList *botList) + :world(world),botList(botList){} + + void add(Team *team){ + (void)world; + teams.push_back({{team,genColour()}}); + botList->add(&teams.back().cteam); + } + + void add(const char *fname){ + cout<<"Adding team from file <"<<fname<<">"<<endl; + ifstream f(fname); + if(!f){ + fl_alert("Cannot open file '%s'",fname); + return; + } + add(new Team(assemble(preprocess(f)))); + } +}; + + +Simulation *simulation; + + +static void openBotFileChooser(){ + Fl_File_Chooser *fc=new Fl_File_Chooser( + ".","Robocom Bot Files (*.rob)",Fl_File_Chooser::MULTI,"Add bots to sim"); + fc->callback([](Fl_File_Chooser *fc,void*){ + if(fc->shown())return; + int count=fc->count(); + for(int i=1;i<=count;i++){ + simulation->add(fc->value(i)); + } + }); + fc->show(); +} + +static BotList* makeBotlist(Fl_Group *parent){ + Fl_Button *openBtn=new Fl_Button(parent->x()+1,parent->y()+1,70,20,"Add bots"); + openBtn->callback([](Fl_Widget*,void*){ + openBotFileChooser(); + }); + + return new BotList(parent); +} + +int main(int argc,char **argv){ + struct timeval tv; + gettimeofday(&tv,nullptr); + srand(tv.tv_sec*1000000+tv.tv_usec); + + + Fl_Window *window=new Fl_Window(960,800,"Mocobor"); + /*window->callback([](Fl_Widget*,void*){ + if(Fl::event()==FL_SHORTCUT&&Fl::event_key()==FL_Escape)return; + window->hide(); + });*/ + + Fl_Group *botlistGroup=new Fl_Group(10,10,150,120); + botlistGroup->box(FL_BORDER_BOX); + BotList *botList=makeBotlist(botlistGroup); + botlistGroup->end(); + + window->end(); + + + World world; + simulation=new Simulation(&world,botList); + + window->show(argc,argv); + return Fl::run(); +} |