📄 ogldiag.cpp
字号:
void wxDiagram::ReadLines(wxExprDatabase& database){ database.BeginFind(); wxExpr *clause = database.FindClauseByFunctor(_T("line")); while (clause) { wxString type; long parentId = -1; clause->GetAttributeValue(_T("type"), type); clause->GetAttributeValue(_T("parent"), parentId); wxClassInfo *classInfo = wxClassInfo::FindClass(type); if (classInfo) { wxLineShape *shape = (wxLineShape *)classInfo->CreateObject(); shape->Show(true); OnShapeLoad(database, *shape, *clause); shape->SetCanvas(GetCanvas()); long image_to = -1; long image_from = -1; clause->GetAttributeValue(_T("to"), image_to); clause->GetAttributeValue(_T("from"), image_from); wxExpr *image_to_expr = database.HashFind(_T("shape"), image_to); if (!image_to_expr) { // Error } wxExpr *image_from_expr = database.HashFind(_T("shape"), image_from); if (!image_from_expr) { // Error } if (image_to_expr && image_from_expr) { wxShape *image_to_object = (wxShape *)image_to_expr->GetClientData(); wxShape *image_from_object = (wxShape *)image_from_expr->GetClientData(); if (image_to_object && image_from_object) { image_from_object->AddLine(shape, image_to_object, shape->GetAttachmentFrom(), shape->GetAttachmentTo()); } } clause->SetClientData(shape); m_shapeList->Append(shape); } clause = database.FindClauseByFunctor(_T("line")); }}// Containers have divisions that reference adjoining divisions,// so we need a separate pass to link everything up.// Also used by Symbol Library.void wxDiagram::ReadContainerGeometry(wxExprDatabase& database){ database.BeginFind(); wxExpr *clause = database.FindClauseByFunctor(_T("shape")); while (clause) { wxShape *image = (wxShape *)clause->GetClientData(); if (image && image->IsKindOf(CLASSINFO(wxCompositeShape))) { wxCompositeShape *composite = (wxCompositeShape *)image; wxExpr *divisionExpr = NULL; // Find the list of divisions in the composite clause->GetAttributeValue(_T("divisions"), &divisionExpr); if (divisionExpr) { int i = 0; wxExpr *idExpr = divisionExpr->Nth(i); while (idExpr) { long divisionId = idExpr->IntegerValue(); wxExpr *childExpr = database.HashFind(_T("shape"), divisionId); if (childExpr && childExpr->GetClientData()) { wxDivisionShape *child = (wxDivisionShape *)childExpr->GetClientData(); composite->GetDivisions().Append(child); // Find the adjoining shapes long leftSideId = -1; long topSideId = -1; long rightSideId = -1; long bottomSideId = -1; childExpr->GetAttributeValue(_T("left_side"), leftSideId); childExpr->GetAttributeValue(_T("top_side"), topSideId); childExpr->GetAttributeValue(_T("right_side"), rightSideId); childExpr->GetAttributeValue(_T("bottom_side"), bottomSideId); if (leftSideId > -1) { wxExpr *leftExpr = database.HashFind(_T("shape"), leftSideId); if (leftExpr && leftExpr->GetClientData()) { wxDivisionShape *leftSide = (wxDivisionShape *)leftExpr->GetClientData(); child->SetLeftSide(leftSide); } } if (topSideId > -1) { wxExpr *topExpr = database.HashFind(_T("shape"), topSideId); if (topExpr && topExpr->GetClientData()) { wxDivisionShape *topSide = (wxDivisionShape *)topExpr->GetClientData(); child->SetTopSide(topSide); } } if (rightSideId > -1) { wxExpr *rightExpr = database.HashFind(_T("shape"), rightSideId); if (rightExpr && rightExpr->GetClientData()) { wxDivisionShape *rightSide = (wxDivisionShape *)rightExpr->GetClientData(); child->SetRightSide(rightSide); } } if (bottomSideId > -1) { wxExpr *bottomExpr = database.HashFind(_T("shape"), bottomSideId); if (bottomExpr && bottomExpr->GetClientData()) { wxDivisionShape *bottomSide = (wxDivisionShape *)bottomExpr->GetClientData(); child->SetBottomSide(bottomSide); } } } i ++; idExpr = divisionExpr->Nth(i); } } } clause = database.FindClauseByFunctor(_T("shape")); }}// Allow for modifying filebool wxDiagram::OnDatabaseLoad(wxExprDatabase& WXUNUSED(db)){ return true;}bool wxDiagram::OnDatabaseSave(wxExprDatabase& WXUNUSED(db)){ return true;}bool wxDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr){ shape.WriteAttributes(&expr); db.Append(&expr); if (shape.IsKindOf(CLASSINFO(wxCompositeShape))) { wxNode *node = shape.GetChildren().GetFirst(); while (node) { wxShape *childShape = (wxShape *)node->GetData(); wxExpr *childExpr = new wxExpr(_T("shape")); OnShapeSave(db, *childShape, *childExpr); node = node->GetNext(); } } return true;}bool wxDiagram::OnShapeLoad(wxExprDatabase& WXUNUSED(db), wxShape& shape, wxExpr& expr){ shape.ReadAttributes(&expr); return true;}bool wxDiagram::OnHeaderSave(wxExprDatabase& WXUNUSED(db), wxExpr& WXUNUSED(expr)){ return true;}bool wxDiagram::OnHeaderLoad(wxExprDatabase& WXUNUSED(db), wxExpr& WXUNUSED(expr)){ return true;}#endifvoid wxDiagram::SetCanvas(wxShapeCanvas *can){ m_diagramCanvas = can;}// Find a shape by its idwxShape* wxDiagram::FindShape(long id) const{ wxNode* node = GetShapeList()->GetFirst(); while (node) { wxShape* shape = (wxShape*) node->GetData(); if (shape->GetId() == id) return shape; node = node->GetNext(); } return NULL;}//// Crossings classeswxLineCrossings::wxLineCrossings(){}wxLineCrossings::~wxLineCrossings(){ ClearCrossings();}void wxLineCrossings::FindCrossings(wxDiagram& diagram){ ClearCrossings(); wxNode* node1 = diagram.GetShapeList()->GetFirst(); while (node1) { wxShape* shape1 = (wxShape*) node1->GetData(); if (shape1->IsKindOf(CLASSINFO(wxLineShape))) { wxLineShape* lineShape1 = (wxLineShape*) shape1; // Iterate through the segments wxList* pts1 = lineShape1->GetLineControlPoints(); size_t i; for (i = 0; i < (pts1->GetCount() - 1); i++) { wxRealPoint* pt1_a = (wxRealPoint*) (pts1->Item(i)->GetData()); wxRealPoint* pt1_b = (wxRealPoint*) (pts1->Item(i+1)->GetData()); // Now we iterate through the segments again wxNode* node2 = diagram.GetShapeList()->GetFirst(); while (node2) { wxShape* shape2 = (wxShape*) node2->GetData(); // 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 < (int) (pts2->GetCount() - 1); j++) { wxRealPoint* pt2_a = (wxRealPoint*) (pts2->Item(j)->GetData()); wxRealPoint* pt2_b = (wxRealPoint*) (pts2->Item(j+1)->GetData()); // 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->GetNext(); } } } node1 = node1->GetNext(); }}void wxLineCrossings::DrawCrossings(wxDiagram& WXUNUSED(diagram), wxDC& dc){ dc.SetBrush(*wxTRANSPARENT_BRUSH); long arcWidth = 8; wxNode* node = m_crossings.GetFirst(); while (node) { wxLineCrossing* crossing = (wxLineCrossing*) node->GetData();// 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->GetNext(); }}void wxLineCrossings::ClearCrossings(){ wxNode* node = m_crossings.GetFirst(); while (node) { wxLineCrossing* crossing = (wxLineCrossing*) node->GetData(); delete crossing; node = node->GetNext(); } m_crossings.Clear();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -