Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

VisualizerFrame.cpp

Go to the documentation of this file.
00001 #include "headers.h"
00002 #include <vector>
00003 
00004 
00005 using std::vector;
00006 
00007 //
00008 // VisualizerFrame class
00009 // =====================
00010 //
00011 
00012 // The event table for the screen saver frame
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         // Register the listener object
00024         // This *must* be the first thing that happens!
00025         m_listener.setFrame(this);
00026 
00027         // For the CodeCon demo, we're going to make the Visualizer
00028         // a frame with a set size of 1024 * 768. We'll eventually
00029         // make it a screen-saver style app.
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         // start the refresh message thread
00038     m_VisualizerThread = new PbVisualizerThread(this);
00039     m_VisualizerThread->Create();
00040     m_VisualizerThread->Run();
00041         
00042         getInitialNeighborNodes();
00043 
00044 } // constructor
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 } // loadBitmaps()
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     // clear the screen
00106     dc->Clear();
00107 
00108         // Render items on screen
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 } // DrawStuff()
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 } // OnPaint()
00141 
00142 
00143 
00144 void 
00145 VisualizerFrame::OnRefreshEvent(wxUpdateUIEvent& event) 
00146 {
00147         // Calculate clipping rectangle
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         // Refresh() calls OnPaint()
00157     this->Refresh(FALSE, &rect); 
00158 
00159 } // OnRefreshEvent()
00160 
00161 
00162 
00163 void 
00164 VisualizerFrame::CloseMe(wxEvent& WXUNUSED(event)) 
00165 {
00166         // Unload bitmaps
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 } // CloseMe()
00178 
00179 
00180 
00181 void
00182 VisualizerFrame::addMessage(VisualizerNodeMessage* message)
00183 {
00184         m_nodeMessageQueue.add(message);
00185 
00186 } // addMessage()
00187 
00188 
00189 
00190 void 
00191 VisualizerFrame::calculateNodes()
00192 {
00193         //m_neighborNodes.clear();
00194 
00195         while (!m_nodeMessageQueue.isEmpty())
00196         {
00197                 VisualizerNodeMessage* v = m_nodeMessageQueue.getNext();
00198                 if (v->isAdded())
00199                 {
00200             // Check that the node isnt already in the list -
00201             // this can happen during initialization.  The time between registering as a listener
00202             // and initializing the node list, an event can occur in which case there would be a 
00203             // duplicate node entry.
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             // only add it if its not there already
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         // Draw surrounding nodes
00273         int numNodes = m_neighborNodes.size();
00274         double angleBetweenNodes = (2 * PI) / numNodes;
00275 
00276         for (int currentNode = 0; currentNode < numNodes; currentNode++)
00277         {
00278                 // Draw node connection, background circle and icon
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                 // Determine which icon to draw.
00288                 // Currently, one of 3 icons will be drawn:
00289                 // 1. Censored (or Firewalled)
00290                 // 2. NATted
00291                 // 3. Normal
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                 // Draw IP address
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                 // Calculate angle
00326                 angle = angle - angleBetweenNodes;
00327                 if (angleBetweenNodes < 0)
00328                 {
00329                         angleBetweenNodes = ((2 * PI) - angleBetweenNodes);
00330                 } // if
00331 
00332         } // for
00333 
00334         // Draw user's node
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 } // drawNodes()

Generated at Thu Jul 11 13:31:53 2002 for Peekabooty by doxygen1.2.9 written by Dimitri van Heesch, © 1997-2001