⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 composit.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        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 + -