📄 composit.cpp
字号:
newDivision->SetBottomSide((wxDivisionShape *)bottomNode->GetData());
}
node = node->GetNext();
}
}
wxOGLConstraint *wxCompositeShape::AddConstraint(wxOGLConstraint *constraint)
{
m_constraints.Append(constraint);
if (constraint->m_constraintId == 0)
constraint->m_constraintId = wxNewId();
return constraint;
}
wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxList& constrained)
{
wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, constrained);
if (constraint->m_constraintId == 0)
constraint->m_constraintId = wxNewId();
m_constraints.Append(constraint);
return constraint;
}
wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxShape *constrained)
{
wxList l;
l.Append(constrained);
wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, l);
if (constraint->m_constraintId == 0)
constraint->m_constraintId = wxNewId();
m_constraints.Append(constraint);
return constraint;
}
wxOGLConstraint *wxCompositeShape::FindConstraint(long cId, wxCompositeShape **actualComposite)
{
wxNode *node = m_constraints.GetFirst();
while (node)
{
wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
if (constraint->m_constraintId == cId)
{
if (actualComposite)
*actualComposite = this;
return constraint;
}
node = node->GetNext();
}
// If not found, try children.
node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
{
wxOGLConstraint *constraint = ((wxCompositeShape *)child)->FindConstraint(cId, actualComposite);
if (constraint)
{
if (actualComposite)
*actualComposite = (wxCompositeShape *)child;
return constraint;
}
}
node = node->GetNext();
}
return NULL;
}
void wxCompositeShape::DeleteConstraint(wxOGLConstraint *constraint)
{
m_constraints.DeleteObject(constraint);
delete constraint;
}
void wxCompositeShape::CalculateSize()
{
double maxX = (double) -999999.9;
double maxY = (double) -999999.9;
double minX = (double) 999999.9;
double minY = (double) 999999.9;
double w, h;
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *object = (wxShape *)node->GetData();
// Recalculate size of composite objects because may not conform
// to size it was set to - depends on the children.
object->CalculateSize();
object->GetBoundingBoxMax(&w, &h);
if ((object->GetX() + (w/2.0)) > maxX)
maxX = (double)(object->GetX() + (w/2.0));
if ((object->GetX() - (w/2.0)) < minX)
minX = (double)(object->GetX() - (w/2.0));
if ((object->GetY() + (h/2.0)) > maxY)
maxY = (double)(object->GetY() + (h/2.0));
if ((object->GetY() - (h/2.0)) < minY)
minY = (double)(object->GetY() - (h/2.0));
node = node->GetNext();
}
m_width = maxX - minX;
m_height = maxY - minY;
m_xpos = (double)(m_width/2.0 + minX);
m_ypos = (double)(m_height/2.0 + minY);
}
bool wxCompositeShape::Recompute()
{
int noIterations = 0;
bool changed = true;
while (changed && (noIterations < 500))
{
changed = Constrain();
noIterations ++;
}
/*
#ifdef wx_x
if (changed)
cerr << "Warning: constraint algorithm failed after 500 iterations.\n";
#endif
*/
return (!changed);
}
bool wxCompositeShape::Constrain()
{
CalculateSize();
bool changed = false;
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *object = (wxShape *)node->GetData();
if (object->Constrain())
changed = true;
node = node->GetNext();
}
node = m_constraints.GetFirst();
while (node)
{
wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
if (constraint->Evaluate()) changed = true;
node = node->GetNext();
}
return changed;
}
#if wxUSE_PROLOGIO
void wxCompositeShape::WriteAttributes(wxExpr *clause)
{
wxRectangleShape::WriteAttributes(clause);
// clause->AddAttributeValue("selectable", (long)selectable);
// Output constraints as constraint1 = (...), constraint2 = (...), etc.
int constraintNo = 1;
wxChar m_constraintNameBuf[20];
wxNode *node = m_constraints.GetFirst();
while (node)
{
wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
wxSprintf(m_constraintNameBuf, _T("constraint%d"), constraintNo);
// Each constraint is stored in the form
// (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
wxExpr *constraintExpr = new wxExpr(wxExprList);
constraintExpr->Append(new wxExpr((long)constraint->m_constraintType));
constraintExpr->Append(new wxExpr(wxExprString, constraint->m_constraintName));
constraintExpr->Append(new wxExpr(constraint->m_constraintId));
constraintExpr->Append(new wxExpr(constraint->m_xSpacing));
constraintExpr->Append(new wxExpr(constraint->m_ySpacing));
constraintExpr->Append(new wxExpr(constraint->m_constrainingObject->GetId()));
wxExpr *objectList = new wxExpr(wxExprList);
wxNode *node1 = constraint->m_constrainedObjects.GetFirst();
while (node1)
{
wxShape *obj = (wxShape *)node1->GetData();
objectList->Append(new wxExpr(obj->GetId()));
node1 = node1->GetNext();
}
constraintExpr->Append(objectList);
clause->AddAttributeValue(m_constraintNameBuf, constraintExpr);
node = node->GetNext();
constraintNo ++;
}
// Write the ids of all the child images
wxExpr *childrenExpr = new wxExpr(wxExprList);
node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
childrenExpr->Append(new wxExpr(child->GetId()));
node = node->GetNext();
}
clause->AddAttributeValue(_T("children"), childrenExpr);
// Write the ids of all the division images
if (m_divisions.GetCount() > 0)
{
wxExpr *divisionsExpr = new wxExpr(wxExprList);
node = m_divisions.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
divisionsExpr->Append(new wxExpr(child->GetId()));
node = node->GetNext();
}
clause->AddAttributeValue(_T("divisions"), divisionsExpr);
}
}
// Problem. Child images are always written AFTER the parent
// so as to be able to link up to parent. So we may not be able
// to find the constraint participants until we've read everything
// in. Need to have another pass for composites.
void wxCompositeShape::ReadAttributes(wxExpr *clause)
{
wxRectangleShape::ReadAttributes(clause);
// clause->GetAttributeValue("selectable", selectable);
}
void wxCompositeShape::ReadConstraints(wxExpr *clause, wxExprDatabase *database)
{
// Constraints are output as constraint1 = (...), constraint2 = (...), etc.
int constraintNo = 1;
wxChar m_constraintNameBuf[20];
bool haveConstraints = true;
while (haveConstraints)
{
wxSprintf(m_constraintNameBuf, _T("constraint%d"), constraintNo);
wxExpr *constraintExpr = NULL;
clause->GetAttributeValue(m_constraintNameBuf, &constraintExpr);
if (!constraintExpr)
{
haveConstraints = false;
break;
}
wxString cName = wxEmptyString;
wxShape *m_constrainingObject = NULL;
wxList m_constrainedObjects;
// Each constraint is stored in the form
// (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
wxExpr *typeExpr = constraintExpr->Nth(0);
wxExpr *nameExpr = constraintExpr->Nth(1);
wxExpr *idExpr = constraintExpr->Nth(2);
wxExpr *xExpr = constraintExpr->Nth(3);
wxExpr *yExpr = constraintExpr->Nth(4);
wxExpr *constrainingExpr = constraintExpr->Nth(5);
wxExpr *constrainedExpr = constraintExpr->Nth(6);
int cType = (int)typeExpr->IntegerValue();
double cXSpacing = xExpr->RealValue();
double cYSpacing = yExpr->RealValue();
cName = nameExpr->StringValue();
long cId = idExpr->IntegerValue();
wxExpr *objExpr1 = database->HashFind(_T("node_image"), constrainingExpr->IntegerValue());
if (objExpr1 && objExpr1->GetClientData())
m_constrainingObject = (wxShape *)objExpr1->GetClientData();
else
wxLogFatalError(wxT("Object graphics error: Couldn't find constraining image of composite."));
int i = 0;
wxExpr *currentIdExpr = constrainedExpr->Nth(i);
while (currentIdExpr)
{
long currentId = currentIdExpr->IntegerValue();
wxExpr *objExpr2 = database->HashFind(_T("node_image"), currentId);
if (objExpr2 && objExpr2->GetClientData())
{
m_constrainedObjects.Append((wxShape *)objExpr2->GetClientData());
}
else
{
wxLogFatalError(wxT("Object graphics error: Couldn't find constrained image of composite."));
}
i ++;
currentIdExpr = constrainedExpr->Nth(i);
}
wxOGLConstraint *newConstraint = AddConstraint(cType, m_constrainingObject, m_constrainedObjects);
newConstraint->SetSpacing(cXSpacing, cYSpacing);
newConstraint->m_constraintId = cId;
newConstraint->m_constraintName = cName;
constraintNo ++;
}
}
#endif
// Make this composite into a container by creating one wxDivisionShape
void wxCompositeShape::MakeContainer()
{
wxDivisionShape *division = OnCreateDivision();
m_divisions.Append(division);
AddChild(division);
division->SetSize(m_width, m_height);
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
division->Move(dc, GetX(), GetY());
Recompute();
division->Show(true);
}
wxDivisionShape *wxCompositeShape::OnCreateDivision()
{
return new wxDivisionShape;
}
wxShape *wxCompositeShape::FindContainerImage()
{
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
if (!m_divisions.Member(child))
return child;
node = node->GetNext();
}
return NULL;
}
// Returns true if division is a descendant of this container
bool wxCompositeShape::ContainsDivision(wxDivisionShape *division)
{
if (m_divisions.Member(division))
return true;
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
{
bool ans = ((wxCompositeShape *)child)->ContainsDivision(division);
if (ans)
return true;
}
node = node->GetNext();
}
return false;
}
/*
* Division object
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxDivisionShape, wxCompositeShape)
wxDivisionShape::wxDivisionShape()
{
SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT);
SetCentreResize(false);
SetAttachmentMode(true);
m_leftSide = NULL;
m_rightSide = NULL;
m_topSide = NULL;
m_bottomSide = NULL;
m_handleSide = DIVISION_SIDE_NONE;
m_leftSidePen = wxBLACK_PEN;
m_topSidePen = wxBLACK_PEN;
m_leftSideColour = wxT("BLACK");
m_topSideColour = wxT("BLACK");
m_leftSideStyle = wxT("Solid");
m_topSideStyle = wxT("Solid");
ClearRegions();
}
wxDivisionShape::~wxDivisionShape()
{
}
void wxDivisionShape::OnDraw(wxDC& dc)
{
dc.SetBrush(* wxTRANSPARENT_BRUSH);
dc.SetBackgroundMode(wxTRANSPARENT);
double x1 = (double)(GetX() - (GetWidth()/2.0));
double y1 = (double)(GetY() - (GetHeight()/2.0));
double x2 = (double)(GetX() + (GetWidth()/2.0));
double y2 = (double)(GetY() + (GetHeight()/2.0));
// Should subtract 1 pixel if drawing under Windows
#ifdef __WXMSW__
y2 -= (double)1.0;
#endif
if (m_leftSide)
{
dc.SetPen(* m_leftSidePen);
dc.DrawLine(WXROUND(x1), WXROUND(y2), WXROUND(x1), WXROUND(y1));
}
if (m_topSide)
{
dc.SetPen(* m_topSidePen);
dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y1));
}
// For testing purposes, draw a rectangle so we know
// how big the division is.
// SetBrush(* wxCYAN_BRUSH);
// wxRectangleShape::OnDraw(dc);
}
void wxDivisionShape::OnDrawContents(wxDC& dc)
{
wxCompositeShape::OnDrawContents(dc);
}
bool wxDivisionShape::OnMovePre(wxDC& dc, double x, double y, double oldx, double oldy, bool display)
{
double diffX = x - oldx;
double diffY = y - oldy;
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *object = (wxShape *)node->GetData();
object->Erase(dc);
object->Move(dc, object->GetX() + diffX, object->GetY() + diffY, display);
node = node->GetNext();
}
return true;
}
void wxDivisionShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -