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

📄 flowchartentitycontainer.cpp

📁 CFlowchartEditor is an extension of CDiagramEditor. CDiagramEditor is a vector editor, with a CWnd-d
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ==========================================================================
	CFlowchartEntityContainer

	Author :		Johan Rosengren, Abstrakt Mekanik AB

	Date :			2004-04-29

	Purpose :		CFlowchartEntityContainer is a CDiagramEntityContainer-
					derived class, holding the data for a CFlowchartEditor. 
					In addition to CDiagramEntityContainer, this class keeps 
					and manages a list of links. This includes copy/paste 
					and undo-handling.

	Description :	The class uses a derived CDiagramClipboardHandler.

	Usage :			Use as a normal CDiagramEntityContainer class. The 
					editor class exposes functions for command enabling.

   ========================================================================*/
#include "stdafx.h"
#include "FlowchartEntityContainer.h"
#include <math.h>

CFlowchartEntityContainer::CFlowchartEntityContainer()
/* ============================================================
	Function :		CFlowchartEntityContainer::CFlowchartEntityContainer
	Description :	constructor
					
	Return :		void
	Parameters :	none

	Usage :			

   ============================================================*/
{
}

CFlowchartEntityContainer::~CFlowchartEntityContainer()
/* ============================================================
	Function :		CFlowchartEntityContainer::~CFlowchartEntityContainer
	Description :	destructor
					
	Return :		void
	Parameters :	none

	Usage :			

   ============================================================*/
{

	ClearLinks();
	ClearUndo();

}

BOOL CFlowchartEntityContainer::CreateLink( CFlowchartEntity* from, CFlowchartEntity* to, const CString& title )
/* ============================================================
	Function :		CFlowchartEntityContainer::CreateLink
	Description :	Creates a link between from and to and 
					puts it into the link-array.
					
	Return :		BOOL					-	TRUE if ok.
	Parameters :	CFlowchartEntity* from	-	From-object.
					CFlowchartEntity* to	-	To-object.
					const CString& title	-	Title of link.
					
	Usage :			Call to create a link between from and to.

   ============================================================*/
{

	BOOL result = FALSE;
	int	fromtype = 0;
	int	totype = 0;
	CPoint source;
	CPoint target;

	if( FindClosestLink( from, to, fromtype, totype ) )
	{

		CFlowchartLink* link = new CFlowchartLink;

		link->from = from->GetName();
		link->to = to->GetName();
		link->fromtype = fromtype;
		link->totype = totype;
		link->title = title;

		m_links.Add( link );
		result = TRUE;
	}

	return result;

}

BOOL CFlowchartEntityContainer::HasLinks( CFlowchartEntity* obj1, CFlowchartEntity* obj2 )
/* ============================================================
	Function :		CFlowchartEntityContainer::HasLinks
	Description :	Returns TRUE if obj1 and obj2 are linked 
					to each other or another object using the 
					link-point closest between them..
					
	Return :		BOOL					-	TRUE if obj1 and 
												obj2 has a link
	Parameters :	CFlowchartEntity* obj1	-	First object to 
												test
					CFlowchartEntity* obj2	-	Second object 
												to test
					
	Usage :			Call to see if it is possible to link two 
					objects, or they already have one or both 
					link-points attached.

   ============================================================*/
{

	BOOL result = FALSE;
	CString n1 = obj1->GetName();
	CString n2 = obj2->GetName();
	
	int	fromtype = 0;
	int	totype = 0;
	if( FindClosestLink( obj1, obj2, fromtype, totype ) )
	{
		if( fromtype & LINK_ALL && totype & LINK_ALL )
		{
			// Box-objects
			int max = m_links.GetSize();
			for( int t = 0; t < max ; t++ )
			{
				CFlowchartLink* link = static_cast< CFlowchartLink* >( m_links.GetAt( t ) );
				if( ( link->fromtype == fromtype && link->from == n1 ) || ( link->totype == totype && link->to == n2 ) )
					result = TRUE;
			}
		}
		else
		{
			// Line-objects
			int max = m_links.GetSize();
			for( int t = 0; t < max ; t++ )
			{
				CFlowchartLink* link = static_cast< CFlowchartLink* >( m_links.GetAt( t ) );
				if( ( ( link->fromtype == fromtype && link->from == n1 ) && ( link->totype == totype && link->to == n2 ) ) ||
					( ( link->fromtype == totype && link->to == n1 ) && ( link->totype == fromtype && link->from == n2 ) ) )
					result = TRUE;
			}
		}
	}

	return result;

}

BOOL CFlowchartEntityContainer::FindClosestLink( CFlowchartEntity* obj1, CFlowchartEntity* obj2, int& fromtype, int& totype )
/* ============================================================
	Function :		CFlowchartEntityContainer::FindClosestLink
	Description :	Finds the closet link types between two 
					objects.
					
	Return :		BOOL					-	TRUE if the 
												objects can be 
												linked.
	Parameters :	CFlowchartEntity* obj1	-	First object 
												to link
					CFlowchartEntity* obj2	-	Second object 
												to link
					int& fromtype			-	Type of link for the first object
					int& totype				-	Type of link for the second object.
					
	Usage :			The link types can be:
					LINK_TOP		Top of the object.
					LINK_BOTTOM		Bottom of the object.
					LINK_LEFT		To the left of the object.
					LINK_RIGHT		To the right of the object.
					LINK_START		To the start of the line (normally 
									the top-left corner of 
									the non-normalized bounding 
									rect).
					LINK_END		To the end of the line 
									(normally the bottom-right 
									corner of the non-normalized 
									bounding rect).

   ============================================================*/
{

	BOOL result = TRUE;
	CPoint start;
	CPoint end;
	double diff2 = 0;
	double diff1 = 0x7FFFFFFF;

	// We go through all the allowed links for obj1, and get the 
	// distance between the inspected link point and the allowed 
	// link points of obj2. Shortest distance wins!

	if( ( obj1->AllowLink() & LINK_LEFT ) )
	{
		start = obj1->GetLinkPosition( LINK_LEFT );
		if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && start.x > end.x )
			{
				fromtype = LINK_LEFT;
				totype = LINK_START;
				diff1 = diff2;
			}

			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && start.x > end.x )
			{
				fromtype = LINK_LEFT;
				totype = LINK_END;
				diff1 = diff2;
			}
		}
		else
		{
			end = obj2->GetLinkPosition( LINK_RIGHT );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && start.x > end.x )
			{
				fromtype = LINK_LEFT;
				totype = LINK_RIGHT;
				diff1 = diff2;
			}
		}
	}

	if( ( obj1->AllowLink() & LINK_RIGHT ) )
	{
		start = obj1->GetLinkPosition( LINK_RIGHT );
		if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.x > start.x )
			{
				fromtype = LINK_RIGHT;
				totype = LINK_START;
				diff1 = diff2;
			}

			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.x > start.x )
			{
				fromtype = LINK_RIGHT;
				totype = LINK_END;
				diff1 = diff2;
			}
		}
		else
		{
			end = obj2->GetLinkPosition( LINK_LEFT );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.x > start.x )
			{
				fromtype = LINK_RIGHT;
				totype = LINK_LEFT;
				diff1 = diff2;
			}
		}
	}

	if( ( obj1->AllowLink() & LINK_TOP ) )
	{
		start = obj1->GetLinkPosition( LINK_TOP );
		if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y > end.y )
			{
				fromtype = LINK_TOP;
				totype = LINK_START;
				diff1 = diff2;
			}
			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y > end.y )
			{
				fromtype = LINK_TOP;
				totype = LINK_END;
				diff1 = diff2;
			}
		}
		else
		{
			end = obj2->GetLinkPosition( LINK_BOTTOM );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y > end.y )
			{
				fromtype = LINK_TOP;
				totype = LINK_BOTTOM;
				diff1 = diff2;
			}
		}
	}

	if( ( obj1->AllowLink() & LINK_BOTTOM ) )
	{
		start = obj1->GetLinkPosition( LINK_BOTTOM );
		if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.y > start.y )
			{
				fromtype = LINK_BOTTOM;
				totype = LINK_START;
				diff1 = diff2;
			}
			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.y > start.y )
			{
				fromtype = LINK_BOTTOM;
				totype = LINK_END;
				diff1 = diff2;
			}
		}
		else
		{
			end = obj2->GetLinkPosition( LINK_TOP );
			diff2 = Dist( start, end );
			if( diff2 <= diff1 && end.y > start.y )
			{
				fromtype = LINK_BOTTOM;
				totype = LINK_TOP;
				diff1 = diff2;
			}
		}
	}

	int sum2 = 0;
	if( ( obj1->AllowLink() & LINK_START ) )
	{
		start = obj1->GetLinkPosition( LINK_START );

		if( obj2->AllowLink() & LINK_START )
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 < diff1 )
			{
				fromtype = LINK_START;
				totype = LINK_START;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_END )
		{
			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 < diff1 )
			{
				fromtype = LINK_START;
				totype = LINK_END;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_LEFT )
		{
			end = obj2->GetLinkPosition( LINK_LEFT );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.x <= end.x)
			{
				fromtype = LINK_START;
				totype = LINK_LEFT;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_RIGHT )
		{
			end = obj2->GetLinkPosition( LINK_RIGHT );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.x >= end.x )
			{
				fromtype = LINK_START;
				totype = LINK_RIGHT;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_TOP )
		{
			end = obj2->GetLinkPosition( LINK_TOP );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y <= end.y )
			{
				fromtype = LINK_START;
				totype = LINK_TOP;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_BOTTOM )
		{
			end = obj2->GetLinkPosition( LINK_BOTTOM );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y >= end.y )
			{
				fromtype = LINK_START;
				totype = LINK_BOTTOM;
				diff1 = diff2;
			}
		}

	}

	if( ( obj1->AllowLink() & LINK_END ) )
	{
		start = obj1->GetLinkPosition( LINK_END );
		if( obj2->AllowLink() & LINK_START )
		{
			end = obj2->GetLinkPosition( LINK_START );
			diff2 = Dist( start, end );
			if( diff2 < diff1 )
			{
				fromtype = LINK_END;
				totype = LINK_START;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_END )
		{
			end = obj2->GetLinkPosition( LINK_END );
			diff2 = Dist( start, end );
			if( diff2 < diff1 )
			{
				fromtype = LINK_END;
				totype = LINK_END;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_LEFT )
		{
			end = obj2->GetLinkPosition( LINK_LEFT );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.x <= end.x )
			{
				fromtype = LINK_END;
				totype = LINK_LEFT;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_RIGHT )
		{
			end = obj2->GetLinkPosition( LINK_RIGHT );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.x >= end.x )
			{
				fromtype = LINK_END;
				totype = LINK_RIGHT;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_TOP )
		{
			end = obj2->GetLinkPosition( LINK_TOP );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y <= end.y )
			{
				fromtype = LINK_END;
				totype = LINK_TOP;
				diff1 = diff2;
			}
		}

		if( obj2->AllowLink() & LINK_BOTTOM )
		{
			end = obj2->GetLinkPosition( LINK_BOTTOM );
			diff2 = Dist( start, end );
			if( diff2 < diff1 && start.y >= end.y )
			{
				fromtype = LINK_END;
				totype = LINK_BOTTOM;
				diff1 = diff2;
			}
		}

	}

	// To be really, really sure
	if( !( obj1->AllowLink() & fromtype ) )
	{
		result = FALSE;
		fromtype = 0;
	}

	if( !( obj2->AllowLink() & totype ) )
	{
		result = FALSE;
		totype = 0;
	}

	return result;

}

CFlowchartLink* CFlowchartEntityContainer::GetLinkAt( int index )
/* ============================================================
	Function :		CFlowchartEntityContainer::GetLinkAt
	Description :	Returns the CFlowchartLink object at 
					position index in the internal data array.
					
	Return :		CFlowchartLink*	-	Object at index. NULL 
										if not a CFlowchartLink 
										or out of bounds.
	Parameters :	int index		-	The index in the data 
										array.
					
	Usage :			Call to get the object at index, or to check 
					if the object is a CFlowchartLink-object.

   ============================================================*/
{

	CFlowchartLink* result = NULL;
	if( index < GetLinks() )
		result = static_cast< CFlowchartLink* >( m_links[ index ] );

	return result;

}

int CFlowchartEntityContainer::GetLinks()
/* ============================================================
	Function :		CFlowchartEntityContainer::GetLinks
	Description :	Returns the number of links in the link 
					array.
					
	Return :		int		-	The current number of links.
	Parameters :	none

	Usage :			Call to get the current number of links.

   ============================================================*/
{

	return m_links.GetSize();

⌨️ 快捷键说明

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