00001 #include "wx/wxprec.h"
00002 #ifndef WX_PRECOMP
00003 #warning Precompiled wx header not used.
00004 #include "wx/wx.h"
00005 #endif
00006 #include "wx/socket.h"
00007 #include "wx/event.h"
00008 #include "../trucknet/trucknet.h"
00009 #include "wxMsg.h"
00010 #include <math.h>
00011
00012
00013 #include "wx/listimpl.cpp"
00014 WX_DECLARE_LIST(wxPoint, wxPointList);
00015 WX_DEFINE_LIST(wxPointList);
00016
00017
00028 class GuiClientApp : public wxApp
00029 {
00030 public:
00031 virtual bool OnInit();
00032 virtual int OnRun();
00033 };
00034
00035 class GuiGraphFrame : public wxFrame
00036 {
00037 public:
00038 GuiGraphFrame (const wxString &title,
00039 const wxPoint &pos,
00040 const wxSize &size);
00041 ~GuiGraphFrame();
00042
00043 };
00044
00045
00046 class GuiMapFrame : public wxFrame
00047 {
00048 public:
00049 GuiMapFrame (const wxString &title,
00050 const wxPoint &pos,
00051 const wxSize &size);
00052 ~GuiMapFrame();
00053 void OnPaint(wxPaintEvent &event);
00054 void OnClick(wxMouseEvent &event);
00055 void OnSize(wxSizeEvent &event);
00056 void PaintMe(wxDC& DC);
00057 void ScaleMe(wxDC& DC);
00058 void AddPoint(wxPoint point);
00059 void SetAngle(float radians);
00060 void Clear();
00061
00062 private:
00063
00064 wxPointList pointlist;
00065
00066
00067 int maxX, minX, maxY, minY;
00068 double scale;
00069 wxCoord offX, offY;
00070
00071
00072 float angle;
00073
00074 DECLARE_EVENT_TABLE()
00075 };
00076
00077 BEGIN_EVENT_TABLE(GuiMapFrame, wxFrame)
00078 EVT_PAINT( GuiMapFrame::OnPaint)
00079 EVT_LEFT_DOWN( GuiMapFrame::OnClick)
00080 EVT_SIZE( GuiMapFrame::OnSize)
00081 END_EVENT_TABLE()
00082
00091 class GuiClientFrame : public wxFrame
00092 {
00093 public:
00094 GuiClientFrame (const wxString &title,
00095 const wxPoint &pos,
00096 const wxSize &size);
00097 ~GuiClientFrame();
00098
00099
00100
00101 void OnQuit(wxCommandEvent& event);
00102 void OnAbout(wxCommandEvent& event);
00103 void OnMove(wxCommandEvent& event);
00104 void OnText(wxKeyEvent& event);
00105 void OnCheck(wxCommandEvent& event);
00106 void OnCommandEnter(wxCommandEvent& event);
00107 void OnSocket(wxSocketEvent& event);
00108
00109 private:
00110 wxTextCtrl *console;
00111 wxTextCtrl *commandline;
00112 wxSocketClient *sock;
00113 wxButton *forward, *left, *back, *right, *stop;
00114 wxMsg msg;
00115 wxMenu *menuMovement;
00116 GuiGraphFrame *graph;
00117 GuiMapFrame *map;
00118 void Connect();
00119 DECLARE_EVENT_TABLE()
00120
00121 };
00122
00123 GuiGraphFrame::GuiGraphFrame
00124 (const wxString &title, const wxPoint &pos, const wxSize &size)
00125 : wxFrame ( (wxFrame *) NULL, wxID_ANY, title, pos, size)
00126 {
00127
00128 }
00129
00130 GuiGraphFrame::~GuiGraphFrame()
00131 {
00132 }
00133
00134 GuiMapFrame::GuiMapFrame
00135 (const wxString &title, const wxPoint &pos, const wxSize &size)
00136 : wxFrame ( (wxFrame *) NULL, wxID_ANY, title, pos, size)
00137 {
00138 scale = 1;
00139 offX = offY = 0;
00140
00141
00142 }
00143
00144 GuiMapFrame::~GuiMapFrame()
00145 {
00146 }
00147
00148 enum event_t
00149 {
00150
00151 ID_Quit = 1,
00152 ID_About,
00153
00154
00155 ID_Stop,
00156 ID_Forward,
00157 ID_Back,
00158 ID_Left,
00159 ID_Right,
00160
00161
00162 ID_Commandline,
00163 ID_Console,
00164
00165
00166 ID_Map,
00167 ID_Graph,
00168 ID_Power,
00169 ID_Numeric,
00170 ID_FOView,
00171 };
00172
00173
00174 BEGIN_EVENT_TABLE(GuiClientFrame, wxFrame)
00175 EVT_MENU(ID_Quit, GuiClientFrame::OnQuit)
00176 EVT_MENU(ID_About, GuiClientFrame::OnAbout)
00177 EVT_MENU(ID_Stop, GuiClientFrame::OnMove)
00178 EVT_MENU(ID_Forward, GuiClientFrame::OnMove)
00179 EVT_MENU(ID_Back, GuiClientFrame::OnMove)
00180 EVT_MENU(ID_Left, GuiClientFrame::OnMove)
00181 EVT_MENU(ID_Right, GuiClientFrame::OnMove)
00182 EVT_BUTTON(ID_Stop, GuiClientFrame::OnMove)
00183 EVT_BUTTON(ID_Forward, GuiClientFrame::OnMove)
00184 EVT_BUTTON(ID_Back, GuiClientFrame::OnMove)
00185 EVT_BUTTON(ID_Left, GuiClientFrame::OnMove)
00186 EVT_BUTTON(ID_Right, GuiClientFrame::OnMove)
00187 EVT_CHECKBOX(ID_Map, GuiClientFrame::OnCheck)
00188 EVT_CHECKBOX(ID_Graph, GuiClientFrame::OnCheck)
00189 EVT_CHECKBOX(ID_Power, GuiClientFrame::OnCheck)
00190 EVT_CHECKBOX(ID_Numeric,GuiClientFrame::OnCheck)
00191 EVT_CHECKBOX(ID_FOView, GuiClientFrame::OnCheck)
00192 EVT_CHAR( GuiClientFrame::OnText)
00193 EVT_TEXT_ENTER(ID_Commandline, GuiClientFrame::OnCommandEnter)
00194 EVT_SOCKET(wxID_ANY, GuiClientFrame::OnSocket)
00195 END_EVENT_TABLE()
00196
00197 IMPLEMENT_APP(GuiClientApp)
00198
00199
00200
00210 bool GuiClientApp::OnInit()
00211 {
00212
00213 GuiClientFrame *frame = \
00214 new GuiClientFrame(wxT("RAPTOR Main Interface"), wxPoint(-1, -1), wxSize(600, 800));
00215 SetTopWindow(frame);
00216 return TRUE;
00217 }
00218
00225 int GuiClientApp::OnRun()
00226 {
00227
00228 wxApp::OnRun();
00229
00230
00231 return TRUE;
00232 }
00233
00234
00244 GuiClientFrame::GuiClientFrame
00245 (const wxString &title, const wxPoint &pos, const wxSize &size)
00246 : wxFrame ( (wxFrame *) NULL, wxID_ANY, title, pos, size)
00247 {
00248
00249 wxMenuBar *menuBar = new wxMenuBar;
00250 wxMenu *menuFile = new wxMenu;
00251 menuMovement = new wxMenu;
00252
00253 menuFile->Append( ID_About, wxT("&About...") );
00254 menuFile->AppendSeparator();
00255 menuFile->Append( ID_Quit, wxT("E&xit\tCtrl-C") );
00256 menuBar->Append( menuFile, wxT("&File") );
00257
00258 menuMovement->Append( ID_Forward, wxT("&Forward\tCtrl-W"));
00259 menuMovement->Append( ID_Left, wxT("&Left\tCtrl-A"));
00260 menuMovement->Append( ID_Back, wxT("&Back\tCtrl-S"));
00261 menuMovement->Append( ID_Right, wxT("&Right\tCtrl-D"));
00262 menuMovement->Append( ID_Stop, wxT("&Stop\tCtrl-Space"));
00263 menuBar->Append( menuMovement, wxT("&Movement") );
00264
00265 SetMenuBar( menuBar );
00266
00267
00268
00269 console = new wxTextCtrl(this , ID_Console, wxT(""), wxDefaultPosition, \
00270 wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
00271 commandline = new wxTextCtrl(this, ID_Commandline, wxT(""), \
00272 wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
00273 wxBoxSizer *textsizer = new wxBoxSizer(wxVERTICAL);
00274 textsizer->Add( commandline, 0, wxEXPAND);
00275 textsizer->Add( console, 1, wxEXPAND);
00276
00277
00278 forward = new wxButton(this,ID_Forward,wxT("Forward"));
00279 left = new wxButton(this,ID_Left,wxT("Left"));
00280 back = new wxButton(this,ID_Back,wxT("Backward"));
00281 right = new wxButton(this,ID_Right,wxT("Right"));
00282 stop = new wxButton(this,ID_Stop,wxT("Stop"));
00283
00284 wxGridSizer *buttonsizer = new wxGridSizer(1,0);
00285 buttonsizer->Add(forward ,0,wxEXPAND);
00286 buttonsizer->Add(left ,0,wxEXPAND);
00287 buttonsizer->Add(back ,0,wxEXPAND);
00288 buttonsizer->Add(right ,0,wxEXPAND);
00289 buttonsizer->Add(stop ,0,wxEXPAND);
00290
00291
00292 wxBoxSizer *checksizer = new wxBoxSizer(wxHORIZONTAL);
00293 checksizer->Add( new wxCheckBox(this, ID_Map, wxT("Map")));
00294 checksizer->Add( new wxCheckBox(this, ID_Graph, wxT("Graph")));
00295 checksizer->Add( new wxCheckBox(this, ID_Power, wxT("Power")));
00296 checksizer->Add( new wxCheckBox(this, ID_Numeric, wxT("Numeric")));
00297 checksizer->Add( new wxCheckBox(this, ID_FOView, wxT("FOView")));
00298
00299
00300 wxBoxSizer *mainsizer = new wxBoxSizer(wxHORIZONTAL);
00301 mainsizer->Add(textsizer, 1, wxEXPAND);
00302 mainsizer->Add(buttonsizer, 0, wxEXPAND);
00303 wxBoxSizer *allsizer = new wxBoxSizer(wxVERTICAL);
00304 allsizer->Add(checksizer, 0, wxEXPAND);
00305 allsizer->Add(mainsizer, 1, wxEXPAND);
00306 allsizer->SetSizeHints(this);
00307 this->SetSizer(allsizer);
00308
00309
00310 graph = new GuiGraphFrame(wxT("RAPTOR Graphs"), wxPoint(-1, -1), wxSize(600, 800));
00311 map = new GuiMapFrame(wxT("RAPTOR Map"), wxPoint(-1, -1), wxSize(600, 800));
00312
00313
00314
00315 CreateStatusBar();
00316 commandline->SetFocus();
00317 Show(true);
00318
00319
00320 sock = new wxSocketClient(wxSOCKET_NOWAIT);
00321 sock->SetEventHandler(*this);
00322 sock->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG | \
00323 wxSOCKET_LOST_FLAG);
00324 sock->Notify(true);
00325 Connect();
00326
00327
00328 msg.setsock(sock);
00329 msg.setconsole(console);
00330 }
00331
00341 GuiClientFrame::~GuiClientFrame()
00342 {
00343 delete sock;
00344 }
00345
00356 void GuiClientFrame::Connect()
00357 {
00358 SetStatusText( wxT("Connecting...") );
00359
00360 wxString hostname = wxGetTextFromUser(
00361 wxT("Enter the server address:"),
00362 wxT("Connect ..."),
00363 wxT("localhost"));
00364
00365 if(hostname.IsEmpty())
00366 { Close( true );
00367 return;
00368 }
00369 wxIPV4address addr;
00370 addr.Hostname(hostname);
00371 addr.Service(GUI_PORT.PORT);
00372 sock->Connect(addr,false);
00373 }
00374
00386 void GuiClientFrame::OnSocket(wxSocketEvent& event)
00387 {
00388 const int buflen = 32;
00389 char buf[buflen];
00390 int count;
00391
00392 switch(event.GetSocketEvent())
00393 {
00394 case wxSOCKET_CONNECTION:
00395 if(sock->IsConnected())
00396 SetStatusText(wxT("Connected."));
00397 else
00398 SetStatusText(wxT("Connected???"));
00399 break;
00400 case wxSOCKET_INPUT:
00401 msg.recv();
00402
00403 if( msg.type() == string("map"))
00404 {
00405 float x, y, theta;
00406 msg >> x >> y >> theta;
00407 map->AddPoint(wxPoint((int)(x*1000),(int)(y*1000)));
00408 map->SetAngle(theta);
00409 if(map->IsShown())
00410 {
00411 wxClientDC DC(map);
00412 map->PaintMe(DC);
00413 }
00414 }
00415 break;
00416 case wxSOCKET_LOST:
00417 *console << wxT("Disconnected.\n");
00418 Connect();
00419 break;
00420 default:
00421 SetStatusText(wxT("Unknown event on socket!"));
00422 }
00423 }
00424
00431 void GuiClientFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
00432 {
00433 Close( true );
00434 }
00435
00447 void GuiClientFrame::OnMove(wxCommandEvent& event)
00448 {
00449 switch(event.GetId())
00450 {
00451 case ID_Forward:
00452 msg << startmsg("forward") << endmsg;
00453 break;
00454 case ID_Back:
00455 msg << startmsg("back") << endmsg;
00456 break;
00457 case ID_Left:
00458 msg << startmsg("left") << endmsg;
00459 break;
00460 case ID_Right:
00461 msg << startmsg("right") << endmsg;
00462 break;
00463 case ID_Stop:
00464 msg << startmsg("stop") << endmsg;
00465 break;
00466
00467 default:
00468 wxMessageBox(wxT("Unknown movement!"),wxT("???"),wxOK | wxICON_INFORMATION );
00469 }
00470 }
00471
00472
00473 void GuiMapFrame::OnPaint(wxPaintEvent &event)
00474 {
00475 wxPaintDC DC(this);
00476 this->ScaleMe(DC);
00477 this->PaintMe(DC);
00478 event.Skip();
00479 }
00480
00481 void GuiMapFrame::OnSize(wxSizeEvent &event)
00482 {
00483 wxClientDC DC(this);
00484 PaintMe(DC);
00485 event.Skip();
00486 }
00487
00488 void GuiMapFrame::OnClick(wxMouseEvent &event)
00489 {
00490 wxPoint p = event.GetPosition();
00491 p.x = (int)(p.x/scale) - offX;
00492 p.y = (int)(p.y/scale) - offY;
00493 AddPoint(p);
00494 wxClientDC DC(this);
00495 this->PaintMe(DC);
00496
00497 event.Skip();
00498 }
00499
00500
00501 void GuiMapFrame::PaintMe(wxDC& DC)
00502 {
00503 const int grid = 1000;
00504 wxCoord w, h;
00505 DC.GetSize(&w,&h);
00506 wxCoord i, j;
00507
00508
00509 DC.SetUserScale(scale, scale);
00510
00511
00512 DC.SetBackground(*wxWHITE_BRUSH);
00513 DC.SetBackgroundMode(wxSOLID);
00514 DC.Clear();
00515
00516
00517 int radius;
00518 if (1 > 1/scale)
00519 radius = 1;
00520 else
00521 radius = (int)(1/scale);
00522 DC.SetPen(wxPen(*wxBLACK, 0));
00523 for(i = offX % grid; i < (int)(w/scale + offX); i += grid)
00524 for(j = offY % grid; j < (int)(h/scale + offX); j += grid)
00525 DC.DrawCircle(i, j, radius);
00526
00527
00528
00529 if(!pointlist.IsEmpty())
00530 DC.DrawLines((wxList *)&pointlist, offX, offY);
00531
00532
00533 if(pointlist.GetLast())
00534 {
00535 wxPoint* p = pointlist.GetLast()->GetData();
00536 DC.DrawCircle(p->x + offX, p->y + offY, 8/scale);
00537 DC.DrawLine(p->x + offX, p->y + offY,\
00538 p->x + offX + (int)(10/scale*cos(angle)),\
00539 p->y + offY + (int)(10/scale*sin(angle)));
00540 }
00541
00542
00543
00544 #if 0
00545 DC.SetPen(*wxWHITE_PEN);
00546 DC.SetBrush( *wxTRANSPARENT_BRUSH );
00547 DC.DrawRoundedRectangle(150, 270, 49, 29, 6);
00548 DC.DrawRoundedRectangle(200, 270, 49, 29, 6);
00549 DC.SetPen(*wxWHITE_PEN);
00550 DC.DrawLine(250, 270, 250, 310);
00551 DC.DrawLine(150, 300, 260, 300);
00552 #endif
00553 }
00554
00555 void GuiMapFrame::AddPoint(wxPoint point)
00556 {
00557 pointlist.Append(new wxPoint(point));
00558
00559 if(pointlist.IsEmpty())
00560 {
00561 minX = maxX = point.x;
00562 minY = maxY = point.y;
00563 }
00564 else
00565 {
00566
00567 if(point.x < minX)
00568 minX = point.x;
00569 else if(point.x > maxX)
00570 maxX = point.x;
00571
00572 if(point.y < minY)
00573 minY = point.y;
00574 else if(point.y > maxY)
00575 maxY = point.y;
00576 }
00577
00578
00579 if(this->IsShown())
00580 {
00581 wxClientDC DC(this);
00582 ScaleMe(DC);
00583 }
00584 }
00585
00586
00587
00588 void GuiMapFrame::ScaleMe(wxDC &DC)
00589 {
00590 wxCoord w, h;
00591 double temp;
00592
00593 DC.GetSize(&w,&h);
00594 if( (scale=(double)(maxX - minX)) != 0)
00595 scale = .9*w/scale;
00596 else
00597 scale = 1;
00598
00599 if( (temp=(double)(maxY - minY)) != 0)
00600 temp = .9*h/temp;
00601 else
00602 temp = 1;
00603
00604 if(temp < scale)
00605 scale = temp;
00606
00607
00608 offX = -(int)((maxX + minX - w/scale)/2);
00609 offY = -(int)((maxY + minY - h/scale)/2);
00610 }
00611
00612 void GuiMapFrame::SetAngle(float radians)
00613 {
00614 angle = radians;
00615 }
00616
00617 void GuiClientFrame::OnCheck(wxCommandEvent& event)
00618 {
00619 switch(event.GetId())
00620 {
00621 case ID_Map:
00622 if (event.IsChecked())
00623 {
00624 map->Show(true);
00625
00626
00627
00628
00629
00630 }
00631 else
00632 map->Show(false);
00633 break;
00634 case ID_Graph:
00635 if (event.IsChecked())
00636 graph->Show(true);
00637 else
00638 graph->Show(false);
00639
00640 break;
00641 case ID_Power:
00642 if (event.IsChecked())
00643 wxMessageBox(wxT("Power not yet implemented."),wxT("Not implemented"),wxOK | wxICON_INFORMATION );
00644 ((wxCheckBox*)event.GetEventObject())->SetValue(false);
00645 break;
00646 case ID_Numeric:
00647 if (event.IsChecked())
00648 wxMessageBox(wxT("Numeric not yet implemented."),wxT("Not implemented"),wxOK | wxICON_INFORMATION );
00649 ((wxCheckBox*)event.GetEventObject())->SetValue(false);
00650 break;
00651 case ID_FOView:
00652 if (event.IsChecked())
00653 wxMessageBox(wxT("FOView not yet implemented."),wxT("Not implemented"),wxOK | wxICON_INFORMATION );
00654 ((wxCheckBox*)event.GetEventObject())->SetValue(false);
00655 break;
00656
00657 default:
00658 wxMessageBox(wxT("Unknown Checkbox!"),wxT("???"),wxOK | wxICON_INFORMATION );
00659 }
00660 }
00661
00668 void GuiClientFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
00669 {
00670 wxMessageBox( wxT("This is a wxWidgets' Hello world sample"),
00671 wxT("About Hello World"), wxOK | wxICON_INFORMATION );
00672 }
00673
00674
00684 void GuiClientFrame::OnText(wxKeyEvent& event)
00685 {
00686 if(event.GetKeyCode() == WXK_TAB)
00687 {
00688 if(commandline->IsEnabled())
00689 {
00690 menuMovement->FindItem(ID_Forward)->SetText(wxT("&Forward\tW"));
00691 menuMovement->FindItem(ID_Left)->SetText(wxT("&Left\tA"));
00692 menuMovement->FindItem(ID_Back)->SetText(wxT("&Back\tS"));
00693 menuMovement->FindItem(ID_Right)->SetText(wxT("&Right\tD"));
00694 menuMovement->FindItem(ID_Stop)->SetText(wxT("&Stop\tSpace"));
00695
00696 #if 0
00697 menuMovement->Destroy(ID_Forward);
00698 menuMovement->Destroy(ID_Left);
00699 menuMovement->Destroy(ID_Back);
00700 menuMovement->Destroy(ID_Right);
00701 menuMovement->Destroy(ID_Stop);
00702
00703 menuMovement->Append( ID_Forward, wxT("&Forward\tW"));
00704 menuMovement->Append( ID_Left, wxT("&Left\tA"));
00705 menuMovement->Append( ID_Back, wxT("&Back\tS"));
00706 menuMovement->Append( ID_Right, wxT("&Right\tD"));
00707 menuMovement->Append( ID_Stop, wxT("&Stop\tSpace"));
00708 #endif
00709 commandline->Disable();
00710 stop->SetFocus();
00711 } else {
00712 menuMovement->FindItem(ID_Forward)->SetText(wxT("&Forward\tCtrl-W"));
00713 menuMovement->FindItem(ID_Left)->SetText(wxT("&Left\tCtrl-A"));
00714 menuMovement->FindItem(ID_Back)->SetText(wxT("&Back\tCtrl-S"));
00715 menuMovement->FindItem(ID_Right)->SetText(wxT("&Right\tCtrl-D"));
00716 menuMovement->FindItem(ID_Stop)->SetText(wxT("&Stop\tCtrl-Space"));
00717 #if 0
00718 menuMovement->Destroy(ID_Forward);
00719 menuMovement->Destroy(ID_Left);
00720 menuMovement->Destroy(ID_Back);
00721 menuMovement->Destroy(ID_Right);
00722 menuMovement->Destroy(ID_Stop);
00723
00724 menuMovement->Append( ID_Forward, wxT("&Forward\tCtrl-W"));
00725 menuMovement->Append( ID_Left, wxT("&Left\tCtrl-A"));
00726 menuMovement->Append( ID_Back, wxT("&Back\tCtrl-S"));
00727 menuMovement->Append( ID_Right, wxT("&Right\tCtrl-D"));
00728 menuMovement->Append( ID_Stop, wxT("&Stop\tCtrl-Space"));
00729 #endif
00730 commandline->Enable();
00731 commandline->SetFocus();
00732 }
00733 }
00734 }
00735
00745 void GuiClientFrame::OnCommandEnter(wxCommandEvent& event)
00746 {
00747 int i;
00748 wxString input = commandline->GetValue();
00749 i = input.Find(wxT(" "));
00750 if(i > -1)
00751 {
00752
00753 msg << startmsg(input.Left(i).mb_str());
00754 input = input.Remove(0,i+1);
00755 } else {
00756
00757 msg << startmsg(input.mb_str());
00758 input.Clear();
00759 }
00760 while(input.Len() > 0)
00761 {
00762 i = input.Find(wxT(" "));
00763 if(i > -1)
00764 {
00765
00766 msg << input.Left(i).mb_str();
00767 input = input.Remove(0,i+1);
00768 } else {
00769
00770 msg << input.mb_str();
00771 input.Clear();
00772 }
00773 }
00774 msg << endmsg;
00775 commandline->Clear();
00776 }
00777