1
////////////////////////////////////////////////////////////////////////////////
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
4
// (c) copyright 1995, Vrije Universiteit Amsterdam.
5
// Author: Frank Dehne (frank@cs.vu.nl).
7
// TCM is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// TCM is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with TCM; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
////////////////////////////////////////////////////////////////////////////////
22
#include "inputfile.h"
23
#include "outputfile.h"
28
const int T1Line::CL_FRACTION = 4;
30
T1Line::T1Line(ShapeView *v, Grafport *g, GShape *n1, GShape *n2,
31
List<Point *> *aline, bool Curved):
32
Line(v, g, n1, n2, aline, Curved) {
34
CalcPositionTextShapes();
37
T1Line::T1Line(ShapeView *v, Grafport *g, GShape *n1, GShape *n2,
38
bool Curved): Line(v, g, n1, n2, Curved) {
42
T1Line::T1Line(const T1Line &aline): Line(aline) {
43
textShape1 = new TextShape(*aline.textShape1);
44
textShape1->SetParent(this);
45
t1Position = aline.t1Position;
48
void T1Line::InitTextShapes() {
49
textShape1 = new TextShape(GetView(), GetGrafport(), this);
50
textShape1->SetSequence(1);
58
void T1Line::CalcPosition() {
60
CalcPositionTextShapes();
63
void T1Line::CalcPositionTextShapes() {
64
CalcPositionTextShape(textShape1, t1Position);
67
void T1Line::UpdateTextShape1(const string *s) {
70
textShape1->SetString(s);
75
void T1Line::SetSelect(bool s) {
77
textShape1->SetSelect(s);
80
void T1Line::SetFont(XFont *ft) {
82
textShape1->SetFont(ft);
85
void T1Line::SetTextColor(const string *c) {
86
Line::SetTextColor(c);
87
textShape1->SetColor(c);
90
TextShape *T1Line::HitTextShape(int x, int y) {
91
TextShape *textShape = Line::HitTextShape(x, y);
94
if (check(textShape1) && textShape1->ContainsPt(x, y))
99
bool T1Line::InTextArea(int x, int y) {
100
if (Line::InTextArea(x, y))
103
return textShape1->InTextArea(x, y);
106
TextShape *T1Line::ChooseTextShape(int x, int y) {
107
if (HitTextShapeArea(textShape1, t1Position, x, y))
109
return Line::ChooseTextShape(x, y);
112
bool T1Line::HasTextShape(TextShape *t) const {
113
if (Line::HasTextShape(t))
116
return (t==textShape1);
119
bool T1Line::HasString(const string *s, bool sens, bool sub) const {
120
if (Line::HasString(s, sens, sub))
122
return (*s != "" && textShape1->HasString(s, sens, sub));
125
bool T1Line::HasString(const string *s, bool sens, bool sub,
126
List<TextShape *> *list) {
127
bool b = Line::HasString(s, sens, sub, list);
129
b += textShape1->HasString(s, sens, sub, list);
133
void T1Line::WriteMembers(OutputFile *ofile) {
134
Line::WriteMembers(ofile);
135
(*ofile)<< "\t{ T1Position " << *(textShape1->GetPosition()) << " }\n";
138
bool T1Line::ReadMembers(InputFile *ifile, double format) {
139
if (!Line::ReadMembers(ifile, format))
141
// read position of the textShape1 text shape.
144
if (!ifile->ReadAttribute2("C1Position", &val1, &val2))
148
if (!ifile->ReadAttribute2("T1Position", &val1, &val2))
151
int x = val1.toint();
152
int y = val2.toint();
153
if (x <= 0 || y <= 0)
154
textShape1->SetWellPositioned(False);
155
Point pt = Point(x, y);
156
textShape1->SetPosition(&pt);
160
void T1Line::SetGrafport(Grafport *g) {
161
Line::SetGrafport(g);
162
textShape1->SetGrafport(g);
165
void T1Line::SetView(ShapeView *v) {
167
textShape1->SetView(v);
170
int T1Line::GetLeftMost() const {
171
return min(Line::GetLeftMost(), textShape1->GetLeftMost());
174
int T1Line::GetTopMost() const {
175
return min(Line::GetTopMost(), textShape1->GetTopMost());
178
int T1Line::GetRightMost() const {
179
return max(Line::GetRightMost(), textShape1->GetRightMost());
182
int T1Line::GetBottomMost() const {
183
return max(Line::GetBottomMost(), textShape1->GetBottomMost());
186
void T1Line::SetTextShape() {
187
Line::SetTextShape();
189
textShape1->SetString(&empty);
190
textShape1->SetParent(this);
191
// calculate default position.
192
if (!textShape1->IsWellPositioned()) {
193
CalcPositionTextShapes();
194
textShape1->SetWellPositioned(True);
198
void T1Line::DrawShape() {
203
void T1Line::MoveRaw(const Point *delta) {
204
Line::MoveRaw(delta);
205
textShape1->Move(delta);
208
void T1Line::CalcPositionTextShape(TextShape *textShape, PositionType tpos) {
209
double pi2 = 2*atan(1); // 90 degrees.
210
List<Point *> *l = GetLine();
212
if (tpos == BL || tpos == TL) {
217
int len = GetLine()->count();
218
from = (*GetLine())[len-1];
219
to = (*GetLine())[len-2];
221
double dy = (double)(to->y - from->y);
222
double dx = (double)(to->x - from->x);
223
double alpha = (dx == 0) ? pi2 : atan(dy/dx);
224
double extrax = (CL_DISTX * sin(alpha));
225
double extray = (CL_DISTY * cos(alpha));
227
if (extray <= 0.01 && extray >= -0.01)
228
extrax = -fabs(extrax);
229
int w = (to->x - from->x)/(2*CL_FRACTION);
230
int h = (to->y - from->y)/(2*CL_FRACTION);
231
// some extra corrections.
232
if (sqrt(w*w + h*h) <= 10) {
233
if (w != 0 && h < 4 && abs(w) < 10)
234
w = (w < 0)? -10 : 10;
235
if (h != 0 && w < 4 && abs(h) < 10)
236
h = (h < 0)? -10 : 10;
243
pt.x = from->x + w - (int)extrax;
244
pt.y = from->y + h + (int)extray;
248
pt.x = from->x + w + (int)extrax;
249
pt.y = from->y + h - (int)extray;
252
if (check(textShape))
253
textShape->SetPosition(&pt);
256
bool T1Line::HitExtraTextShapeArea(int x, int y,
257
const Point *from, const Point *to) {
259
if (!ContainsPtLine(x, y, from, to, c_x, c_y))
261
// distance line-textshape
262
int w = (to->x - from->x)/CL_FRACTION;
263
int h = (to->y - from->y)/CL_FRACTION;
264
int quadra = w * w + h * h;
266
int delta = (from->x - c_x) * (from->x - c_x) +
267
(from->y - c_y) * (from->y - c_y);
268
return (delta < quadra);
271
bool T1Line::HitTextShapeArea(TextShape *textShape,
272
PositionType tpos, int x, int y) {
273
List<Point *> *l = GetLine();
274
// for non empty textShape
275
if (textShape->ContainsPt(x, y))
277
// for empty textShape
279
if (tpos == TL || tpos == BL) {
283
if (from->x == to->x) {
285
return False; // vertical case
287
else if (AboveLine(x, y, from, to))
291
if (from->x == to->x) {
295
else if (!AboveLine(x, y, from, to))
300
int len = GetLine()->count();
301
from = (*GetLine())[len-1];
302
to = (*GetLine())[len-2];
304
if (from->x == to->x) {
306
return False; // vertical case
308
else if (AboveLine(x, y, from, to))
312
if (from->x == to->x) {
316
else if (!AboveLine(x, y, from, to))
320
return (HitExtraTextShapeArea(x, y, from, to));