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

📄 transitionarrow.c

📁 这个工具集提供以下结构化分析和UML分析中所用的图形化绘图工具:ER-diagrams, data and event flow diagrams and state-transition diagr
💻 C
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////////// This file is part of Toolkit for Conceptual Modeling (TCM).// (c) copyright 1996, Vrije Universiteit Amsterdam.// Author: Frank Dehne (frank@cs.vu.nl).//// TCM is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or // (at your option) any later version.//// TCM is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with TCM; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA.////////////////////////////////////////////////////////////////////////////////#include "grafport.h"#include "inputfile.h"#include "outputfile.h"#include <math.h>#include <stdlib.h>#include "transition.h"#include "transitionarrow.h"#include "diagramviewer.h" const int TransitionArrow::HLINELEN = 20;const int TransitionArrow::HLINEXOFFSET = 4;const int TransitionArrow::HLINEYOFFSET = 2;const int TransitionArrow::HLINEDIST = 10;TransitionArrow::TransitionArrow(ShapeView *v, Grafport *g, 		GShape *node1, GShape *node2, List<Point *> *aline, bool Curved): 			Line(v, g, node1, node2, aline, Curved) {	event = new TextShape(v, g, this);	event->SetAlignment(TextAlign::LEFT);	event->SetDescription("Event");	actions = new List<TextShape *>;	separator = RIGHT;	CalcPosition();	SetEnd2(LineEnd::FILLED_ARROW);}TransitionArrow::TransitionArrow(ShapeView *v, Grafport *g, GShape *node1, 	GShape *node2, bool Curved): Line(v, g, node1, node2, Curved) {	event = new TextShape(v, g, this);	event->SetAlignment(TextAlign::LEFT);	event->SetDescription("Event");	actions = new List<TextShape *>;	separator = RIGHT;	SetEnd2(LineEnd::FILLED_ARROW);}TransitionArrow::TransitionArrow(const TransitionArrow &aline): Line(aline) {	hlineFrom = aline.hlineFrom;	hlineTo = aline.hlineTo;	anchorPoint = aline.anchorPoint;	separator = aline.separator;	event = new TextShape(*(TextShape *)(aline.event));	event->SetParent(this);	actions = new List<TextShape *>;	for (aline.actions->first(); !aline.actions->done(); aline.actions->next()) {		TextShape *a = aline.actions->cur();		TextShape *b = new TextShape (*a);		b->SetParent(this);		actions->add(b);	}}TransitionArrow::~TransitionArrow() {	delete event;	actions->clear();	delete actions;}void TransitionArrow::DrawShape() {	Line::DrawShape();	event->Draw();	SetDrawAttributes();	GetGrafport()->DrawLine(hlineFrom.x, hlineFrom.y, hlineTo.x, hlineTo.y);	for (actions->first(); !actions->done(); actions->next())		actions->cur()->Draw();}void TransitionArrow::UpdateAnchor(const Point *p, const Point *t) {	Point pt = anchorPoint;	if (IsCurved()) {		pt.y += p->y;		pt.x += p->x;	}	else if (separator == LEFT || separator == RIGHT) {		// find segment where the anchor point is located.		// (void) GetLine(pt.x, pt.y);		pt.y += p->y;		// shift left <-> RIGHT ?		Point dp = *t + *p;		if (dp.x < anchorPoint.x)			separator = LEFT;		else			separator = RIGHT;	}	else { 		pt.x += p->x;		// shift up <-> down ?		Point dp = *t + *p;		if (dp.y < anchorPoint.y)			separator = UP;		else			separator = DOWN;	}	Undraw();	if (IsCurved())		anchorPoint = pt;	else if (separator == LEFT || separator == RIGHT) {		int cx, cy;		// make anchorpoint a point on the line.		(void) ContainsPtLine(pt.x, pt.y, 			(*GetLine())[GetLineNumber()-1], 			(*GetLine())[GetLineNumber()], cx, cy);		anchorPoint = Point(cx, cy);	}	else		anchorPoint = pt;	CalcHLinePart();	Draw();}void TransitionArrow::CalcPosition() {	Line::CalcPosition();	anchorPoint = *GetPosition();	CalcSeparator();	CalcHLinePart();}void TransitionArrow::CalcHLinePart() {	CalcPositionHLine();	CalcPositionEvent();	CalcPositionActions();}void TransitionArrow::CalcSeparator() {	double alpha;	if (GetWidth() != 0)		alpha = atan((double)GetHeight()/(double)GetWidth());	else		alpha = 2*atan(1);	// estimation.	// if (fabs(alpha) > 0.5*atan(1)) { 	if (fabs(alpha) > atan(1)) { 		if (separator == UP || separator == DOWN)			separator = RIGHT;	}	else {		if (separator == LEFT || separator == RIGHT)			separator = UP;	}}void TransitionArrow::CalcPositionHLine() {	int d1 = HLineLength();	if (separator == RIGHT) { // attach right to line.		hlineFrom = anchorPoint;		hlineTo = Point(hlineFrom.x + d1, hlineFrom.y);	}	else if (separator == LEFT) { // attach left to line.		hlineTo = anchorPoint;		hlineFrom = Point(hlineTo.x - d1, hlineTo.y);	}	else { // put above/below the line.		double alpha = atan((double)GetHeight()/(double)GetWidth());		if (separator == UP) {			int d2 = (int)(cos(alpha)*max(HLINEDIST,				 HLINEYOFFSET+actions->count()*GetName()->GetFontHeight()));			d2 += HLINEYOFFSET;			hlineFrom = Point(anchorPoint.x - d1/2, 				anchorPoint.y - d2);			hlineTo = Point(anchorPoint.x + d1/2, 				anchorPoint.y - d2);		}		else { // separator == DOWN			int textHeight = max(GetName()->GetFontHeight(), 						event->GetStringHeight());			int d2 = (int)(cos(alpha)*max(HLINEDIST,HLINEYOFFSET+					textHeight));			d2 += HLINEYOFFSET;			hlineFrom = Point(anchorPoint.x - d1/2, 				anchorPoint.y + d2);			hlineTo = Point(anchorPoint.x + d1/2, 				anchorPoint.y + d2);		}	}	hlineFrom = Point(max(3,hlineFrom.x), max(3,hlineFrom.y)); 	hlineTo = Point(max(3,hlineTo.x), max(3,hlineTo.y)); }void TransitionArrow::CalcPositionEvent() {	Point pt;	const string *s = event->GetString();	if (*s != "") {		pt.x = hlineFrom.x + event->GetStringWidth()/2;		pt.y = hlineFrom.y - event->GetStringHeight()/2;		pt.y -= 2*HLINEYOFFSET;	}	else {		pt.x = (hlineFrom.x + hlineTo.x)/2;		pt.y = hlineFrom.y - event->GetFontHeight()/2;	}	pt.x += HLINEXOFFSET;	event->SetPosition(&pt);}void TransitionArrow::CalcPositionActions() {	Point pt; int w, h;	int textHeight = GetName()->GetFontHeight();	pt = hlineFrom;	pt.y += HLINEYOFFSET + textHeight/2;	for (actions->first(); !actions->done(); actions->next()) {		w = actions->cur()->GetStringWidth();		h = actions->cur()->GetStringHeight();		pt.x = hlineFrom.x + w/2 + HLINEXOFFSET;		actions->cur()->SetPosition(&pt);		pt.y += textHeight;	}}void TransitionArrow::UpdateEvent(const string *c) {	if (IsVisible())		Undraw();	event->SetString(c);	CalcHLinePart();	if (IsVisible())		Draw();}void TransitionArrow::UpdateAction(const string *s, unsigned n, bool update) {	if (IsVisible())		Undraw();	SetAction(s, n, update);	CalcHLinePart();	if (IsVisible())		Draw();}void TransitionArrow::SetSelect(bool set) {	Line::SetSelect(set);}bool TransitionArrow::ContainsPt(int x, int y) {	if (Line::ContainsPt(x,y))		return True;	else		return HitHLine(x, y);}bool TransitionArrow::HitHLine(int x, int y) {	// point near horizontal line ?	int textHeight = GetName()->GetFontHeight();	return (x >= hlineFrom.x && x <= hlineTo.x &&		y >= hlineFrom.y - textHeight &&		y <= hlineFrom.y + textHeight);}int TransitionArrow::HLineLength() {	int max = HLINELEN;	int n = event->GetStringWidth()+HLINEXOFFSET;	if (n > max)		max = n;	for (actions->first(); !actions->done(); actions->next()) {		n = actions->cur()->GetStringWidth()+HLINEXOFFSET;		if (n > max)			max = n;	}	return max;}bool TransitionArrow::InTextArea(int x, int y) {	if (Line::InTextArea(x,y))		return True;	else if (event->ContainsPt(x, y))		return True;	for (actions->first(); !actions->done(); actions->next()) {		if (actions->cur()->ContainsPt(x, y))			return True;	}	return False;}TextShape *TransitionArrow::HitTextShape(int x, int y) {	if (event->ContainsPt(x, y))		return event;	for (actions->first(); !actions->done(); actions->next()) {		 if (actions->cur()->ContainsPt(x, y))			return actions->cur();	} 	return 0;}TextShape *TransitionArrow::ChooseTextShape(int x, int y) {	// This is the winner of the "clumsiest function award".	int textHeight = GetName()->GetFontHeight();	// hit event string.	if (event->ContainsPt(x, y))		return event;	// hit action string.	if (actions->first()) {		// action text shapes can overlap		// make sure that you choose the right one.		do {			int pt_y = actions->cur()->GetTopMost();			pt_y += textHeight;			if (actions->cur()->ContainsPt(x,y) && y <= pt_y) {				// return the action.				TextShape *t = actions->cur();				return t;			}			// pt_y += textHeight;		} while (actions->next());		if (actions->last()) {			if (actions->cur()->ContainsPt(x,y))				return actions->cur();		}	}	// hit hline part ?	if (HitHLine(x, y)) {		if (y <= hlineFrom.y) {			// above line -> return event.			Point pt = *event->GetPosition();

⌨️ 快捷键说明

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