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

📄 composit.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        composit.cpp
// Purpose:     Composite OGL class
// Author:      Julian Smart
// Modified by:
// Created:     12/07/98
// RCS-ID:      $Id: composit.cpp,v 1.17 2005/10/06 18:17:21 ABX Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#if wxUSE_PROLOGIO
#include "wx/deprecated/wxexpr.h"
#endif

#include "wx/ogl/ogl.h"


#if wxUSE_PROLOGIO
// Sometimes, objects need to access the whole database to
// construct themselves.
wxExprDatabase *GlobalwxExprDatabase = NULL;
#endif

/*
 * Division control point
 */

class wxDivisionControlPoint: public wxControlPoint
{
 DECLARE_DYNAMIC_CLASS(wxDivisionControlPoint)
 public:
  wxDivisionControlPoint() {}
  wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type);
  ~wxDivisionControlPoint();

  void OnDragLeft(bool draw, double x, double y, int keys=0, int attachment = 0);
  void OnBeginDragLeft(double x, double y, int keys=0, int attachment = 0);
  void OnEndDragLeft(double x, double y, int keys=0, int attachment = 0);
};

IMPLEMENT_DYNAMIC_CLASS(wxDivisionControlPoint, wxControlPoint)

/*
 * Composite object
 *
 */

IMPLEMENT_DYNAMIC_CLASS(wxCompositeShape, wxRectangleShape)

wxCompositeShape::wxCompositeShape(): wxRectangleShape(10.0, 10.0)
{
//  selectable = false;
  m_oldX = m_xpos;
  m_oldY = m_ypos;
}

wxCompositeShape::~wxCompositeShape()
{
  wxNode *node = m_constraints.GetFirst();
  while (node)
  {
    wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
    delete constraint;
    node = node->GetNext();
  }
  node = m_children.GetFirst();
  while (node)
  {
    wxShape *object = (wxShape *)node->GetData();
    wxNode *next = node->GetNext();
    object->Unlink();
    delete object;
    node = next;
  }
}

void wxCompositeShape::OnDraw(wxDC& dc)
{
  double x1 = (double)(m_xpos - m_width/2.0);
  double y1 = (double)(m_ypos - m_height/2.0);

  if (m_shadowMode != SHADOW_NONE)
  {
    if (m_shadowBrush)
      dc.SetBrush(* m_shadowBrush);
    dc.SetPen(* g_oglTransparentPen);

    if (m_cornerRadius != 0.0)
      dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY),
                               WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
    else
      dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height));
  }
}

void wxCompositeShape::OnDrawContents(wxDC& dc)
{
  wxNode *node = m_children.GetFirst();
  while (node)
  {
    wxShape *object = (wxShape *)node->GetData();
    object->Draw(dc);
    object->DrawLinks(dc);
    node = node->GetNext();
  }
  wxShape::OnDrawContents(dc);
}

bool wxCompositeShape::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 wxCompositeShape::OnErase(wxDC& dc)
{
  wxRectangleShape::OnErase(dc);
  wxNode *node = m_children.GetFirst();
  while (node)
  {
    wxShape *object = (wxShape *)node->GetData();
    object->Erase(dc);
    node = node->GetNext();
  }
}

static double objectStartX = 0.0;
static double objectStartY = 0.0;

void wxCompositeShape::OnDragLeft(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
{
  double xx = x;
  double yy = y;
  m_canvas->Snap(&xx, &yy);
  double offsetX = xx - objectStartX;
  double offsetY = yy - objectStartY;

  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  dc.SetLogicalFunction(OGLRBLF);
  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetPen(dottedPen);
  dc.SetBrush((* wxTRANSPARENT_BRUSH));

  GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());
//  wxShape::OnDragLeft(draw, x, y, keys, attachment);
}

void wxCompositeShape::OnBeginDragLeft(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
{
  objectStartX = x;
  objectStartY = y;

  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  Erase(dc);

  dc.SetLogicalFunction(OGLRBLF);

  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetPen(dottedPen);
  dc.SetBrush((* wxTRANSPARENT_BRUSH));
  m_canvas->CaptureMouse();

  double xx = x;
  double yy = y;
  m_canvas->Snap(&xx, &yy);
  double offsetX = xx - objectStartX;
  double offsetY = yy - objectStartY;

  GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());

//  wxShape::OnBeginDragLeft(x, y, keys, attachment);
}

void wxCompositeShape::OnEndDragLeft(double x, double y, int keys, int WXUNUSED(attachment))
{
//  wxShape::OnEndDragLeft(x, y, keys, attachment);

  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  m_canvas->ReleaseMouse();

  if (!m_draggable)
  {
    if (m_parent) m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, 0);
    return;
  }

  dc.SetLogicalFunction(wxCOPY);
  double xx = x;
  double yy = y;
  m_canvas->Snap(&xx, &yy);
  double offsetX = xx - objectStartX;
  double offsetY = yy - objectStartY;

  Move(dc, GetX() + offsetX, GetY() + offsetY);

  if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
}

void wxCompositeShape::OnRightClick(double x, double y, int keys, int WXUNUSED(attachment))
{
  // If we get a ctrl-right click, this means send the message to
  // the division, so we can invoke a user interface for dealing with regions.
  if (keys & KEY_CTRL)
  {
    wxNode *node = m_divisions.GetFirst();
    while (node)
    {
      wxDivisionShape *division = (wxDivisionShape *)node->GetData();
      wxNode *next = node->GetNext();
      int attach = 0;
      double dist = 0.0;
      if (division->HitTest(x, y, &attach, &dist))
      {
        division->GetEventHandler()->OnRightClick(x, y, keys, attach);
        node = NULL;
      }
      if (node)
        node = next;
    }
  }
}

void wxCompositeShape::SetSize(double w, double h, bool recursive)
{
  SetAttachmentSize(w, h);

  double xScale = (double)(w/(wxMax(1.0, GetWidth())));
  double yScale = (double)(h/(wxMax(1.0, GetHeight())));

  m_width = w;
  m_height = h;

  if (!recursive) return;

  wxNode *node = m_children.GetFirst();

  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  double xBound, yBound;
  while (node)
  {
    wxShape *object = (wxShape *)node->GetData();

    // Scale the position first
    double newX = (double)(((object->GetX() - GetX())*xScale) + GetX());
    double newY = (double)(((object->GetY() - GetY())*yScale) + GetY());
    object->Show(false);
    object->Move(dc, newX, newY);
    object->Show(true);

    // Now set the scaled size
    object->GetBoundingBoxMin(&xBound, &yBound);
    object->SetSize(object->GetFixedWidth() ? xBound : xScale*xBound,
                    object->GetFixedHeight() ? yBound : yScale*yBound);

    node = node->GetNext();
  }
  SetDefaultRegionSize();
}

void wxCompositeShape::AddChild(wxShape *child, wxShape *addAfter)
{
  m_children.Append(child);
  child->SetParent(this);
  if (m_canvas)
  {
    // Ensure we add at the right position
    if (addAfter)
      child->RemoveFromCanvas(m_canvas);
    child->AddToCanvas(m_canvas, addAfter);
  }
}

void wxCompositeShape::RemoveChild(wxShape *child)
{
  m_children.DeleteObject(child);
  m_divisions.DeleteObject(child);
  RemoveChildFromConstraints(child);
  child->SetParent(NULL);
}

void wxCompositeShape::DeleteConstraintsInvolvingChild(wxShape *child)
{
  wxNode *node = m_constraints.GetFirst();
  while (node)
  {
    wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
    wxNode *nextNode = node->GetNext();

    if ((constraint->m_constrainingObject == child) ||
        constraint->m_constrainedObjects.Member(child))
    {
      delete constraint;
      delete node;
    }
    node = nextNode;
  }
}

void wxCompositeShape::RemoveChildFromConstraints(wxShape *child)
{
  wxNode *node = m_constraints.GetFirst();
  while (node)
  {
    wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
    wxNode *nextNode = node->GetNext();

    if (constraint->m_constrainedObjects.Member(child))
      constraint->m_constrainedObjects.DeleteObject(child);
    if (constraint->m_constrainingObject == child)
      constraint->m_constrainingObject = NULL;

    // Delete the constraint if no participants left
    if (!constraint->m_constrainingObject)
    {
      delete constraint;
      delete node;
    }

    node = nextNode;
  }
}

void wxCompositeShape::Copy(wxShape& copy)
{
  wxRectangleShape::Copy(copy);

  wxASSERT( copy.IsKindOf(CLASSINFO(wxCompositeShape)) ) ;

  wxCompositeShape& compositeCopy = (wxCompositeShape&) copy;

  // Associate old and new copies for compositeCopying constraints and division geometry
  oglObjectCopyMapping.Append((long)this, &compositeCopy);

  // Copy the children
  wxNode *node = m_children.GetFirst();
  while (node)
  {
    wxShape *object = (wxShape *)node->GetData();
    wxShape *newObject = object->CreateNewCopy(false, false);
    if (newObject->GetId() == 0)
      newObject->SetId(wxNewId());

    newObject->SetParent(&compositeCopy);
    compositeCopy.m_children.Append(newObject);

    // Some m_children may be divisions
    if (m_divisions.Member(object))
      compositeCopy.m_divisions.Append(newObject);

    oglObjectCopyMapping.Append((long)object, newObject);

    node = node->GetNext();
  }

  // Copy the constraints
  node = m_constraints.GetFirst();
  while (node)
  {
    wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();

    wxShape *newConstraining = (wxShape *)(oglObjectCopyMapping.Find((long)constraint->m_constrainingObject)->GetData());

    wxList newConstrainedList;
    wxNode *node2 = constraint->m_constrainedObjects.GetFirst();
    while (node2)
    {
      wxShape *constrainedObject = (wxShape *)node2->GetData();
      wxShape *newConstrained = (wxShape *)(oglObjectCopyMapping.Find((long)constrainedObject)->GetData());
      newConstrainedList.Append(newConstrained);
      node2 = node2->GetNext();
    }

    wxOGLConstraint *newConstraint = new wxOGLConstraint(constraint->m_constraintType, newConstraining,
                                            newConstrainedList);
    newConstraint->m_constraintId = constraint->m_constraintId;
    if (constraint->m_constraintName)
    {
      newConstraint->m_constraintName = constraint->m_constraintName;
    }
    newConstraint->SetSpacing(constraint->m_xSpacing, constraint->m_ySpacing);
    compositeCopy.m_constraints.Append(newConstraint);

    node = node->GetNext();
  }

  // Now compositeCopy the division geometry
  node = m_divisions.GetFirst();
  while (node)
  {
    wxDivisionShape *division = (wxDivisionShape *)node->GetData();
    wxNode *node1 = oglObjectCopyMapping.Find((long)division);
    wxNode *leftNode = NULL;
    wxNode *topNode = NULL;
    wxNode *rightNode = NULL;
    wxNode *bottomNode = NULL;
    if (division->GetLeftSide())
      leftNode = oglObjectCopyMapping.Find((long)division->GetLeftSide());
    if (division->GetTopSide())
      topNode = oglObjectCopyMapping.Find((long)division->GetTopSide());
    if (division->GetRightSide())
      rightNode = oglObjectCopyMapping.Find((long)division->GetRightSide());
    if (division->GetBottomSide())
      bottomNode = oglObjectCopyMapping.Find((long)division->GetBottomSide());
    if (node1)
    {
      wxDivisionShape *newDivision = (wxDivisionShape *)node1->GetData();
      if (leftNode)
        newDivision->SetLeftSide((wxDivisionShape *)leftNode->GetData());
      if (topNode)
        newDivision->SetTopSide((wxDivisionShape *)topNode->GetData());
      if (rightNode)
        newDivision->SetRightSide((wxDivisionShape *)rightNode->GetData());
      if (bottomNode)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -