linkablemapobj.cpp
author insilmaril
Tue, 08 Sep 2009 12:15:39 +0000
changeset 792 7d67be709091
parent 791 f1006de05c54
child 798 d251c7b2de54
permissions -rw-r--r--
First results in moving colliding MapCenters apart
insilmaril@721
     1
#include <iostream>
insilmaril@139
     2
#include <math.h>
insilmaril@139
     3
insilmaril@0
     4
#include "linkablemapobj.h"
insilmaril@0
     5
#include "branchobj.h"
insilmaril@721
     6
#include "vymmodel.h"
insilmaril@721
     7
insilmaril@721
     8
using namespace std;
insilmaril@0
     9
insilmaril@0
    10
/////////////////////////////////////////////////////////////////
insilmaril@0
    11
// LinkableMapObj
insilmaril@0
    12
/////////////////////////////////////////////////////////////////
insilmaril@0
    13
insilmaril@790
    14
/* FIXME-3
insilmaril@0
    15
LinkableMapObj::LinkableMapObj():MapObj()
insilmaril@0
    16
{
insilmaril@0
    17
  //  cout << "Const LinkableMapObj ()\n";
insilmaril@0
    18
    init ();
insilmaril@0
    19
}
insilmaril@790
    20
*/
insilmaril@0
    21
insilmaril@790
    22
LinkableMapObj::LinkableMapObj(QGraphicsScene* s, TreeItem *ti) :MapObj(s,ti)
insilmaril@0
    23
{
insilmaril@790
    24
//    cout << "Const LinkableMapObj s="<<s<<"  ti="<<ti<<"  treeItem="<<treeItem<<endl;
insilmaril@0
    25
    init ();
insilmaril@0
    26
}
insilmaril@0
    27
insilmaril@408
    28
LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
insilmaril@0
    29
{
insilmaril@0
    30
    copy (lmo);
insilmaril@0
    31
}
insilmaril@0
    32
insilmaril@0
    33
LinkableMapObj::~LinkableMapObj()
insilmaril@0
    34
{
insilmaril@791
    35
	//cout << "Destructor LMO\n";
insilmaril@0
    36
    delete (bottomline);
insilmaril@0
    37
	delLink();
insilmaril@0
    38
}
insilmaril@0
    39
insilmaril@0
    40
void LinkableMapObj::delLink()
insilmaril@0
    41
{
insilmaril@0
    42
	switch (style)
insilmaril@0
    43
	{
insilmaril@473
    44
		case Line:
insilmaril@0
    45
			delete (l);
insilmaril@0
    46
			break;
insilmaril@473
    47
		case Parabel:
insilmaril@406
    48
			while (!segment.isEmpty()) delete segment.takeFirst();
insilmaril@0
    49
			break;
insilmaril@473
    50
		case PolyLine:
insilmaril@0
    51
			delete (p);
insilmaril@0
    52
			break;
insilmaril@473
    53
		case PolyParabel:
insilmaril@0
    54
			delete (p);
insilmaril@0
    55
			break;
insilmaril@0
    56
		default:
insilmaril@0
    57
			break;
insilmaril@0
    58
	}		
insilmaril@0
    59
}
insilmaril@0
    60
insilmaril@0
    61
void LinkableMapObj::init ()
insilmaril@0
    62
{
insilmaril@0
    63
    parObj=NULL;
insilmaril@0
    64
    parObjTmpBuf=NULL;
insilmaril@408
    65
    parPos=QPointF(0,0);
insilmaril@408
    66
    childPos=QPointF(0,0);
insilmaril@0
    67
	link2ParPos=false;
insilmaril@0
    68
    l=NULL;
insilmaril@727
    69
	p=NULL;
insilmaril@473
    70
    orientation=UndefinedOrientation;
insilmaril@0
    71
    linkwidth=20;		
insilmaril@0
    72
	thickness_start=8;
insilmaril@473
    73
    style=UndefinedStyle;
insilmaril@473
    74
	linkpos=Bottom;
insilmaril@0
    75
    arcsegs=13;
insilmaril@0
    76
    
insilmaril@412
    77
// TODO instead of linkcolor pen.color() could be used	all around
insilmaril@408
    78
	pen.setWidth (1);
insilmaril@408
    79
	pen.setColor (linkcolor);
insilmaril@408
    80
	pen.setCapStyle ( Qt::RoundCap );
insilmaril@408
    81
	bottomline=scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
    82
    bottomline->setZValue(Z_LINK);
insilmaril@0
    83
    bottomline->show();
insilmaril@0
    84
insilmaril@175
    85
	topPad=botPad=leftPad=rightPad=0;
insilmaril@175
    86
insilmaril@0
    87
	repositionRequest=false;
insilmaril@218
    88
insilmaril@218
    89
	// Rel Positions
insilmaril@408
    90
	relPos=QPointF(0,0);
insilmaril@250
    91
	useRelPos=false;
insilmaril@0
    92
}
insilmaril@0
    93
insilmaril@0
    94
void LinkableMapObj::copy (LinkableMapObj* other)
insilmaril@0
    95
{
insilmaril@0
    96
    MapObj::copy(other);
insilmaril@0
    97
	bboxTotal=other->bboxTotal;
insilmaril@0
    98
    setLinkStyle(other->style);
insilmaril@0
    99
    setLinkColor (other->linkcolor);
insilmaril@218
   100
	relPos=other->relPos;
insilmaril@726
   101
	treeItem=other->treeItem;
insilmaril@726
   102
}
insilmaril@726
   103
insilmaril@0
   104
void LinkableMapObj::setParObj(LinkableMapObj* o)
insilmaril@0
   105
{
insilmaril@0
   106
    parObj=o;
insilmaril@0
   107
}
insilmaril@0
   108
insilmaril@746
   109
void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)	// FIXME-3 make pure virtual
insilmaril@0
   110
{
insilmaril@0
   111
}
insilmaril@0
   112
insilmaril@746
   113
void LinkableMapObj::unsetParObjTmp()	// FIXME-3 make pure virtual
insilmaril@0
   114
{
insilmaril@0
   115
}
insilmaril@0
   116
insilmaril@164
   117
bool LinkableMapObj::hasParObjTmp()
insilmaril@164
   118
{
insilmaril@164
   119
	if (parObjTmpBuf) return true;
insilmaril@164
   120
	return false;
insilmaril@164
   121
}
insilmaril@164
   122
insilmaril@218
   123
void LinkableMapObj::setUseRelPos (const bool &b)
insilmaril@218
   124
{
insilmaril@218
   125
	useRelPos=b;
insilmaril@218
   126
}
insilmaril@218
   127
insilmaril@218
   128
void LinkableMapObj::setRelPos()
insilmaril@218
   129
{
insilmaril@218
   130
	if (parObj)
insilmaril@218
   131
	{	
insilmaril@395
   132
		relPos.setX (absPos.x() - parObj->getChildPos().x() );
insilmaril@395
   133
		relPos.setY (absPos.y() - parObj->getChildPos().y() );
insilmaril@218
   134
		parObj->calcBBoxSize();
insilmaril@494
   135
	}	
insilmaril@218
   136
}
insilmaril@218
   137
insilmaril@408
   138
void LinkableMapObj::setRelPos(const QPointF &p)
insilmaril@218
   139
{
insilmaril@218
   140
	relPos=p;
insilmaril@218
   141
	if (parObj)
insilmaril@388
   142
	{		
insilmaril@388
   143
		parObj->calcBBoxSize();
insilmaril@388
   144
		requestReposition();
insilmaril@395
   145
	}
insilmaril@218
   146
}
insilmaril@218
   147
insilmaril@408
   148
QPointF LinkableMapObj::getRelPos()
insilmaril@366
   149
{
insilmaril@408
   150
	if (!parObj) return QPointF();
insilmaril@366
   151
	return relPos;
insilmaril@366
   152
}
insilmaril@366
   153
insilmaril@408
   154
qreal LinkableMapObj::getTopPad()
insilmaril@175
   155
{
insilmaril@175
   156
	return topPad;
insilmaril@175
   157
}
insilmaril@175
   158
insilmaril@408
   159
qreal LinkableMapObj::getLeftPad()
insilmaril@175
   160
{
insilmaril@175
   161
	return leftPad;
insilmaril@175
   162
}
insilmaril@175
   163
insilmaril@408
   164
qreal LinkableMapObj::getRightPad()
insilmaril@175
   165
{
insilmaril@175
   166
	return rightPad;
insilmaril@175
   167
}
insilmaril@175
   168
insilmaril@786
   169
LinkableMapObj::Style LinkableMapObj::getDefLinkStyle (TreeItem *parent)
insilmaril@0
   170
{
insilmaril@773
   171
	VymModel *model=treeItem->getModel();
insilmaril@721
   172
	if (!model)
insilmaril@721
   173
	{
insilmaril@721
   174
		qWarning ("LMO::getDefLinkStyle   model=NULL");
insilmaril@727
   175
		//return UndefinedStyle;
insilmaril@721
   176
	}
insilmaril@721
   177
	Style ls=model->getMapLinkStyle();
insilmaril@786
   178
	int depth=1+parent->depth();
insilmaril@727
   179
	if (depth==0) return UndefinedStyle;
insilmaril@0
   180
	switch (ls)
insilmaril@0
   181
	{
insilmaril@473
   182
		case Line: 
insilmaril@0
   183
			return ls;
insilmaril@0
   184
			break;
insilmaril@473
   185
		case Parabel:
insilmaril@0
   186
			return ls;
insilmaril@0
   187
			break;
insilmaril@473
   188
		case PolyLine:	
insilmaril@0
   189
			if (depth>1)
insilmaril@473
   190
				return Line;
insilmaril@0
   191
			else	
insilmaril@0
   192
				return ls;
insilmaril@0
   193
			break;
insilmaril@473
   194
		case PolyParabel:	
insilmaril@0
   195
			if (depth>1)
insilmaril@473
   196
				return Parabel;
insilmaril@0
   197
			else	
insilmaril@0
   198
				return ls;
insilmaril@0
   199
			break;
insilmaril@0
   200
		default: 
insilmaril@0
   201
			break;	
insilmaril@0
   202
	}	
insilmaril@473
   203
	return UndefinedStyle;
insilmaril@0
   204
}
insilmaril@0
   205
insilmaril@473
   206
void LinkableMapObj::setLinkStyle(Style newstyle)
insilmaril@0
   207
{
insilmaril@786
   208
	//if (newstyle==style) return; FIXME-3
insilmaril@0
   209
	delLink();
insilmaril@0
   210
		
insilmaril@0
   211
	style=newstyle;
insilmaril@0
   212
insilmaril@773
   213
    if (parObj != NULL)
insilmaril@0
   214
    {
insilmaril@408
   215
		QGraphicsLineItem *cl;
insilmaril@0
   216
		switch (style)
insilmaril@0
   217
		{
insilmaril@473
   218
			case UndefinedStyle:
insilmaril@0
   219
				bottomline->hide();
insilmaril@0
   220
				break;
insilmaril@473
   221
			case Line: 
insilmaril@408
   222
				l = scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
   223
				l->setZValue(Z_LINK);
insilmaril@0
   224
				if (visible)
insilmaril@0
   225
					l->show();
insilmaril@0
   226
				else
insilmaril@0
   227
					l->hide();
insilmaril@0
   228
				break;
insilmaril@473
   229
			case Parabel:
insilmaril@408
   230
				for (int i=0;i<arcsegs;i++)
insilmaril@0
   231
				{
insilmaril@408
   232
					cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
insilmaril@408
   233
					cl->setZValue(Z_LINK);
insilmaril@0
   234
					if (visible)
insilmaril@0
   235
						cl->show();
insilmaril@0
   236
					else
insilmaril@0
   237
						cl->hide();
insilmaril@0
   238
					segment.append(cl);
insilmaril@0
   239
				}
insilmaril@0
   240
				pa0.resize (arcsegs+1);
insilmaril@0
   241
				break;
insilmaril@473
   242
			case PolyLine:	
insilmaril@408
   243
				p =scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   244
				p->setZValue(Z_LINK);
insilmaril@0
   245
				if (visible)
insilmaril@0
   246
					p->show();
insilmaril@0
   247
				else
insilmaril@0
   248
					p->hide();
insilmaril@0
   249
				pa0.resize (3);
insilmaril@0
   250
				break;
insilmaril@473
   251
			case PolyParabel:	
insilmaril@408
   252
				p = scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   253
				p->setZValue(Z_LINK);
insilmaril@0
   254
				if (visible)
insilmaril@0
   255
					p->show();
insilmaril@0
   256
				else
insilmaril@0
   257
					p->hide();
insilmaril@0
   258
				pa0.resize (arcsegs*2+2);
insilmaril@0
   259
				pa1.resize (arcsegs+1);
insilmaril@0
   260
				pa2.resize (arcsegs+1);
insilmaril@0
   261
				break;
insilmaril@0
   262
			default: 
insilmaril@0
   263
				break;	
insilmaril@0
   264
		}	
insilmaril@164
   265
	} 
insilmaril@0
   266
}
insilmaril@0
   267
insilmaril@473
   268
LinkableMapObj::Style LinkableMapObj::getLinkStyle()
insilmaril@0
   269
{
insilmaril@0
   270
	return style;
insilmaril@0
   271
}
insilmaril@0
   272
insilmaril@779
   273
void LinkableMapObj::setHideLinkUnselected()
insilmaril@160
   274
{
insilmaril@160
   275
	setVisibility (visible);
insilmaril@779
   276
	updateLinkGeometry();
insilmaril@160
   277
}
insilmaril@160
   278
insilmaril@473
   279
void LinkableMapObj::setLinkPos(Position lp)
insilmaril@0
   280
{
insilmaril@0
   281
	linkpos=lp;
insilmaril@0
   282
}
insilmaril@0
   283
insilmaril@473
   284
LinkableMapObj::Position LinkableMapObj::getLinkPos()
insilmaril@0
   285
{
insilmaril@0
   286
	return linkpos;
insilmaril@0
   287
}
insilmaril@0
   288
insilmaril@0
   289
void LinkableMapObj::setLinkColor()
insilmaril@0
   290
{
insilmaril@721
   291
	// Overloaded in BranchObj and children
insilmaril@0
   292
	// here only set default color
insilmaril@773
   293
	VymModel *model=treeItem->getModel();
insilmaril@721
   294
	if (model)
insilmaril@721
   295
		setLinkColor (model->getMapDefLinkColor());
insilmaril@0
   296
}
insilmaril@0
   297
insilmaril@0
   298
void LinkableMapObj::setLinkColor(QColor col)
insilmaril@0
   299
{
insilmaril@0
   300
	linkcolor=col;
insilmaril@408
   301
	pen.setColor(col);
insilmaril@408
   302
    bottomline->setPen( pen );
insilmaril@0
   303
	switch (style)
insilmaril@0
   304
	{
insilmaril@473
   305
		case Line:
insilmaril@408
   306
			l->setPen( pen);
insilmaril@0
   307
			break;	
insilmaril@473
   308
		case Parabel:	
insilmaril@406
   309
			for (int i=0; i<segment.size(); ++i)
insilmaril@408
   310
				segment.at(i)->setPen( pen);
insilmaril@0
   311
			break;
insilmaril@473
   312
		case PolyLine:
insilmaril@0
   313
			p->setBrush( QBrush(col));
insilmaril@497
   314
			p->setPen( pen);
insilmaril@0
   315
			break;
insilmaril@473
   316
		case PolyParabel:	
insilmaril@0
   317
			p->setBrush( QBrush(col));
insilmaril@497
   318
			p->setPen( pen);
insilmaril@0
   319
			break;
insilmaril@0
   320
		default:
insilmaril@0
   321
			break;
insilmaril@755
   322
	} 
insilmaril@0
   323
}
insilmaril@0
   324
insilmaril@0
   325
QColor LinkableMapObj::getLinkColor()
insilmaril@0
   326
{
insilmaril@0
   327
	return linkcolor;
insilmaril@0
   328
}
insilmaril@0
   329
insilmaril@0
   330
void LinkableMapObj::setVisibility (bool v)
insilmaril@0
   331
{
insilmaril@0
   332
	MapObj::setVisibility (v);
insilmaril@779
   333
	updateVisibility();
insilmaril@779
   334
}
insilmaril@779
   335
insilmaril@779
   336
void LinkableMapObj::setOrientation()
insilmaril@779
   337
{
insilmaril@779
   338
	Orientation orientOld=orientation;
insilmaril@779
   339
insilmaril@779
   340
	if (!parObj) 
insilmaril@779
   341
	{
insilmaril@779
   342
		orientation=UndefinedOrientation;
insilmaril@779
   343
		return;
insilmaril@779
   344
	}
insilmaril@779
   345
		
insilmaril@779
   346
    // Set orientation, first look for orientation of parent
insilmaril@779
   347
    if (parObj->getOrientation() != UndefinedOrientation ) 
insilmaril@779
   348
		// use the orientation of the parent:
insilmaril@779
   349
		orientation=parObj->getOrientation();
insilmaril@779
   350
    else
insilmaril@779
   351
    {
insilmaril@779
   352
		// calc orientation depending on position rel to parent
insilmaril@779
   353
		if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
insilmaril@779
   354
			orientation=LeftOfCenter; 
insilmaril@779
   355
		else
insilmaril@779
   356
			orientation=RightOfCenter;
insilmaril@779
   357
    }
insilmaril@779
   358
	if (orientOld!=orientation) requestReposition();
insilmaril@779
   359
}
insilmaril@779
   360
insilmaril@779
   361
void LinkableMapObj::updateVisibility()
insilmaril@779
   362
{
insilmaril@160
   363
	bool visnow=visible;
insilmaril@260
   364
insilmaril@779
   365
	if (((MapItem*)treeItem)->getHideLinkUnselected()
insilmaril@779
   366
		&& treeItem->getModel()->getSelectedLMO() !=this)
insilmaril@160
   367
		visnow=false;
insilmaril@160
   368
insilmaril@160
   369
	if (visnow) 
insilmaril@0
   370
	{
insilmaril@0
   371
		bottomline->show();
insilmaril@160
   372
		switch (style)
insilmaril@0
   373
		{
insilmaril@473
   374
			case Line:
insilmaril@160
   375
				if (l) l->show();
insilmaril@160
   376
				break;
insilmaril@473
   377
			case Parabel:	
insilmaril@406
   378
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   379
					segment.at(i)->show();
insilmaril@160
   380
				break;	
insilmaril@473
   381
			case PolyLine:
insilmaril@779
   382
				if (!p) cout << "LMO::updateVis p==0 (PolyLine)\n"; //FIXME-3
insilmaril@160
   383
				if (p) p->show();
insilmaril@160
   384
				break;
insilmaril@473
   385
			case PolyParabel:	
insilmaril@779
   386
				if (!p) cout << "LMO::updateVis p==0 (PolyParabel) "<<treeItem->getHeading().toStdString()<<endl; //FIXME-3
insilmaril@160
   387
				if (p) p->show();
insilmaril@160
   388
				break;
insilmaril@160
   389
			default:
insilmaril@160
   390
				break;
insilmaril@160
   391
		}
insilmaril@0
   392
	} else 
insilmaril@0
   393
	{
insilmaril@0
   394
		bottomline->hide();
insilmaril@160
   395
		switch (style)
insilmaril@0
   396
		{
insilmaril@473
   397
			case Line:
insilmaril@160
   398
				if (l) l->hide();
insilmaril@160
   399
				break;
insilmaril@473
   400
			case Parabel:	
insilmaril@406
   401
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   402
					segment.at(i)->hide();
insilmaril@160
   403
				break;	
insilmaril@473
   404
			case PolyLine:
insilmaril@160
   405
				if (p) p->hide();
insilmaril@160
   406
				break;
insilmaril@473
   407
			case PolyParabel:	
insilmaril@160
   408
				if (p) p->hide();
insilmaril@160
   409
				break;
insilmaril@160
   410
			default:
insilmaril@160
   411
				break;
insilmaril@160
   412
		}
insilmaril@0
   413
	}	
insilmaril@0
   414
}
insilmaril@0
   415
insilmaril@779
   416
void LinkableMapObj::updateLinkGeometry()
insilmaril@0
   417
{
insilmaril@0
   418
    // needs:
insilmaril@0
   419
    //	childPos of parent
insilmaril@0
   420
    //	orient   of parent
insilmaril@0
   421
    //	style
insilmaril@0
   422
    // 
insilmaril@0
   423
    // sets:
insilmaril@0
   424
    //	orientation
insilmaril@225
   425
    //	childPos	(by calling setDockPos())
insilmaril@225
   426
    //	parPos		(by calling setDockPos())
insilmaril@175
   427
	//  bottomlineY
insilmaril@0
   428
    //	drawing of the link itself
insilmaril@0
   429
insilmaril@779
   430
	// updateLinkGeometry is called from move, but called from constructor we don't
insilmaril@0
   431
	// have parents yet...
insilmaril@775
   432
insilmaril@785
   433
//cout <<"LMO::updateLinkGeometry: "<<treeItem->getHeadingStd()<<"  "<<parObj<<endl;
insilmaril@775
   434
	if (!parObj)	
insilmaril@775
   435
	{
insilmaril@775
   436
		// If I am a mapcenter, set childPos to middle of MapCenterObj
insilmaril@775
   437
		childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
insilmaril@775
   438
		childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
insilmaril@775
   439
		parPos=childPos;		
insilmaril@775
   440
		// Redraw links to children
insilmaril@775
   441
		for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@779
   442
			treeItem->getBranchObjNum(i)->updateLinkGeometry();
insilmaril@775
   443
		return;	
insilmaril@775
   444
	}
insilmaril@775
   445
insilmaril@473
   446
	if (style==UndefinedStyle) return;	
insilmaril@0
   447
insilmaril@0
   448
	switch (linkpos)
insilmaril@0
   449
	{
insilmaril@473
   450
		case Middle:
insilmaril@442
   451
			bottomlineY=bbox.top() + bbox.height()/2;	// draw link to middle (of frame)
insilmaril@0
   452
			break;
insilmaril@473
   453
		case Bottom:
insilmaril@785
   454
			//bottomlineY=bbox.bottom()-1;	// draw link to bottom of box
insilmaril@785
   455
			bottomlineY=bbox.bottom()-botPad;
insilmaril@0
   456
			break;
insilmaril@0
   457
	}
insilmaril@0
   458
	
insilmaril@0
   459
    double p2x,p2y;								// Set P2 Before setting
insilmaril@0
   460
	if (!link2ParPos)
insilmaril@0
   461
	{
insilmaril@408
   462
		p2x=QPointF( parObj->getChildPos() ).x();	// P1, we have to look at
insilmaril@408
   463
		p2y=QPointF( parObj->getChildPos() ).y();	// orientation
insilmaril@0
   464
	} else	
insilmaril@0
   465
	{
insilmaril@408
   466
		p2x=QPointF( parObj->getParPos() ).x();	
insilmaril@408
   467
		p2y=QPointF( parObj->getParPos() ).y();
insilmaril@0
   468
	} 
insilmaril@0
   469
insilmaril@388
   470
	setDockPos(); // Call overloaded method
insilmaril@393
   471
	setOrientation();
insilmaril@0
   472
insilmaril@0
   473
	double p1x=parPos.x();	// Link is drawn from P1 to P2
insilmaril@0
   474
	double p1y=parPos.y();
insilmaril@0
   475
insilmaril@0
   476
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   477
	double vy=p2y - p1y;
insilmaril@0
   478
insilmaril@0
   479
	// Draw the horizontal line below heading (from ChildPos to ParPos)
insilmaril@427
   480
	//bottomline->prepareGeometryChange();
insilmaril@408
   481
	bottomline->setLine (QLine (qRound(childPos.x()),
insilmaril@104
   482
		qRound(childPos.y()),
insilmaril@104
   483
		qRound(p1x),
insilmaril@408
   484
		qRound(p1y) ));
insilmaril@0
   485
insilmaril@0
   486
	double a;	// angle
insilmaril@0
   487
	if (vx > -0.000001 && vx < 0.000001)
insilmaril@0
   488
		a=M_PI_2;
insilmaril@0
   489
	else
insilmaril@0
   490
		a=atan( vy / vx );
insilmaril@0
   491
	// "turning point" for drawing polygonal links
insilmaril@408
   492
	QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));	
insilmaril@0
   493
	
insilmaril@0
   494
    // Draw the link
insilmaril@0
   495
	switch (style)
insilmaril@0
   496
	{
insilmaril@473
   497
		case Line:
insilmaril@408
   498
			l->setLine( QLine(qRound (parPos.x()),
insilmaril@104
   499
				qRound(parPos.y()),
insilmaril@104
   500
				qRound(p2x),
insilmaril@408
   501
				qRound(p2y) ));
insilmaril@0
   502
			break;	
insilmaril@473
   503
		case Parabel:	
insilmaril@0
   504
			parabel (pa0, p1x,p1y,p2x,p2y);
insilmaril@406
   505
			for (int i=0; i<segment.size(); ++i)
insilmaril@408
   506
				segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
insilmaril@0
   507
			break;
insilmaril@473
   508
		case PolyLine:
insilmaril@408
   509
			pa0.clear();
insilmaril@408
   510
			pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
insilmaril@408
   511
			pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
insilmaril@408
   512
			pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
insilmaril@408
   513
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   514
			break;
insilmaril@473
   515
		case PolyParabel:	
insilmaril@0
   516
			parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
insilmaril@0
   517
			parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
insilmaril@408
   518
			pa0.clear();
insilmaril@406
   519
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   520
				pa0 << QPointF (pa1.at(i));
insilmaril@408
   521
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   522
				pa0 << QPointF (pa2.at(arcsegs-i));
insilmaril@408
   523
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   524
			break;
insilmaril@0
   525
		default:
insilmaril@0
   526
			break;
insilmaril@779
   527
	} 
insilmaril@0
   528
}
insilmaril@0
   529
	
insilmaril@0
   530
LinkableMapObj* LinkableMapObj::getParObj()
insilmaril@0
   531
{
insilmaril@0
   532
    return parObj;
insilmaril@0
   533
}
insilmaril@0
   534
insilmaril@408
   535
QPointF LinkableMapObj::getChildPos()
insilmaril@0
   536
{
insilmaril@0
   537
    return childPos;
insilmaril@0
   538
}
insilmaril@0
   539
insilmaril@408
   540
QPointF LinkableMapObj::getParPos()
insilmaril@0
   541
{
insilmaril@0
   542
    return parPos;
insilmaril@0
   543
}
insilmaril@0
   544
insilmaril@473
   545
LinkableMapObj::Orientation LinkableMapObj::getOrientation()
insilmaril@0
   546
{
insilmaril@0
   547
    return orientation;
insilmaril@0
   548
}
insilmaril@0
   549
insilmaril@408
   550
QPointF LinkableMapObj::getRandPos()
insilmaril@0
   551
{
insilmaril@0
   552
	// Choose a random position with given distance to parent:
insilmaril@0
   553
	double a=rand()%360 * 2 * M_PI / 360;
insilmaril@408
   554
    return QPointF ( (int)( + 150*cos (a)),
insilmaril@0
   555
                    (int)( + 150*sin (a)));
insilmaril@0
   556
}
insilmaril@0
   557
insilmaril@0
   558
void LinkableMapObj::reposition()
insilmaril@0
   559
{
insilmaril@0
   560
}
insilmaril@0
   561
insilmaril@785
   562
void LinkableMapObj::requestReposition()	//FIXME-3 needed?
insilmaril@0
   563
{
insilmaril@0
   564
	if (!repositionRequest)
insilmaril@0
   565
	{
insilmaril@0
   566
		// Pass on the request to parental objects, if this hasn't
insilmaril@0
   567
		// been done yet
insilmaril@0
   568
		repositionRequest=true;
insilmaril@0
   569
		if (parObj) parObj->requestReposition();
insilmaril@0
   570
	}
insilmaril@0
   571
}
insilmaril@0
   572
insilmaril@0
   573
void LinkableMapObj::forceReposition()
insilmaril@0
   574
{
insilmaril@0
   575
	// Sometimes a reposition has to be done immediatly: For example
insilmaril@0
   576
	// if the note editor flag changes, there is no user event in mapeditor
insilmaril@0
   577
	// which could collect requests for a reposition.
insilmaril@0
   578
	// Then we have to call forceReposition()
insilmaril@0
   579
	// But no rule without exception: While loading a map or undoing it,
insilmaril@0
   580
	// we want to block expensive repositioning, but just do it once at
insilmaril@0
   581
	// the end, thus check first:
insilmaril@0
   582
insilmaril@773
   583
	VymModel *model=treeItem->getModel();
insilmaril@724
   584
	if (model->isRepositionBlocked()) return;	
insilmaril@0
   585
	
insilmaril@724
   586
	// Pass on the request to parent objects, if this hasn't been done yet
insilmaril@0
   587
	if (parObj) 
insilmaril@0
   588
		parObj->forceReposition(); 
insilmaril@0
   589
	else 
insilmaril@83
   590
		reposition(); 
insilmaril@83
   591
}
insilmaril@0
   592
insilmaril@0
   593
bool LinkableMapObj::repositionRequested()
insilmaril@0
   594
{
insilmaril@0
   595
	return repositionRequest;
insilmaril@0
   596
}
insilmaril@0
   597
insilmaril@408
   598
void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
insilmaril@0
   599
insilmaril@0
   600
{
insilmaril@0
   601
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   602
	double vy=p2y - p1y;
insilmaril@0
   603
insilmaril@0
   604
	double dx;				// delta x during calculation of parabel
insilmaril@0
   605
	
insilmaril@0
   606
	double pnx;				// next point
insilmaril@0
   607
	double pny;
insilmaril@0
   608
	double m;
insilmaril@0
   609
insilmaril@0
   610
	if (vx > -0.0001 && vx < 0.0001)
insilmaril@0
   611
		m=0;
insilmaril@0
   612
	else	
insilmaril@0
   613
		m=(vy / (vx*vx));
insilmaril@0
   614
	dx=vx/(arcsegs);
insilmaril@408
   615
	ya.clear();
insilmaril@579
   616
	ya<<QPointF (p1x,p1y);
insilmaril@408
   617
	for (int i=1;i<=arcsegs;i++)
insilmaril@0
   618
	{	
insilmaril@0
   619
		pnx=p1x+dx;
insilmaril@0
   620
		pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
insilmaril@579
   621
		ya<<QPointF (pnx,pny);
insilmaril@0
   622
		p1x=pnx;
insilmaril@0
   623
		p1y=pny;
insilmaril@0
   624
	}	
insilmaril@0
   625
}
insilmaril@0
   626