📄 composit.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// 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 + -