]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/ogl/src/ogldiag.cpp
Change a Popup menu from using a callback to using events. Can't test
[wxWidgets.git] / utils / ogl / src / ogldiag.cpp
index 60efe27a7d23f0dd486df65f6099431fc500a079..b447f545ed24585348e8f2b43fda9ddbcc890e86 100644 (file)
 #include <wx/wx.h>
 #endif
 
-#ifdef PROLOGIO
 #include <wx/wxexpr.h>
-#endif
 
-#if USE_IOSTREAMH
+#if wxUSE_IOSTREAMH
 #include <iostream.h>
+#include <fstream.h>
 #else
 #include <iostream>
+#include <fstream>
+#ifdef _MSC_VER
+using namespace std;
+#endif
 #endif
 
-#include <fstream.h>
 #include <ctype.h>
 #include <math.h>
 #include <stdlib.h>
@@ -91,7 +93,7 @@ void wxDiagram::Redraw(wxDC& dc)
   if (m_shapeList)
   {
     if (GetCanvas())
-      GetCanvas()->SetCursor(wxHOURGLASS_CURSOR);
+      GetCanvas()->SetCursor(wxHOURGLASS_CURSOR);
     wxNode *current = m_shapeList->First();
 
     while (current)
@@ -103,7 +105,7 @@ void wxDiagram::Redraw(wxDC& dc)
       current = current->Next();
     }
     if (GetCanvas())
-      GetCanvas()->SetCursor(wxSTANDARD_CURSOR);
+      GetCanvas()->SetCursor(wxSTANDARD_CURSOR);
   }
 }
 
@@ -189,20 +191,20 @@ void wxDiagram::DrawOutline(wxDC& dc, double x1, double y1, double x2, double y2
 
   wxPoint points[5];
 
-  points[0].x = x1;
-  points[0].y = y1;
+  points[0].x = (int) x1;
+  points[0].y = (int) y1;
 
-  points[1].x = x2;
-  points[1].y = y1;
+  points[1].x = (int) x2;
+  points[1].y = (int) y1;
 
-  points[2].x = x2;
-  points[2].y = y2;
+  points[2].x = (int) x2;
+  points[2].y = (int) y2;
 
-  points[3].x = x1;
-  points[3].y = y2;
+  points[3].x = (int) x1;
+  points[3].y = (int) y2;
 
-  points[4].x = x1;
-  points[4].y = y1;
+  points[4].x = (int) x1;
+  points[4].y = (int) y1;
   dc.DrawLines(5, points);
 }
 
@@ -223,20 +225,20 @@ void wxDiagram::RecentreAll(wxDC& dc)
 bool wxDiagram::SaveFile(const wxString& filename)
 {
   wxBeginBusyCursor();
-  
+
   wxExprDatabase *database = new wxExprDatabase;
 
   // First write the diagram type
   wxExpr *header = new wxExpr("diagram");
   OnHeaderSave(*database, *header);
-  
+
   database->Append(header);
-  
+
   wxNode *node = m_shapeList->First();
   while (node)
   {
     wxShape *shape = (wxShape *)node->Data();
-    
+
     if (!shape->IsKindOf(CLASSINFO(wxControlPoint)))
     {
       wxExpr *expr = NULL;
@@ -250,19 +252,19 @@ bool wxDiagram::SaveFile(const wxString& filename)
     node = node->Next();
   }
   OnDatabaseSave(*database);
-  
+
   char tempFile[400];
   wxGetTempFileName("diag", tempFile);
-  ofstream stream(tempFile);
-  if (stream.bad())
+  FILE* file = fopen(tempFile, "w");
+  if (! file)
   {
     wxEndBusyCursor();
     delete database;
     return FALSE;
   }
-  
-  database->Write(stream);
-  stream.close();
+
+  database->Write(file);
+  fclose(file);
   delete database;
 
 /*
@@ -299,14 +301,14 @@ bool wxDiagram::SaveFile(const wxString& filename)
 bool wxDiagram::LoadFile(const wxString& filename)
 {
   wxBeginBusyCursor();
-  
-  wxExprDatabase database(PrologInteger, "id");
+
+  wxExprDatabase database(wxExprInteger, "id");
   if (!database.Read(filename))
   {
     wxEndBusyCursor();
     return FALSE;
   }
-  
+
   DeleteAllShapes();
 
   database.BeginFind();
@@ -329,7 +331,7 @@ bool wxDiagram::LoadFile(const wxString& filename)
   ReadNodes(database);
   ReadContainerGeometry(database);
   ReadLines(database);
-  
+
   OnDatabaseLoad(database);
 
   wxEndBusyCursor();
@@ -354,7 +356,7 @@ void wxDiagram::ReadNodes(wxExprDatabase& database)
     {
       wxShape *shape = (wxShape *)classInfo->CreateObject();
       OnShapeLoad(database, *shape, *clause);
-      
+
       shape->SetCanvas(GetCanvas());
       shape->Show(TRUE);
 
@@ -376,7 +378,7 @@ void wxDiagram::ReadNodes(wxExprDatabase& database)
     }
     if (type)
       delete[] type;
-      
+
     clause = database.FindClauseByFunctor("shape");
   }
   return;
@@ -400,6 +402,7 @@ void wxDiagram::ReadLines(wxExprDatabase& database)
       shape->Show(TRUE);
 
       OnShapeLoad(database, *shape, *clause);
+      shape->SetCanvas(GetCanvas());
 
       long image_to = -1; long image_from = -1;
       clause->GetAttributeValue("to", image_to);
@@ -536,7 +539,7 @@ bool wxDiagram::OnDatabaseSave(wxExprDatabase& db)
 
 bool wxDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
 {
-  shape.WritePrologAttributes(&expr);
+  shape.WriteAttributes(&expr);
   db.Append(&expr);
 
   if (shape.IsKindOf(CLASSINFO(wxCompositeShape)))
@@ -556,7 +559,7 @@ bool wxDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
 
 bool wxDiagram::OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
 {
-  shape.ReadPrologAttributes(&expr);
+  shape.ReadAttributes(&expr);
   return TRUE;
 }
 
@@ -577,4 +580,177 @@ void wxDiagram::SetCanvas(wxShapeCanvas *can)
   m_diagramCanvas = can;
 }
 
+// Find a shape by its id
+wxShape* wxDiagram::FindShape(long id) const
+{
+    wxNode* node = GetShapeList()->First();
+    while (node)
+    {
+        wxShape* shape = (wxShape*) node->Data();
+        if (shape->GetId() == id)
+            return shape;
+        node = node->Next();
+    }
+    return NULL;
+}
+
+
+//// Crossings classes
+
+wxLineCrossings::wxLineCrossings()
+{
+}
+
+wxLineCrossings::~wxLineCrossings()
+{
+    ClearCrossings();
+}
+
+void wxLineCrossings::FindCrossings(wxDiagram& diagram)
+{
+    ClearCrossings();
+    wxNode* node1 = diagram.GetShapeList()->First();
+    while (node1)
+    {
+        wxShape* shape1 = (wxShape*) node1->Data();
+        if (shape1->IsKindOf(CLASSINFO(wxLineShape)))
+        {
+            wxLineShape* lineShape1 = (wxLineShape*) shape1;
+            // Iterate through the segments
+            wxList* pts1 = lineShape1->GetLineControlPoints();
+            int i;
+            for (i = 0; i < (pts1->Number() - 1); i++)
+            {
+                wxRealPoint* pt1_a = (wxRealPoint*) (pts1->Nth(i)->Data());
+                wxRealPoint* pt1_b = (wxRealPoint*) (pts1->Nth(i+1)->Data());
+
+                // Now we iterate through the segments again
+
+                wxNode* node2 = diagram.GetShapeList()->First();
+                while (node2)
+                {
+                    wxShape* shape2 = (wxShape*) node2->Data();
+
+                    // Assume that the same line doesn't cross itself
+                    if (shape2->IsKindOf(CLASSINFO(wxLineShape)) && (shape1 != shape2))
+                    {
+                        wxLineShape* lineShape2 = (wxLineShape*) shape2;
+                        // Iterate through the segments
+                        wxList* pts2 = lineShape2->GetLineControlPoints();
+                        int j;
+                        for (j = 0; j < (pts2->Number() - 1); j++)
+                        {
+                            wxRealPoint* pt2_a = (wxRealPoint*) (pts2->Nth(j)->Data());
+                            wxRealPoint* pt2_b = (wxRealPoint*) (pts2->Nth(j+1)->Data());
+
+                            // Now let's see if these two segments cross.
+                            double ratio1, ratio2;
+                            oglCheckLineIntersection(pt1_a->x, pt1_a->y, pt1_b->x, pt1_b->y,
+                               pt2_a->x, pt2_a->y, pt2_b->x, pt2_b->y,
+                             & ratio1, & ratio2);
+
+                            if ((ratio1 < 1.0) && (ratio1 > -1.0))
+                            {
+                                // Intersection!
+                                wxLineCrossing* crossing = new wxLineCrossing;
+                                crossing->m_intersect.x = (pt1_a->x + (pt1_b->x - pt1_a->x)*ratio1);
+                                crossing->m_intersect.y = (pt1_a->y + (pt1_b->y - pt1_a->y)*ratio1);
+
+                                crossing->m_pt1 = * pt1_a;
+                                crossing->m_pt2 = * pt1_b;
+                                crossing->m_pt3 = * pt2_a;
+                                crossing->m_pt4 = * pt2_b;
+
+                                crossing->m_lineShape1 = lineShape1;
+                                crossing->m_lineShape2 = lineShape2;
+
+                                m_crossings.Append(crossing);
+                            }
+                        }
+                    }
+                    node2 = node2->Next();
+                }
+            }
+        }
+
+        node1 = node1->Next();
+    }
+}
+
+void wxLineCrossings::DrawCrossings(wxDiagram& diagram, wxDC& dc)
+{
+    dc.SetBrush(*wxTRANSPARENT_BRUSH);
+
+    long arcWidth = 8;
+
+    wxNode* node = m_crossings.First();
+    while (node)
+    {
+        wxLineCrossing* crossing = (wxLineCrossing*) node->Data();
+//        dc.DrawEllipse((long) (crossing->m_intersect.x - (arcWidth/2.0) + 0.5), (long) (crossing->m_intersect.y - (arcWidth/2.0) + 0.5),
+//           arcWidth, arcWidth);
+
+
+        // Let's do some geometry to find the points on either end of the arc.
+/*
+
+(x1, y1)
+    |\
+    | \
+    |  \
+    |   \
+    |    \
+    |    |\ c    c1
+    |  a | \
+         |  \
+    |     -  x <-- centre of arc
+ a1 |     b  |\
+    |        | \ c2
+    |     a2 |  \
+    |         -  \
+    |         b2  \
+    |              \
+    |_______________\ (x2, y2)
+          b1
+
+*/
+
+        double a1 = wxMax(crossing->m_pt1.y, crossing->m_pt2.y) - wxMin(crossing->m_pt1.y, crossing->m_pt2.y) ;
+        double b1 = wxMax(crossing->m_pt1.x, crossing->m_pt2.x) - wxMin(crossing->m_pt1.x, crossing->m_pt2.x) ;
+        double c1 = sqrt( (a1*a1) + (b1*b1) );
+
+        double c = arcWidth / 2.0;
+        double a = c * a1/c1 ;
+        double b = c * b1/c1 ;
+
+        // I'm not sure this is right, since we don't know which direction we should be going in - need
+        // to know which way the line slopes and choose the sign appropriately.
+        double arcX1 = crossing->m_intersect.x - b;
+        double arcY1 = crossing->m_intersect.y - a;
+
+        double arcX2 = crossing->m_intersect.x + b;
+        double arcY2 = crossing->m_intersect.y + a;
+
+        dc.SetPen(*wxBLACK_PEN);
+        dc.DrawArc( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2,
+            (long) crossing->m_intersect.x, (long) crossing->m_intersect.y);
+
+        dc.SetPen(*wxWHITE_PEN);
+        dc.DrawLine( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2 );
+
+        node = node->Next();
+    }
+}
+
+void wxLineCrossings::ClearCrossings()
+{
+    wxNode* node = m_crossings.First();
+    while (node)
+    {
+        wxLineCrossing* crossing = (wxLineCrossing*) node->Data();
+        delete crossing;
+        node = node->Next();
+    }
+    m_crossings.Clear();
+}