www.pudn.com > 20065291434354190.rar > XSpot.cpp


#include "Stdafx.h" 
 
#include "XSpot.h" 
#include "XTube.h" 
 
#include  
const float pi = 3.1415926535f; 
 
XSpot::XSpot (PointF pt, SpotTypeEnum vType, CString vName) 
{ 
	parent = NULL; 
 
	position = pt; 
	type = vType; 
	name = vName; 
	title = ""; 
	description = ""; 
 
	icon = ITE_NULL; 
 
	left = position; 
	right = position; 
	center = position; 
 
	fontFace = "Arial"; 
	fontHeight = 10; 
	fontStyle = FontStyleBold; 
 
	angle = 0; 
	startAngle = 0; 
	sweepAngle = 0; 
	radius = 0; 
 
	ANGLE = 0; 
	A = B1 = B2 = C1 = C2 = position; 
} 
 
XSpot::XSpot (Point pt, SpotTypeEnum vType, CString vName) 
{ 
	parent = NULL; 
 
	position = PointF (REAL(pt.X), REAL(pt.Y)); 
	type = vType; 
	name = vName; 
	title = ""; 
	description = ""; 
 
	icon = ITE_NULL; 
 
	left = position; 
	right = position; 
	center = position; 
 
	fontFace = "Arial"; 
	fontHeight = 10; 
	fontStyle = FontStyleBold; 
 
	angle = 0; 
	startAngle = 0; 
	sweepAngle = 0; 
	radius = 0; 
 
	ANGLE = 0; 
	A = B1 = B2 = C1 = C2 = position; 
} 
 
bool XSpot::operator == (const XSpot& vSpot) 
{ 
	return (parent == vSpot.parent && position.Equals (vSpot.position) == TRUE && type == vSpot.type && name == vSpot.name 
		&& description == vSpot.description ); 
 
} 
 
int XSpot::Move (float x, float y) 
{ 
	PointF offs (x, y); 
 
	position = position + offs; 
 
	left = left + offs; 
	right = right + offs; 
	center = center + offs; 
	A = A + offs; 
	B1 = B1 + offs; 
	B2 = B2 + offs; 
	C1 = C1 + offs; 
	C2 = C2 + offs; 
 
	return 0; 
} 
 
void XSpot::SetParent (XTube* vParent) 
{ 
	parent = vParent; 
 
	SetType (type); 
 
	fontColor = vParent->defFontColor; 
	fontFace = vParent->defFontFace; 
	fontHeight = vParent->defFontHeight; 
	fontStyle = vParent->defFontStyle; 
} 
 
void XSpot::SetType (SpotTypeEnum vType) 
{ 
	type = vType; 
 
	if (!parent) return; 
 
	switch (type) 
	{ 
		case STE_LEFT: 
			color = parent->defLeftColor; 
			break; 
 
		case STE_RIGHT: 
			color = parent->defRightColor; 
			break; 
 
		case STE_CIRCLE: 
		case STE_SMALL_CIRCLE: //自动取外部点 
		case STE_MEDIUM_CIRCLE: 
		case STE_LARGE_CIRCLE: //自动取外部点 
			color = parent->defCircleOutlineColor; 
			break; 
 
		case STE_START: 
			color = parent->defStartColor; 
			break; 
 
		case STE_END: 
			color = parent->defEndColor; 
			break; 
 
		default: 
			color = Color(255, 0, 0, 0); 
			break; 
 
	} 
} 
 
int XSpot::Draw (Graphics* g, map* spotMap) 
{ 
	if (!parent) return -1; 
 
	//<<优化 
	if (type == STE_NULL) return 0; 
	if (name == "" || name.IsEmpty ()) return 0; 
 
	if (spotMap) 
	{ 
		map::iterator pos = spotMap->find (name); 
		if (pos == spotMap->end ()) 
			(*spotMap) [name] = position; 
		else ///*** 
			return 0; 
	} 
	//>> 
 
	REAL width = parent->lineWidth; 
 
	//画车站 
	Pen spotPen (color, width); 
	PointF refPoint; 
	switch (type) 
	{ 
		case STE_LEFT: 
			g->DrawLine (&spotPen, A, B1); 
			refPoint = C1; 
			break; 
 
		case STE_RIGHT: 
			g->DrawLine (&spotPen, A, B2); 
			refPoint = C2; 
			break; 
 
		case STE_START: 
			g->DrawLine (&spotPen, B1, B2); 
			refPoint = C1; //*** 
			break; 
 
		case STE_END: 
			g->DrawLine (&spotPen, B1, B2); 
 
			refPoint = C1; //*** 
			break; 
 
		case STE_INNER: 
		{ 
			float dx1 = A.X - center.X; 
			float dy1 = A.Y - center.Y; 
 
			float dx2 = C1.X - A.X; 
			float dy2 = C1.Y - A.Y; 
 
			if (dx1*dx2 < 0 || dy1*dy2 < 0) 
				refPoint = C1; 
			else 
				refPoint = C2; 
 
			break; 
		} 
 
		case STE_CIRCLE: 
		case STE_SMALL_CIRCLE: //自动取外部点 
		case STE_MEDIUM_CIRCLE: 
		case STE_LARGE_CIRCLE: //自动取外部点 
		{ 
			REAL radius = width; 
			REAL lineWidth = 2; 
 
			if (type == STE_SMALL_CIRCLE) 
			{ 
				radius = 3; 
				lineWidth = 1; 
			} 
			else if (type == STE_MEDIUM_CIRCLE) 
			{ 
				radius = 5; 
				lineWidth = 1.5; 
			} 
			else if (type == STE_LARGE_CIRCLE) 
			{ 
				radius = 10; 
				lineWidth = 2; 
			} 
 
			Pen circlePen (color, lineWidth); 
			SolidBrush circleBrush (parent->defCircleFillColor); 
 
			g->FillEllipse (&circleBrush, A.X - radius, A.Y-radius, radius*2, radius*2); 
			g->DrawEllipse (&circlePen, A.X - radius, A.Y-radius, radius*2, radius*2); 
 
			//refPoint = C1; 
			//break; 
		} 
 
		case STE_OUTER: 
		case STE_AUTO: 
		{ 
			float dx1 = A.X - center.X; 
			float dy1 = A.Y - center.Y; 
 
			float dx2 = C1.X - A.X; 
			float dy2 = C1.Y - A.Y; 
 
			if (dx1*dx2 < 0 || dy1*dy2 < 0) 
				refPoint = C2; 
			else 
				refPoint = C1; 
 
			break; 
		} 
 
		default: 
			refPoint = C1; 
			break; 
	} 
 
	// 
	Font* font; 
	if (fontFace == parent->defFontFace 
		&& fontHeight == parent->defFontHeight 
		&& fontStyle == parent->defFontStyle) 
		font = parent->defFont; 
	else 
		font = new Font (CStringW(fontFace).GetBuffer(), fontHeight, fontStyle); 
 
	RectF testRect (0, 0, 200, 200); 
	RectF resultRect = testRect; 
	g->MeasureString (CStringW(name).GetBuffer (), CStringW(name).GetLength(), font, testRect, &resultRect); 
 
	RectF layoutRect = resultRect; 
 
	float dx = refPoint.X - A.X; 
	float dy = refPoint.Y - A.Y; 
	 
	if (fabsf (dx) > fabsf (dy)) 
	{ 
		if (dx > 0) //右 
			layoutRect.Offset (refPoint.X, refPoint.Y - resultRect.Height/2); 
		else //左 
			layoutRect.Offset (refPoint.X - resultRect.Width, refPoint.Y - resultRect.Height/2); 
	} 
	else 
	{ 
		REAL kx = fabsf (dx/dy*resultRect.Width/4); 
		if (dx < 0) 
			kx = -kx; 
 
		if (dy > 0) //下 
			layoutRect.Offset (refPoint.X - resultRect.Width/2 + kx, refPoint.Y); 
		else //上 
			layoutRect.Offset (refPoint.X - resultRect.Width/2 + kx, refPoint.Y - resultRect.Height); 
	} 
 
	SolidBrush fontBrush (fontColor); 
	g->DrawString (CStringW(name).GetBuffer (), CStringW(name).GetLength(), font, layoutRect, NULL, &fontBrush); 
/* 
	Pen outlinePen (parent->outlineColor, 1); 
	g->DrawRectangle (&outlinePen, RectF(refPoint.X - 2, refPoint.Y - 2, 4, 4)); 
	g->DrawRectangle (&outlinePen, layoutRect); 
*/ 
	if (font != parent->defFont) 
		delete font; 
 
	return 0; 
}