📄 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 file
bool 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;
}
#endif
void wxDiagram::SetCanvas(wxShapeCanvas *can)
{
m_diagramCanvas = can;
}
// Find a shape by its id
wxShape* 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 classes
wxLineCrossings::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 + -