00001 #include "headers.h"
00002 #include <vector>
00003
00004
00005 using std::vector;
00006
00007
00008
00009
00010
00011
00012
00013 BEGIN_EVENT_TABLE(VisualizerFrame, wxFrame)
00014 EVT_PAINT(VisualizerFrame::OnPaint)
00015 EVT_COMMAND(REFRESH_EVENT, wxEVT_COMMAND_ENTER, VisualizerFrame::OnRefreshEvent)
00016 END_EVENT_TABLE()
00017
00018
00019
00020 VisualizerFrame::VisualizerFrame()
00021 : wxFrame((wxFrame *)NULL, -1, "Peekabooty")
00022 {
00023
00024
00025 m_listener.setFrame(this);
00026
00027
00028
00029
00030 const wxRect frameRect(wxPoint(0,0), wxSize(1024, 768));
00031 this->SetSize(wxRect(frameRect));
00032
00033 loadBitmaps();
00034
00035 startAngle = 3.141592 / 4;
00036
00037
00038 m_VisualizerThread = new PbVisualizerThread(this);
00039 m_VisualizerThread->Create();
00040 m_VisualizerThread->Run();
00041
00042 getInitialNeighborNodes();
00043
00044 }
00045
00046
00047
00048 void
00049 VisualizerFrame::getInitialNeighborNodes()
00050 {
00051 LinkLayerInterface* lli = GlobalObjects::instance()->getNetworkLayer()->getLli();
00052 int numConnections = lli->getNumConnections();
00053
00054 for (int i=0; i < numConnections; i++)
00055 {
00056 Node* currentNode = lli->getConnection(i);
00057 m_neighborNodes.push_back(currentNode);
00058 }
00059 }
00060
00061
00062
00063 void
00064 VisualizerFrame::loadBitmaps()
00065 {
00066 const wxString LOGO_FILE = "logo.bmp";
00067 const wxString LEGEND_FILE = "legend.bmp";
00068 const wxString NORMAL_NODE_ICON_FILE = "normal_node_icon.bmp";
00069 const wxString NATTED_NODE_ICON_FILE = "natted_node_icon.bmp";
00070 const wxString CENSORED_NODE_ICON_FILE = "censored_node_icon.bmp";
00071 const wxString NO_CONNECTIONS_NODE_ICON_FILE = "no_connections_node_icon.bmp";
00072
00073
00074 wxString curDir = wxGetCwd() + "\\images\\";
00075
00076 m_pLogoGraphic = new wxBitmap();
00077 m_pLogoGraphic->LoadFile(curDir + LOGO_FILE, wxBITMAP_TYPE_BMP);
00078 m_pLegendGraphic = new wxBitmap();
00079 m_pLegendGraphic->LoadFile(curDir + LEGEND_FILE, wxBITMAP_TYPE_BMP);
00080 m_pNormalNodeIcon = new wxBitmap();
00081 m_pNormalNodeIcon->LoadFile(curDir + NORMAL_NODE_ICON_FILE, wxBITMAP_TYPE_BMP);
00082 m_pNattedNodeIcon = new wxBitmap();
00083 m_pNattedNodeIcon->LoadFile(curDir + NATTED_NODE_ICON_FILE, wxBITMAP_TYPE_BMP);
00084 m_pCensoredNodeIcon = new wxBitmap();
00085 m_pCensoredNodeIcon->LoadFile(curDir + CENSORED_NODE_ICON_FILE, wxBITMAP_TYPE_BMP);
00086 m_pNoConnectionsNodeIcon = new wxBitmap();
00087 m_pNoConnectionsNodeIcon->LoadFile(curDir + NO_CONNECTIONS_NODE_ICON_FILE, wxBITMAP_TYPE_BMP);
00088
00089 }
00090
00091
00092
00093 void
00094 VisualizerFrame::DrawStuff(wxDC* dc, int width, int height)
00095 {
00096 wxBrush* backgroundColorBrush = wxBLACK_BRUSH;
00097 wxPen* backgroundColorPen = wxBLACK_PEN;
00098 wxBrush* foregroundColorBrush = wxWHITE_BRUSH;
00099 wxPen* foregroundColorPen = wxWHITE_PEN;
00100 wxFont textFont;
00101 textFont.SetFaceName("Verdana");
00102 dc->SetBackground(*wxBLACK_BRUSH);
00103 dc->SetBrush(*foregroundColorBrush);
00104
00105
00106 dc->Clear();
00107
00108
00109 calculateNodes();
00110 dc->DrawBitmap(*m_pLogoGraphic, wxPoint(10,10));
00111 dc->DrawBitmap(*m_pLegendGraphic, wxPoint(80, 250));
00112 drawNodes(dc);
00113
00114 wxColour* wxforeText = wxWHITE;
00115 wxColour* wxbackText = wxBLACK;
00116 dc->SetFont(textFont);
00117 dc->SetTextForeground(*wxforeText);
00118 dc->SetTextBackground(*wxbackText);
00119
00120 }
00121
00122
00123
00124 void
00125 VisualizerFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
00126 {
00127 int width, height;
00128 this->GetSize(&width, &height);
00129
00130 wxBitmap bitmap(width, height);
00131
00132 wxMemoryDC memoryDC;
00133 memoryDC.SelectObject(bitmap);
00134 DrawStuff(&memoryDC, width, height);
00135
00136 wxPaintDC dc(this);
00137
00138 dc.Blit(0, 0, width, height, &memoryDC, 0, 0);
00139
00140 }
00141
00142
00143
00144 void
00145 VisualizerFrame::OnRefreshEvent(wxUpdateUIEvent& event)
00146 {
00147
00148 int clipRectX = 0;
00149 int clipRectY = 0;
00150 int width, height;
00151 this->GetSize(&width, &height);
00152 int clipRectWidth = width;
00153 int clipRectHeight = height;
00154 wxRect rect(clipRectX, clipRectY, width, height);
00155
00156
00157 this->Refresh(FALSE, &rect);
00158
00159 }
00160
00161
00162
00163 void
00164 VisualizerFrame::CloseMe(wxEvent& WXUNUSED(event))
00165 {
00166
00167 delete m_pLogoGraphic;
00168 delete m_pLegendGraphic;
00169 delete m_pNormalNodeIcon;
00170 delete m_pNattedNodeIcon;
00171 delete m_pCensoredNodeIcon;
00172 delete m_pNoConnectionsNodeIcon;
00173
00174 m_VisualizerThread->Delete();
00175 Close(TRUE);
00176
00177 }
00178
00179
00180
00181 void
00182 VisualizerFrame::addMessage(VisualizerNodeMessage* message)
00183 {
00184 m_nodeMessageQueue.add(message);
00185
00186 }
00187
00188
00189
00190 void
00191 VisualizerFrame::calculateNodes()
00192 {
00193
00194
00195 while (!m_nodeMessageQueue.isEmpty())
00196 {
00197 VisualizerNodeMessage* v = m_nodeMessageQueue.getNext();
00198 if (v->isAdded())
00199 {
00200
00201
00202
00203
00204 vector<Node*>::iterator iter;
00205 bool found = false;
00206 for (iter = m_neighborNodes.begin(); iter != m_neighborNodes.end(); ++iter) {
00207 if (*iter == v->getNode()) {
00208 found = true;
00209 }
00210 }
00211
00212
00213 if (!found) {
00214 m_neighborNodes.push_back(v->getNode());
00215 }
00216 }
00217 else
00218 {
00219 vector<Node*>::iterator iter = find(m_neighborNodes.begin(), m_neighborNodes.end(), v->getNode());
00220 if (iter != m_neighborNodes.end())
00221 {
00222 m_neighborNodes.erase(iter);
00223 }
00224
00225 }
00226 }
00227
00228 }
00229
00230
00231
00232 void
00233 VisualizerFrame::drawNodes(wxDC* dc)
00234 {
00235 const wxCoord NODE_ORIGIN_X = 600;
00236 const wxCoord NODE_ORIGIN_Y = 350;
00237 const int NODE_DIAMETER = 120;
00238 const int NODE_RADIUS = NODE_DIAMETER / 2;
00239 const int NODE_CONNECTION_LINE_WIDTH = 7;
00240 const int TEXT_PADDING = 10;
00241
00242 const double PI = 3.141592;
00243 const wxCoord radius = 200;
00244 double angle = startAngle;
00245 startAngle = startAngle + (PI / 30.0);
00246 if (startAngle >= 2 * PI)
00247 {
00248 startAngle = startAngle - (2 * PI);
00249 }
00250
00251 wxBrush* backgroundColorBrush = wxBLACK_BRUSH;
00252 wxPen* backgroundColorPen = wxBLACK_PEN;
00253 wxBrush* foregroundColorBrush = wxWHITE_BRUSH;
00254 wxPen* foregroundColorPen = wxWHITE_PEN;
00255 foregroundColorPen->SetWidth(NODE_CONNECTION_LINE_WIDTH);
00256 wxFont textFont;
00257 textFont.SetFaceName("Verdana");
00258 textFont.SetPointSize(8);
00259 wxColour* wxforeText = wxWHITE;
00260 wxColour* wxbackText = wxBLACK;
00261 dc->SetFont(textFont);
00262 dc->SetTextForeground(*wxforeText);
00263 dc->SetTextBackground(*wxbackText);
00264
00265 dc->SetBackground(*backgroundColorBrush);
00266 dc->SetBrush(*foregroundColorBrush);
00267 dc->SetPen(*foregroundColorPen);
00268
00269
00270 dc->BeginDrawing();
00271
00272
00273 int numNodes = m_neighborNodes.size();
00274 double angleBetweenNodes = (2 * PI) / numNodes;
00275
00276 for (int currentNode = 0; currentNode < numNodes; currentNode++)
00277 {
00278
00279 wxCoord nodeX = static_cast<wxCoord>((radius * cos(angle)) + NODE_ORIGIN_X);
00280 wxCoord nodeY = static_cast<wxCoord>((radius * sin(angle)) + NODE_ORIGIN_Y);
00281
00282 dc->DrawLine(wxPoint(NODE_ORIGIN_X, NODE_ORIGIN_Y),
00283 wxPoint(nodeX, nodeY));
00284 dc->DrawEllipse(wxPoint(nodeX - NODE_RADIUS, nodeY - NODE_RADIUS),
00285 wxSize(NODE_DIAMETER, NODE_DIAMETER));
00286
00287
00288
00289
00290
00291
00292 wxBitmap* pCurrentIcon;
00293 if (m_neighborNodes[currentNode]->isFirewalled())
00294 {
00295 pCurrentIcon = m_pCensoredNodeIcon;
00296 }
00297 else if (m_neighborNodes[currentNode]->isNatted())
00298 {
00299 pCurrentIcon = m_pNattedNodeIcon;
00300 }
00301 else
00302 {
00303 pCurrentIcon = m_pNormalNodeIcon;
00304 }
00305
00306 int neighbourNodeIconXOffset = m_pNormalNodeIcon->GetWidth() / 2;
00307 int neighbourNodeIconYOffset = m_pNormalNodeIcon->GetHeight() / 2;
00308 dc->DrawBitmap(*pCurrentIcon, wxPoint(nodeX - neighbourNodeIconXOffset,
00309 nodeY - neighbourNodeIconYOffset));
00310
00311
00312 wxString nodeIPAddress = m_neighborNodes[currentNode]->getSocketAddress()->getIpAddress().toCStr();
00313 int textYOffset;
00314 if ((angle > 0) && (angle < PI))
00315 {
00316 textYOffset = NODE_RADIUS + TEXT_PADDING;
00317 }
00318 else
00319 {
00320 textYOffset = -NODE_RADIUS - (TEXT_PADDING * 2);
00321 }
00322
00323 dc->DrawText(nodeIPAddress, wxPoint(nodeX + TEXT_PADDING, nodeY + textYOffset));
00324
00325
00326 angle = angle - angleBetweenNodes;
00327 if (angleBetweenNodes < 0)
00328 {
00329 angleBetweenNodes = ((2 * PI) - angleBetweenNodes);
00330 }
00331
00332 }
00333
00334
00335 wxBitmap* pUserNodeIcon;
00336 if (numNodes > 0)
00337 {
00338 pUserNodeIcon = m_pNormalNodeIcon;
00339 }
00340 else
00341 {
00342 pUserNodeIcon = m_pNoConnectionsNodeIcon;
00343 }
00344
00345 dc->DrawEllipse(wxPoint(NODE_ORIGIN_X - NODE_RADIUS, NODE_ORIGIN_Y - NODE_RADIUS),
00346 wxSize(NODE_DIAMETER, NODE_DIAMETER));
00347 dc->DrawBitmap(*pUserNodeIcon, wxPoint(NODE_ORIGIN_X - (m_pNormalNodeIcon->GetWidth() / 2),
00348 NODE_ORIGIN_Y - (m_pNormalNodeIcon->GetHeight() / 2)));
00349
00350
00351 dc->EndDrawing();
00352
00353 }