]>
git.saurik.com Git - wxWidgets.git/blob - utils/ogl/src/ogldiag.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "ogldiag.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include <wx/wxprec.h>
28 #include <wx/wxexpr.h>
50 IMPLEMENT_DYNAMIC_CLASS(wxDiagram
, wxObject
)
53 wxDiagram::wxDiagram()
55 m_diagramCanvas
= NULL
;
56 m_quickEditMode
= FALSE
;
59 m_shapeList
= new wxList
;
60 m_mouseTolerance
= DEFAULT_MOUSE_TOLERANCE
;
63 wxDiagram::~wxDiagram()
69 void wxDiagram::SetSnapToGrid(bool snap
)
74 void wxDiagram::SetGridSpacing(double spacing
)
76 m_gridSpacing
= spacing
;
79 void wxDiagram::Snap(double *x
, double *y
)
83 *x
= m_gridSpacing
* ((int)(*x
/m_gridSpacing
+ 0.5));
84 *y
= m_gridSpacing
* ((int)(*y
/m_gridSpacing
+ 0.5));
89 void wxDiagram::Redraw(wxDC
& dc
)
94 GetCanvas()->SetCursor(wxHOURGLASS_CURSOR
);
95 wxNode
*current
= m_shapeList
->First();
99 wxShape
*object
= (wxShape
*)current
->Data();
100 if (!object
->GetParent())
103 current
= current
->Next();
106 GetCanvas()->SetCursor(wxSTANDARD_CURSOR
);
110 void wxDiagram::Clear(wxDC
& dc
)
115 // Insert object after addAfter, or at end of list.
116 void wxDiagram::AddShape(wxShape
*object
, wxShape
*addAfter
)
118 wxNode
*nodeAfter
= NULL
;
120 nodeAfter
= m_shapeList
->Member(addAfter
);
122 if (!m_shapeList
->Member(object
))
126 if (nodeAfter
->Next())
127 m_shapeList
->Insert(nodeAfter
->Next(), object
);
129 m_shapeList
->Append(object
);
132 m_shapeList
->Append(object
);
133 object
->SetCanvas(GetCanvas());
137 void wxDiagram::InsertShape(wxShape
*object
)
139 m_shapeList
->Insert(object
);
140 object
->SetCanvas(GetCanvas());
143 void wxDiagram::RemoveShape(wxShape
*object
)
145 m_shapeList
->DeleteObject(object
);
148 // Should this delete the actual objects too? I think not.
149 void wxDiagram::RemoveAllShapes()
151 m_shapeList
->Clear();
154 void wxDiagram::DeleteAllShapes()
156 wxNode
*node
= m_shapeList
->First();
159 wxShape
*shape
= (wxShape
*)node
->Data();
160 if (!shape
->GetParent())
164 node
= m_shapeList
->First();
171 void wxDiagram::ShowAll(bool show
)
173 wxNode
*current
= m_shapeList
->First();
177 wxShape
*object
= (wxShape
*)current
->Data();
180 current
= current
->Next();
184 void wxDiagram::DrawOutline(wxDC
& dc
, double x1
, double y1
, double x2
, double y2
)
186 wxPen
dottedPen(wxColour(0, 0, 0), 1, wxDOT
);
187 dc
.SetPen(dottedPen
);
188 dc
.SetBrush((* wxTRANSPARENT_BRUSH
));
206 dc
.DrawLines(5, points
);
209 // Make sure all text that should be centred, is centred.
210 void wxDiagram::RecentreAll(wxDC
& dc
)
212 wxNode
*object_node
= m_shapeList
->First();
215 wxShape
*obj
= (wxShape
*)object_node
->Data();
217 object_node
= object_node
->Next();
223 bool wxDiagram::SaveFile(const wxString
& filename
)
227 wxExprDatabase
*database
= new wxExprDatabase
;
229 // First write the diagram type
230 wxExpr
*header
= new wxExpr("diagram");
231 OnHeaderSave(*database
, *header
);
233 database
->Append(header
);
235 wxNode
*node
= m_shapeList
->First();
238 wxShape
*shape
= (wxShape
*)node
->Data();
240 if (!shape
->IsKindOf(CLASSINFO(wxControlPoint
)))
243 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
244 expr
= new wxExpr("line");
246 expr
= new wxExpr("shape");
248 OnShapeSave(*database
, *shape
, *expr
);
252 OnDatabaseSave(*database
);
255 wxGetTempFileName("diag", tempFile
);
256 ofstream
stream(tempFile
);
264 database
->Write(stream
);
270 if (FileExists(filename))
274 sprintf(buf, "%s.bak", filename);
277 sprintf(buf, "_diagram.bak");
279 if (FileExists(buf)) wxRemoveFile(buf);
280 if (!wxRenameFile(filename, buf))
282 wxCopyFile(filename, buf);
283 wxRemoveFile(filename);
288 // Copy the temporary file to the correct filename
289 if (!wxRenameFile(tempFile
, filename
))
291 wxCopyFile(tempFile
, filename
);
292 wxRemoveFile(tempFile
);
299 bool wxDiagram::LoadFile(const wxString
& filename
)
303 wxExprDatabase
database(wxExprInteger
, "id");
304 if (!database
.Read(filename
))
312 database
.BeginFind();
313 wxExpr
*header
= database
.FindClauseByFunctor("diagram");
316 OnHeaderLoad(database
, *header
);
318 // Scan through all clauses and register the ids
319 wxNode
*node
= database
.First();
322 wxExpr
*clause
= (wxExpr
*)node
->Data();
324 clause
->GetAttributeValue("id", id
);
330 ReadContainerGeometry(database
);
333 OnDatabaseLoad(database
);
340 void wxDiagram::ReadNodes(wxExprDatabase
& database
)
342 // Find and create the node images
343 database
.BeginFind();
344 wxExpr
*clause
= database
.FindClauseByFunctor("shape");
350 clause
->AssignAttributeValue("type", &type
);
351 clause
->AssignAttributeValue("parent", &parentId
);
352 wxClassInfo
*classInfo
= wxClassInfo::FindClass(type
);
355 wxShape
*shape
= (wxShape
*)classInfo
->CreateObject();
356 OnShapeLoad(database
, *shape
, *clause
);
358 shape
->SetCanvas(GetCanvas());
361 m_shapeList
->Append(shape
);
363 // If child of composite, link up
366 wxExpr
*parentExpr
= database
.HashFind("shape", parentId
);
367 if (parentExpr
&& parentExpr
->GetClientData())
369 wxShape
*parent
= (wxShape
*)parentExpr
->GetClientData();
370 shape
->SetParent(parent
);
371 parent
->GetChildren().Append(shape
);
375 clause
->SetClientData(shape
);
380 clause
= database
.FindClauseByFunctor("shape");
385 void wxDiagram::ReadLines(wxExprDatabase
& database
)
387 database
.BeginFind();
388 wxExpr
*clause
= database
.FindClauseByFunctor("line");
394 clause
->GetAttributeValue("type", type
);
395 clause
->GetAttributeValue("parent", parentId
);
396 wxClassInfo
*classInfo
= wxClassInfo::FindClass((char*) (const char*) type
);
399 wxLineShape
*shape
= (wxLineShape
*)classInfo
->CreateObject();
402 OnShapeLoad(database
, *shape
, *clause
);
403 shape
->SetCanvas(GetCanvas());
405 long image_to
= -1; long image_from
= -1;
406 clause
->GetAttributeValue("to", image_to
);
407 clause
->GetAttributeValue("from", image_from
);
409 wxExpr
*image_to_expr
= database
.HashFind("shape", image_to
);
415 wxExpr
*image_from_expr
= database
.HashFind("shape", image_from
);
417 if (!image_from_expr
)
422 if (image_to_expr
&& image_from_expr
)
424 wxShape
*image_to_object
= (wxShape
*)image_to_expr
->GetClientData();
425 wxShape
*image_from_object
= (wxShape
*)image_from_expr
->GetClientData();
427 if (image_to_object
&& image_from_object
)
429 image_from_object
->AddLine(shape
, image_to_object
, shape
->GetAttachmentFrom(), shape
->GetAttachmentTo());
432 clause
->SetClientData(shape
);
434 m_shapeList
->Append(shape
);
437 clause
= database
.FindClauseByFunctor("line");
441 // Containers have divisions that reference adjoining divisions,
442 // so we need a separate pass to link everything up.
443 // Also used by Symbol Library.
444 void wxDiagram::ReadContainerGeometry(wxExprDatabase
& database
)
446 database
.BeginFind();
447 wxExpr
*clause
= database
.FindClauseByFunctor("shape");
450 wxShape
*image
= (wxShape
*)clause
->GetClientData();
451 if (image
&& image
->IsKindOf(CLASSINFO(wxCompositeShape
)))
453 wxCompositeShape
*composite
= (wxCompositeShape
*)image
;
454 wxExpr
*divisionExpr
= NULL
;
456 // Find the list of divisions in the composite
457 clause
->GetAttributeValue("divisions", &divisionExpr
);
461 wxExpr
*idExpr
= divisionExpr
->Nth(i
);
464 long divisionId
= idExpr
->IntegerValue();
465 wxExpr
*childExpr
= database
.HashFind("shape", divisionId
);
466 if (childExpr
&& childExpr
->GetClientData())
468 wxDivisionShape
*child
= (wxDivisionShape
*)childExpr
->GetClientData();
469 composite
->GetDivisions().Append(child
);
471 // Find the adjoining shapes
472 long leftSideId
= -1;
474 long rightSideId
= -1;
475 long bottomSideId
= -1;
476 childExpr
->GetAttributeValue("left_side", leftSideId
);
477 childExpr
->GetAttributeValue("top_side", topSideId
);
478 childExpr
->GetAttributeValue("right_side", rightSideId
);
479 childExpr
->GetAttributeValue("bottom_side", bottomSideId
);
482 wxExpr
*leftExpr
= database
.HashFind("shape", leftSideId
);
483 if (leftExpr
&& leftExpr
->GetClientData())
485 wxDivisionShape
*leftSide
= (wxDivisionShape
*)leftExpr
->GetClientData();
486 child
->SetLeftSide(leftSide
);
491 wxExpr
*topExpr
= database
.HashFind("shape", topSideId
);
492 if (topExpr
&& topExpr
->GetClientData())
494 wxDivisionShape
*topSide
= (wxDivisionShape
*)topExpr
->GetClientData();
495 child
->SetTopSide(topSide
);
498 if (rightSideId
> -1)
500 wxExpr
*rightExpr
= database
.HashFind("shape", rightSideId
);
501 if (rightExpr
&& rightExpr
->GetClientData())
503 wxDivisionShape
*rightSide
= (wxDivisionShape
*)rightExpr
->GetClientData();
504 child
->SetRightSide(rightSide
);
507 if (bottomSideId
> -1)
509 wxExpr
*bottomExpr
= database
.HashFind("shape", bottomSideId
);
510 if (bottomExpr
&& bottomExpr
->GetClientData())
512 wxDivisionShape
*bottomSide
= (wxDivisionShape
*)bottomExpr
->GetClientData();
513 child
->SetBottomSide(bottomSide
);
518 idExpr
= divisionExpr
->Nth(i
);
523 clause
= database
.FindClauseByFunctor("shape");
527 // Allow for modifying file
528 bool wxDiagram::OnDatabaseLoad(wxExprDatabase
& db
)
533 bool wxDiagram::OnDatabaseSave(wxExprDatabase
& db
)
538 bool wxDiagram::OnShapeSave(wxExprDatabase
& db
, wxShape
& shape
, wxExpr
& expr
)
540 shape
.WriteAttributes(&expr
);
543 if (shape
.IsKindOf(CLASSINFO(wxCompositeShape
)))
545 wxNode
*node
= shape
.GetChildren().First();
548 wxShape
*childShape
= (wxShape
*)node
->Data();
549 wxExpr
*childExpr
= new wxExpr("shape");
550 OnShapeSave(db
, *childShape
, *childExpr
);
558 bool wxDiagram::OnShapeLoad(wxExprDatabase
& db
, wxShape
& shape
, wxExpr
& expr
)
560 shape
.ReadAttributes(&expr
);
564 bool wxDiagram::OnHeaderSave(wxExprDatabase
& db
, wxExpr
& expr
)
569 bool wxDiagram::OnHeaderLoad(wxExprDatabase
& db
, wxExpr
& expr
)
576 void wxDiagram::SetCanvas(wxShapeCanvas
*can
)
578 m_diagramCanvas
= can
;
581 // Find a shape by its id
582 wxShape
* wxDiagram::FindShape(long id
) const
584 wxNode
* node
= GetShapeList()->First();
587 wxShape
* shape
= (wxShape
*) node
->Data();
588 if (shape
->GetId() == id
)