mirror of
http://172.16.200.102/MOISE/Timed-Altarica-To-Fiacre-Translator.git
synced 2026-04-20 15:07:41 +02:00
Initial commit.
This commit is contained in:
827
sdk/wxshapeframework/src/DiagramManager.cpp
Normal file
827
sdk/wxshapeframework/src/DiagramManager.cpp
Normal file
@@ -0,0 +1,827 @@
|
||||
/***************************************************************
|
||||
* Name: DiagramManager.cpp
|
||||
* Purpose: Implements shape manager class
|
||||
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
|
||||
* Created: 2007-07-25
|
||||
* Copyright: Michal Bližňák
|
||||
* License: wxWidgets license (www.wxwidgets.org)
|
||||
* Notes:
|
||||
**************************************************************/
|
||||
|
||||
#include "wx_pch.h"
|
||||
|
||||
#ifdef _DEBUG_MSVC
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/listimpl.cpp>
|
||||
|
||||
#include "wx/wxsf/DiagramManager.h"
|
||||
#include "wx/wxsf/ShapeCanvas.h"
|
||||
#include "wx/wxsf/ControlShape.h"
|
||||
#include "wx/wxsf/LineShape.h"
|
||||
#include "wx/wxsf/GridShape.h"
|
||||
|
||||
using namespace wxSFCommonFcn;
|
||||
|
||||
// TODO: implement autolayout
|
||||
// TODO: implement better line X ellipse check
|
||||
|
||||
WX_DEFINE_LIST(IDList);
|
||||
|
||||
XS_IMPLEMENT_CLONABLE_CLASS(wxSFDiagramManager, wxXmlSerializer);
|
||||
|
||||
wxSFDiagramManager::wxSFDiagramManager()
|
||||
{
|
||||
m_pShapeCanvas = NULL;
|
||||
m_lstIDPairs.DeleteContents(true);
|
||||
|
||||
m_sSFVersion = wxT("1.12.4 beta");
|
||||
|
||||
SetSerializerOwner(wxT("wxShapeFramework"));
|
||||
SetSerializerVersion(wxT("1.0"));
|
||||
SetSerializerRootName(wxT("chart"));
|
||||
}
|
||||
|
||||
wxSFDiagramManager::wxSFDiagramManager(const wxSFDiagramManager &obj)
|
||||
: wxXmlSerializer(obj)
|
||||
{
|
||||
m_pShapeCanvas = NULL;
|
||||
m_sSFVersion = obj.m_sSFVersion;
|
||||
|
||||
m_lstIDPairs.DeleteContents(true);
|
||||
}
|
||||
|
||||
wxSFDiagramManager::~wxSFDiagramManager()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
// Adding/removing shapes functions
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::AddShape(wxClassInfo* shapeInfo, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
wxPoint shapePos;
|
||||
|
||||
if(m_pShapeCanvas)
|
||||
{
|
||||
wxRect crect = m_pShapeCanvas->GetClientRect();
|
||||
shapePos = wxPoint((crect.GetRight() - crect.GetLeft())/2,
|
||||
(crect.GetBottom() - crect.GetTop())/2);
|
||||
}
|
||||
|
||||
wxSFShapeBase* pShape = AddShape(shapeInfo, shapePos, saveState, err);
|
||||
|
||||
return pShape;
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::AddShape(wxClassInfo* shapeInfo, const wxPoint& pos, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
wxASSERT( shapeInfo );
|
||||
|
||||
if( shapeInfo && IsShapeAccepted(shapeInfo->GetClassName()) )
|
||||
{
|
||||
// create shape object from class info
|
||||
wxSFShapeBase *pShape = (wxSFShapeBase*)shapeInfo->CreateObject();
|
||||
|
||||
wxSFShapeBase *pParentShape = NULL;
|
||||
// update given possition
|
||||
wxPoint lpos = pos;
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
lpos = m_pShapeCanvas->FitPositionToGrid( m_pShapeCanvas->DP2LP(pos) );
|
||||
}
|
||||
// line shapes can be assigned to root only
|
||||
if( !pShape->IsKindOf(CLASSINFO(wxSFLineShape)) ) pParentShape = GetShapeAtPosition(lpos);
|
||||
|
||||
if( pParentShape && pParentShape->IsChildAccepted(shapeInfo->GetClassName()) )
|
||||
{
|
||||
pShape = AddShape(pShape, (xsSerializable*)pParentShape, pos - Conv2Point( pParentShape->GetAbsolutePosition() ), sfINITIALIZE, saveState, err);
|
||||
}
|
||||
else
|
||||
pShape = AddShape(pShape, GetRootItem(), pos, sfINITIALIZE, saveState, err);
|
||||
|
||||
|
||||
if( pParentShape )pParentShape->Update();
|
||||
|
||||
return pShape;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( err ) *err = wxSF::errNOT_ACCEPTED;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::AddShape(wxSFShapeBase* shape, xsSerializable* parent, const wxPoint& pos, bool initialize, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
if(shape)
|
||||
{
|
||||
if( shape->IsKindOf(CLASSINFO(wxSFShapeBase)) && IsShapeAccepted(shape->GetClassInfo()->GetClassName()) )
|
||||
{
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
wxPoint newPos = m_pShapeCanvas->FitPositionToGrid(m_pShapeCanvas->DP2LP(pos));
|
||||
shape->SetRelativePosition( Conv2RealPoint(newPos) );
|
||||
}
|
||||
else
|
||||
shape->SetRelativePosition( Conv2RealPoint(pos) );
|
||||
|
||||
// add parent shape to the data manager (serializer)
|
||||
if(parent)
|
||||
{
|
||||
AddItem(parent, shape);
|
||||
}
|
||||
else
|
||||
AddItem(GetRootItem(), shape);
|
||||
|
||||
// initialize added shape
|
||||
if(initialize)
|
||||
{
|
||||
shape->CreateHandles();
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
shape->SetHoverColour(m_pShapeCanvas->GetHoverColour());
|
||||
}
|
||||
|
||||
if(HasChildren(shape))
|
||||
{
|
||||
wxSFShapeBase* pChild;
|
||||
ShapeList lstChildren;
|
||||
|
||||
// get shape's children (if exist)
|
||||
shape->GetChildShapes(sfANY, lstChildren, sfRECURSIVE);
|
||||
// initialize shape's children
|
||||
ShapeList::compatibility_iterator node = lstChildren.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pChild = (wxSFShapeBase*)node->GetData();
|
||||
|
||||
pChild->CreateHandles();
|
||||
pChild->Update();
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
pChild->SetHoverColour(m_pShapeCanvas->GetHoverColour());
|
||||
}
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset scale of assigned shape canvas (if exists and it is necessary...)
|
||||
if( m_pShapeCanvas && shape->IsKindOf( CLASSINFO(wxSFControlShape) ) )
|
||||
{
|
||||
m_pShapeCanvas->SetScale( 1 );
|
||||
}
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
if( saveState )
|
||||
{
|
||||
m_pShapeCanvas->SaveCanvasState();
|
||||
}
|
||||
}
|
||||
|
||||
if( err ) *err = wxSF::errOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
//wxMessageBox(wxString::Format(wxT("Unable to add '%s' class object to the canvas"), shape->GetClassInfo()->GetClassName()), wxT("ShapeFramework"), wxICON_WARNING);
|
||||
|
||||
delete shape;
|
||||
shape = NULL;
|
||||
|
||||
if( err ) *err = wxSF::errNOT_ACCEPTED;
|
||||
}
|
||||
}
|
||||
else if( err ) *err = wxSF::errINVALID_INPUT;
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
return CreateConnection(srcId, trgId, CLASSINFO(wxSFLineShape), saveState, err);
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, wxClassInfo *lineInfo, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
wxSFShapeBase* pShape = AddShape(lineInfo, sfDONT_SAVE_STATE, err);
|
||||
if(pShape)
|
||||
{
|
||||
wxSFLineShape *pLine = (wxSFLineShape*)pShape;
|
||||
pLine->SetSrcShapeId(srcId);
|
||||
pLine->SetTrgShapeId(trgId);
|
||||
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
if(saveState)m_pShapeCanvas->SaveCanvasState();
|
||||
pLine->Refresh();
|
||||
}
|
||||
}
|
||||
return pShape;
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, wxSFLineShape *line, bool saveState, wxSF::ERRCODE *err)
|
||||
{
|
||||
wxSFShapeBase* pShape = AddShape(line, NULL, wxDefaultPosition, sfINITIALIZE, sfDONT_SAVE_STATE, err);
|
||||
if(pShape)
|
||||
{
|
||||
wxSFLineShape *pLine = (wxSFLineShape*)pShape;
|
||||
pLine->SetSrcShapeId(srcId);
|
||||
pLine->SetTrgShapeId(trgId);
|
||||
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
if(saveState)m_pShapeCanvas->SaveCanvasState();
|
||||
pLine->Refresh();
|
||||
}
|
||||
}
|
||||
return pShape;
|
||||
}
|
||||
|
||||
|
||||
void wxSFDiagramManager::RemoveShape(wxSFShapeBase* shape, bool refresh)
|
||||
{
|
||||
if(shape)
|
||||
{
|
||||
wxSFShapeBase *pParent = shape->GetParentShape();
|
||||
|
||||
// remove connected lines (to all children)
|
||||
ShapeList lstChildren;
|
||||
ShapeList lstConnections;
|
||||
ShapeList lstRemovedConnections;
|
||||
|
||||
// get all shape's children
|
||||
shape->GetChildShapes(sfANY, lstChildren, sfRECURSIVE);
|
||||
lstChildren.Append(shape);
|
||||
|
||||
// retrieve all assigned lines
|
||||
ShapeList::compatibility_iterator snode = lstChildren.GetFirst();
|
||||
while(snode)
|
||||
{
|
||||
GetAssignedConnections(snode->GetData(), CLASSINFO(wxSFLineShape), wxSFShapeBase::lineBOTH, lstConnections);
|
||||
snode = snode->GetNext();
|
||||
}
|
||||
|
||||
// remove all assigne lines
|
||||
ShapeList::compatibility_iterator node = lstConnections.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
// one connection may be used by the parent and also by his child
|
||||
if(lstRemovedConnections.IndexOf(node->GetData()) == wxNOT_FOUND)
|
||||
{
|
||||
lstRemovedConnections.Append(node->GetData());
|
||||
RemoveShape(node->GetData(), false);
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
// remove the shape also from m_lstCurrentShapes list
|
||||
if( m_pShapeCanvas ) m_pShapeCanvas->RemoveFromTemporaries( shape );
|
||||
|
||||
// remove the shape
|
||||
RemoveItem(shape);
|
||||
|
||||
if( pParent ) pParent->Update();
|
||||
|
||||
if( refresh && m_pShapeCanvas ) m_pShapeCanvas->Refresh(false);
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::RemoveShapes(const ShapeList& selection)
|
||||
{
|
||||
wxSFShapeBase* pShape;
|
||||
ShapeList::compatibility_iterator node = selection.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = node->GetData();
|
||||
// it is important to check whether double-linked shapes already exist before
|
||||
// they are deleted
|
||||
if(Contains(pShape))RemoveShape(pShape, false);
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::Clear()
|
||||
{
|
||||
RemoveAll();
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
m_pShapeCanvas->GetMultiselectionBox().Show(false);
|
||||
m_pShapeCanvas->UpdateVirtualSize();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
// Serialization/deserialization functions
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
bool wxSFDiagramManager::SerializeToXml(const wxString& file, bool withroot)
|
||||
{
|
||||
return wxXmlSerializer::SerializeToXml(file, withroot);
|
||||
}
|
||||
|
||||
bool wxSFDiagramManager::SerializeToXml(wxOutputStream& outstream, bool withroot)
|
||||
{
|
||||
return wxXmlSerializer::SerializeToXml(outstream, withroot);
|
||||
}
|
||||
|
||||
bool wxSFDiagramManager::DeserializeFromXml(const wxString& file)
|
||||
{
|
||||
bool fSuccess = false;
|
||||
|
||||
wxFileInputStream instream(file);
|
||||
if(instream.IsOk())
|
||||
{
|
||||
if( m_pShapeCanvas) m_pShapeCanvas->ClearCanvasHistory();
|
||||
|
||||
fSuccess = DeserializeFromXml(instream);
|
||||
|
||||
if( m_pShapeCanvas) m_pShapeCanvas->SaveCanvasState();
|
||||
}
|
||||
else
|
||||
wxMessageBox(wxT("Unable to initialize input stream."), wxT("ShapeFramework"), wxOK | wxICON_ERROR);
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
bool wxSFDiagramManager::DeserializeFromXml(wxInputStream& instream)
|
||||
{
|
||||
// load an XML file
|
||||
try
|
||||
{
|
||||
wxXmlDocument xmlDoc;
|
||||
xmlDoc.Load(instream);
|
||||
|
||||
wxXmlNode* root = xmlDoc.GetRoot();
|
||||
if(root && (root->GetName() == wxT("chart")))
|
||||
{
|
||||
// read shape objects from XML recursively
|
||||
DeserializeObjects(NULL, root);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
wxMessageBox(wxT("Unknown file format."), wxT("ShapeFramework"), wxOK | wxICON_WARNING);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
wxMessageBox(wxT("Unable to load XML file."), wxT("ShapeFramework"), wxOK | wxICON_ERROR);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::DeserializeObjects(xsSerializable* parent, wxXmlNode* node)
|
||||
{
|
||||
_DeserializeObjects(parent, node);
|
||||
|
||||
// update IDs in connection lines and grids
|
||||
UpdateConnections();
|
||||
UpdateGrids();
|
||||
|
||||
m_lstIDPairs.Clear();
|
||||
|
||||
if( m_pShapeCanvas )
|
||||
{
|
||||
//m_pShapeCanvas->MoveShapesFromNegatives();
|
||||
m_pShapeCanvas->UpdateVirtualSize();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::_DeserializeObjects(xsSerializable* parent, wxXmlNode* node)
|
||||
{
|
||||
wxSFShapeBase *pShape;
|
||||
|
||||
wxXS::IntArray arrNewIDs;
|
||||
SerializableList lstForUpdate;
|
||||
|
||||
wxXmlNode* shapeNode = node->GetChildren();
|
||||
while(shapeNode)
|
||||
{
|
||||
if(shapeNode->GetName() == wxT("object"))
|
||||
{
|
||||
#if wxVERSION_NUMBER < 2900
|
||||
pShape = AddShape((wxSFShapeBase*)wxCreateDynamicObject(shapeNode->GetPropVal(wxT("type"), wxT(""))), parent, wxPoint(0, 0), true, sfDONT_SAVE_STATE);
|
||||
#else
|
||||
pShape = AddShape((wxSFShapeBase*)wxCreateDynamicObject(shapeNode->GetAttribute(wxT("type"), wxT(""))), parent, wxPoint(0, 0), true, sfDONT_SAVE_STATE);
|
||||
#endif
|
||||
if(pShape)
|
||||
{
|
||||
// store new assigned ID
|
||||
lstForUpdate.Append( pShape );
|
||||
pShape->GetChildrenRecursively( NULL, lstForUpdate );
|
||||
|
||||
for( SerializableList::iterator it = lstForUpdate.begin(); it != lstForUpdate.end(); ++it )
|
||||
{
|
||||
arrNewIDs.Add( (*it)->GetId() );
|
||||
}
|
||||
|
||||
// deserialize stored content
|
||||
pShape->DeserializeObject(shapeNode);
|
||||
|
||||
// update handle in line shapes
|
||||
if( pShape->IsKindOf( CLASSINFO(wxSFLineShape) ) )
|
||||
{
|
||||
pShape->CreateHandles();
|
||||
m_lstLinesForUpdate.Append(pShape);
|
||||
}
|
||||
else if( pShape->IsKindOf( CLASSINFO(wxSFGridShape) ) )
|
||||
{
|
||||
m_lstGridsForUpdate.Append(pShape);
|
||||
}
|
||||
|
||||
// store information about IDs' changes and re-assign shapes' IDs
|
||||
int newId, i = 0;
|
||||
for( SerializableList::iterator it = lstForUpdate.begin(); it != lstForUpdate.end(); ++it )
|
||||
{
|
||||
newId = arrNewIDs[i++];
|
||||
if( newId != (*it)->GetId() )
|
||||
{
|
||||
m_lstIDPairs.Append( new IDPair((*it)->GetId(), newId) );
|
||||
(*it)->SetId( newId );
|
||||
}
|
||||
}
|
||||
|
||||
// deserialize child objects
|
||||
_DeserializeObjects(pShape, shapeNode);
|
||||
|
||||
arrNewIDs.Clear();
|
||||
lstForUpdate.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are some unsupported shapes so the diagrams must be cleared because of possible damage
|
||||
RemoveAll();
|
||||
m_lstLinesForUpdate.Clear();
|
||||
m_lstGridsForUpdate.Clear();
|
||||
|
||||
wxMessageBox( wxT("Deserialization couldn't be completed because not of all shapes are accepted."), wxT("wxShapeFramework"), wxOK | wxICON_WARNING );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(shapeNode->GetName() == m_sRootName + wxT("_properties"))
|
||||
{
|
||||
m_pRoot->DeserializeObject(shapeNode->GetChildren());
|
||||
}
|
||||
shapeNode = shapeNode->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
// Shape handling functions
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
void wxSFDiagramManager::AcceptShape(const wxString& type)
|
||||
{
|
||||
if(m_arrAcceptedShapes.Index(type) == wxNOT_FOUND)
|
||||
{
|
||||
m_arrAcceptedShapes.Add(type);
|
||||
}
|
||||
}
|
||||
bool wxSFDiagramManager::IsShapeAccepted(const wxString& type)
|
||||
{
|
||||
if( m_arrAcceptedShapes.Index(type) != wxNOT_FOUND )return true;
|
||||
else if( m_arrAcceptedShapes.Index(wxT("All")) != wxNOT_FOUND )return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::GetAssignedConnections(wxSFShapeBase* parent, wxClassInfo* shapeInfo, wxSFShapeBase::CONNECTMODE mode, ShapeList& lines)
|
||||
{
|
||||
wxSFLineShape* pLine;
|
||||
|
||||
if( parent->GetId() == -1 ) return;
|
||||
|
||||
SerializableList lstLines;
|
||||
// lines are children of root item only so we have not to search recursively...
|
||||
GetRootItem()->GetChildren( shapeInfo, lstLines );
|
||||
|
||||
if( !lstLines.IsEmpty() )
|
||||
{
|
||||
SerializableList::compatibility_iterator node = lstLines.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pLine = (wxSFLineShape*)node->GetData();
|
||||
switch(mode)
|
||||
{
|
||||
case wxSFShapeBase::lineSTARTING:
|
||||
if( pLine->GetSrcShapeId() == parent->GetId() ) lines.Append(pLine);
|
||||
break;
|
||||
|
||||
case wxSFShapeBase::lineENDING:
|
||||
if( pLine->GetTrgShapeId() == parent->GetId() ) lines.Append(pLine);
|
||||
break;
|
||||
|
||||
case wxSFShapeBase::lineBOTH:
|
||||
if( ( pLine->GetSrcShapeId() == parent->GetId() ) ||
|
||||
( pLine->GetTrgShapeId() == parent->GetId() ) ) lines.Append(pLine);
|
||||
break;
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::GetShapes(wxClassInfo* shapeInfo, ShapeList& shapes, xsSerializable::SEARCHMODE mode)
|
||||
{
|
||||
GetItems(shapeInfo, (SerializableList&)shapes, mode);
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::GetShapeAtPosition(const wxPoint& pos, int zorder, SEARCHMODE mode)
|
||||
{
|
||||
int nCounter = 0;
|
||||
ShapeList m_lstSortedShapes;
|
||||
wxSFShapeBase* pShape;
|
||||
|
||||
// sort shapes list in the way that the line shapes will be at the top of the list
|
||||
ShapeList shapes;
|
||||
GetShapes(CLASSINFO(wxSFShapeBase), shapes, xsSerializable::searchBFS);
|
||||
|
||||
ShapeList::compatibility_iterator node = shapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = node->GetData();
|
||||
if(pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
|
||||
{
|
||||
m_lstSortedShapes.Insert(pShape);
|
||||
nCounter++;
|
||||
}
|
||||
else
|
||||
m_lstSortedShapes.Insert(nCounter, pShape);
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
// find the topmost shape according to the given rules
|
||||
nCounter = 1;
|
||||
node = m_lstSortedShapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = (wxSFShapeBase*)node->GetData();
|
||||
if(pShape->IsVisible() && pShape->IsActive() && pShape->Contains(pos))
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case searchSELECTED:
|
||||
if(pShape->IsSelected())
|
||||
{
|
||||
if(nCounter == zorder)return pShape;
|
||||
else
|
||||
nCounter++;
|
||||
}
|
||||
break;
|
||||
|
||||
case searchUNSELECTED:
|
||||
if(!pShape->IsSelected())
|
||||
{
|
||||
if(nCounter == zorder)return pShape;
|
||||
else
|
||||
nCounter++;
|
||||
}
|
||||
break;
|
||||
|
||||
case searchBOTH:
|
||||
if(nCounter == zorder)return pShape;
|
||||
else
|
||||
nCounter++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::GetShapesAtPosition(const wxPoint& pos, ShapeList& shapes)
|
||||
{
|
||||
shapes.Clear();
|
||||
wxSFShapeBase *pShape;
|
||||
|
||||
ShapeList lstShapes;
|
||||
GetShapes(CLASSINFO(wxSFShapeBase), lstShapes);
|
||||
|
||||
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = node->GetData();
|
||||
if(pShape->IsVisible() && pShape->IsActive() && pShape->Contains(pos))shapes.Append(pShape);
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::GetShapesInside(const wxRect& rct, ShapeList& shapes)
|
||||
{
|
||||
shapes.Clear();
|
||||
wxSFShapeBase* pShape;
|
||||
|
||||
ShapeList lstShapes;
|
||||
GetShapes(CLASSINFO(wxSFShapeBase), lstShapes);
|
||||
|
||||
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = node->GetData();
|
||||
if(pShape->IsVisible() && pShape->IsActive() && pShape->Intersects(rct))shapes.Append(pShape);
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
wxSFShapeBase* wxSFDiagramManager::FindShape(long id)
|
||||
{
|
||||
if(id == -1)return NULL;
|
||||
else
|
||||
return (wxSFShapeBase*)GetItem(id);
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::GetNeighbours(wxSFShapeBase* parent, ShapeList& neighbours, wxClassInfo *shapeInfo, wxSFShapeBase::CONNECTMODE condir, bool direct)
|
||||
{
|
||||
if(parent)
|
||||
{
|
||||
parent->GetNeighbours(neighbours, shapeInfo, condir, direct);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxASSERT(GetRootItem());
|
||||
|
||||
wxSFShapeBase* pShape;
|
||||
|
||||
SerializableList::compatibility_iterator node = GetRootItem()->GetFirstChildNode();
|
||||
while(node)
|
||||
{
|
||||
pShape = (wxSFShapeBase*)node->GetData();
|
||||
pShape->GetNeighbours(neighbours, shapeInfo, condir, direct);
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool wxSFDiagramManager::HasChildren(wxSFShapeBase* parent)
|
||||
{
|
||||
if(parent->GetFirstChildNode())return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::UpdateConnections()
|
||||
{
|
||||
if( !m_lstLinesForUpdate.IsEmpty() )
|
||||
{
|
||||
wxSFLineShape* pLine;
|
||||
IDPair* pIDPair;
|
||||
|
||||
// now check ids
|
||||
long oldSrcId, oldTrgId;
|
||||
long newSrcId, newTrgId;
|
||||
IDList::compatibility_iterator idnode;
|
||||
|
||||
ShapeList::compatibility_iterator node = m_lstLinesForUpdate.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pLine = (wxSFLineShape*)node->GetData();
|
||||
newSrcId = oldSrcId = pLine->GetSrcShapeId();
|
||||
newTrgId = oldTrgId = pLine->GetTrgShapeId();
|
||||
idnode = m_lstIDPairs.GetFirst();
|
||||
while(idnode)
|
||||
{
|
||||
pIDPair = idnode->GetData();
|
||||
/*if(pIDPair->m_nNewID != pIDPair->m_nOldID)
|
||||
{*/
|
||||
if(oldSrcId == pIDPair->m_nOldID) newSrcId = pIDPair->m_nNewID;
|
||||
if(oldTrgId == pIDPair->m_nOldID) newTrgId = pIDPair->m_nNewID;
|
||||
/*}*/
|
||||
idnode = idnode->GetNext();
|
||||
}
|
||||
pLine->SetSrcShapeId(newSrcId);
|
||||
pLine->SetTrgShapeId(newTrgId);
|
||||
|
||||
// check whether line's src and trg shapes really exists
|
||||
if(!GetItem(pLine->GetSrcShapeId()) || !GetItem(pLine->GetTrgShapeId()))
|
||||
{
|
||||
RemoveItem(pLine);
|
||||
}
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
m_lstLinesForUpdate.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::UpdateGrids()
|
||||
{
|
||||
if( !m_lstGridsForUpdate.IsEmpty() )
|
||||
{
|
||||
// now check ids
|
||||
wxSFGridShape* pGrid;
|
||||
IDPair* pIDPair;
|
||||
int nIndex;
|
||||
IDList::compatibility_iterator idnode;
|
||||
|
||||
ShapeList::compatibility_iterator node = m_lstGridsForUpdate.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pGrid = (wxSFGridShape*)node->GetData();
|
||||
nIndex = wxNOT_FOUND;
|
||||
|
||||
idnode = m_lstIDPairs.GetFirst();
|
||||
while(idnode)
|
||||
{
|
||||
pIDPair = idnode->GetData();
|
||||
|
||||
nIndex = pGrid->m_arrCells.Index( pIDPair->m_nOldID );
|
||||
if( nIndex != wxNOT_FOUND ) pGrid->m_arrCells[ nIndex ] = pIDPair->m_nNewID;
|
||||
|
||||
idnode = idnode->GetNext();
|
||||
}
|
||||
|
||||
// check whether grid's children really exists
|
||||
for( size_t i = 0; i < pGrid->m_arrCells.GetCount(); )
|
||||
{
|
||||
if( !GetItem( pGrid->m_arrCells[i] ) ) pGrid->RemoveFromGrid( pGrid->m_arrCells[i] );
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
m_lstGridsForUpdate.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::UpdateAll()
|
||||
{
|
||||
wxSFShapeBase *pShape;
|
||||
|
||||
ShapeList lstShapes;
|
||||
GetShapes( CLASSINFO(wxSFShapeBase), lstShapes );
|
||||
|
||||
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
|
||||
while( node )
|
||||
{
|
||||
pShape = node->GetData();
|
||||
// update only shapes withour children because the Update() function is called recursively on all parents
|
||||
if( !HasChildren( pShape ) ) pShape->Update();
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void wxSFDiagramManager::MoveShapesFromNegatives()
|
||||
{
|
||||
wxSFShapeBase *pShape;
|
||||
wxRealPoint shapePos;
|
||||
double minx = 0, miny = 0;
|
||||
|
||||
// find the maximal negative position value
|
||||
ShapeList shapes;
|
||||
GetShapes(CLASSINFO(wxSFShapeBase), shapes);
|
||||
|
||||
ShapeList::compatibility_iterator node = shapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
shapePos = node->GetData()->GetAbsolutePosition();
|
||||
|
||||
if(node == shapes.GetFirst())
|
||||
{
|
||||
minx = shapePos.x;
|
||||
miny = shapePos.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(shapePos.x < minx)minx = shapePos.x;
|
||||
if(shapePos.y < miny)miny = shapePos.y;
|
||||
}
|
||||
|
||||
node = node->GetNext();
|
||||
}
|
||||
|
||||
// move all parents shape so they (and their children) will be located in the positive values only
|
||||
if((minx < 0) || (miny < 0))
|
||||
{
|
||||
node = shapes.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
pShape = node->GetData();
|
||||
|
||||
if(pShape->GetParentShape() == NULL)
|
||||
{
|
||||
if(minx < 0)pShape->MoveBy(abs((int)minx), 0);
|
||||
if(miny < 0)pShape->MoveBy(0, abs((int)miny));
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user