3 #include "linkablemapobj.h"
7 /////////////////////////////////////////////////////////////////
9 /////////////////////////////////////////////////////////////////
11 LinkableMapObj::LinkableMapObj():MapObj()
13 // cout << "Const LinkableMapObj ()\n";
17 LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
19 // cout << "Const LinkableMapObj (s)\n";
23 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
28 LinkableMapObj::~LinkableMapObj()
36 void LinkableMapObj::delLink()
44 while (!segment.isEmpty()) delete segment.takeFirst();
49 case StylePolyParabel:
57 void LinkableMapObj::init ()
65 childPos=QPointF(0,0);
68 orientation=OrientUndef;
75 // TODO instead of linkcolor pen.color() could be used all around
77 pen.setColor (linkcolor);
78 pen.setCapStyle ( Qt::RoundCap );
79 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
80 bottomline->setZValue(Z_LINK);
83 // Prepare showing the selection of a MapObj
84 selbox = scene->addRect(QRectF(0,0,0,0), QPen(QColor(255,255,0) ), QColor(255,255,0));
85 selbox->setZValue(Z_SELBOX);
89 hideLinkUnselected=false;
91 topPad=botPad=leftPad=rightPad=0;
94 frame = new FrameObj (scene);
96 repositionRequest=false;
104 void LinkableMapObj::copy (LinkableMapObj* other)
107 bboxTotal=other->bboxTotal;
108 setLinkStyle(other->style);
109 setLinkColor (other->linkcolor);
110 relPos=other->relPos;
111 useOrientation=other->useOrientation;
115 void LinkableMapObj::setChildObj(LinkableMapObj* o)
120 void LinkableMapObj::setParObj(LinkableMapObj* o)
123 mapEditor=parObj->getMapEditor();
126 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)
130 void LinkableMapObj::unsetParObjTmp()
134 bool LinkableMapObj::hasParObjTmp()
136 if (parObjTmpBuf) return true;
140 void LinkableMapObj::setUseRelPos (const bool &b)
145 void LinkableMapObj::setRelPos()
149 relPos.setX (absPos.x() - parObj->getChildPos().x() );
150 relPos.setY (absPos.y() - parObj->getChildPos().y() );
151 parObj->calcBBoxSize();
154 qWarning ("LMO::setRelPos No parent yet!");
158 void LinkableMapObj::setRelPos(const QPointF &p)
163 parObj->calcBBoxSize();
167 qWarning ("LMO::setRelPos No parent yet!");
171 QPointF LinkableMapObj::getRelPos()
173 if (!parObj) return QPointF();
177 qreal LinkableMapObj::getTopPad()
182 qreal LinkableMapObj::getLeftPad()
187 qreal LinkableMapObj::getRightPad()
192 LinkStyle LinkableMapObj::getDefLinkStyle ()
194 if (mapEditor==0) return StyleUndef;
195 LinkStyle ls=mapEditor->getMapLinkStyle();
210 case StylePolyParabel:
222 void LinkableMapObj::setLinkStyle(LinkStyle newstyle)
224 //if (newstyle=style) return;
229 if (childObj!=NULL && parObj != NULL)
231 QGraphicsLineItem *cl;
238 l = scene->addLine(QLineF(1,1,1,1),pen);
239 l->setZValue(Z_LINK);
246 for (int i=0;i<arcsegs;i++)
248 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
249 cl->setZValue(Z_LINK);
256 pa0.resize (arcsegs+1);
259 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
260 p->setZValue(Z_LINK);
267 case StylePolyParabel:
268 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
269 p->setZValue(Z_LINK);
274 pa0.resize (arcsegs*2+2);
275 pa1.resize (arcsegs+1);
276 pa2.resize (arcsegs+1);
284 LinkStyle LinkableMapObj::getLinkStyle()
289 void LinkableMapObj::setHideLinkUnselected(bool b)
291 hideLinkUnselected=b;
292 setVisibility (visible);
296 bool LinkableMapObj::getHideLinkUnselected()
298 return hideLinkUnselected;
301 void LinkableMapObj::setLinkPos(LinkPos lp)
306 LinkPos LinkableMapObj::getLinkPos()
312 void LinkableMapObj::setLinkColor()
314 // Overloaded in BranchObj and childs
315 // here only set default color
317 setLinkColor (mapEditor->getMapDefLinkColor());
320 void LinkableMapObj::setLinkColor(QColor col)
324 bottomline->setPen( pen );
331 for (int i=0; i<segment.size(); ++i)
332 segment.at(i)->setPen( pen);
335 p->setBrush( QBrush(col));
337 case StylePolyParabel:
338 p->setBrush( QBrush(col));
345 QColor LinkableMapObj::getLinkColor()
350 FrameType LinkableMapObj::getFrameType()
352 return frame->getFrameType();
355 void LinkableMapObj::setFrameType(const FrameType &t)
357 frame->setFrameType(t);
363 void LinkableMapObj::setFrameType(const QString &t)
365 frame->setFrameType(t);
371 void LinkableMapObj::setVisibility (bool v)
373 MapObj::setVisibility (v);
376 // We can hide the link, while object is not selected
377 if (hideLinkUnselected && !selected)
389 for (int i=0; i<segment.size(); ++i)
390 segment.at(i)->show();
395 case StylePolyParabel:
410 for (int i=0; i<segment.size(); ++i)
411 segment.at(i)->hide();
416 case StylePolyParabel:
425 void LinkableMapObj::setOrientation()
427 LinkOrient orientOld=orientation;
431 orientation=OrientUndef;
435 // Set orientation, first look for orientation of parent
436 if (parObj->getOrientation() != OrientUndef )
437 // use the orientation of the parent:
438 orientation=parObj->getOrientation();
441 // calc orientation depending on position rel to parent
442 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
443 orientation=OrientLeftOfCenter;
445 orientation=OrientRightOfCenter;
447 if (orientOld!=orientation) requestReposition();
450 void LinkableMapObj::updateLink()
453 // childPos of parent
459 // childPos (by calling setDockPos())
460 // parPos (by calling setDockPos())
462 // drawing of the link itself
464 // updateLink is called from move, but called from constructor we don't
465 // have parents yet...
466 if (style==StyleUndef) return;
468 if (frame->getFrameType() == NoFrame)
475 bottomlineY=bbox.top()+bbox.height() /2; // draw link to middle (of frame)
478 bottomlineY=bbox.bottom()-1; // draw link to bottom of box
482 double p2x,p2y; // Set P2 Before setting
485 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
486 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
489 p2x=QPointF( parObj->getParPos() ).x();
490 p2y=QPointF( parObj->getParPos() ).y();
493 setDockPos(); // Call overloaded method
496 double p1x=parPos.x(); // Link is drawn from P1 to P2
497 double p1y=parPos.y();
499 double vx=p2x - p1x; // V=P2-P1
502 // Draw the horizontal line below heading (from ChildPos to ParPos)
503 bottomline->setLine (QLine (qRound(childPos.x()),
504 qRound(childPos.y()),
509 if (vx > -0.000001 && vx < 0.000001)
513 // "turning point" for drawing polygonal links
514 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
520 l->setLine( QLine(qRound (parPos.x()),
526 parabel (pa0, p1x,p1y,p2x,p2y);
527 for (int i=0; i<segment.size(); ++i)
528 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
532 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
533 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
534 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
535 p->setPolygon(QPolygonF (pa0));
537 case StylePolyParabel:
538 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
539 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
541 for (int i=0;i<=arcsegs;i++)
542 pa0 << QPointF (pa1.at(i));
543 for (int i=0;i<=arcsegs;i++)
544 pa0 << QPointF (pa2.at(arcsegs-i));
545 p->setPolygon(QPolygonF (pa0));
552 LinkableMapObj* LinkableMapObj::getChildObj()
557 LinkableMapObj* LinkableMapObj::getParObj()
562 LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
564 LinkableMapObj *lmo=this;
568 while (!s.isEmpty() )
570 part=s.section(",",0,0);
572 num=part.right(part.length() - 3);
576 return false; // in a subtree there is no center
581 lmo=((BranchObj*)(lmo))->getBranchNum (num.toInt());
584 lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
588 s=s.right(s.length() - part.length() -1 );
595 QPointF LinkableMapObj::getChildPos()
600 QPointF LinkableMapObj::getParPos()
605 void LinkableMapObj::setUseOrientation (const bool &b)
607 if (useOrientation!=b)
614 LinkOrient LinkableMapObj::getOrientation()
619 int LinkableMapObj::getDepth()
624 void LinkableMapObj::setMapEditor (MapEditor *me)
629 MapEditor* LinkableMapObj::getMapEditor ()
634 QPointF LinkableMapObj::getRandPos()
636 // Choose a random position with given distance to parent:
637 double a=rand()%360 * 2 * M_PI / 360;
638 return QPointF ( (int)( + 150*cos (a)),
639 (int)( + 150*sin (a)));
642 void LinkableMapObj::reposition()
646 void LinkableMapObj::requestReposition()
648 if (!repositionRequest)
650 // Pass on the request to parental objects, if this hasn't
652 repositionRequest=true;
653 if (parObj) parObj->requestReposition();
657 void LinkableMapObj::forceReposition()
659 // Sometimes a reposition has to be done immediatly: For example
660 // if the note editor flag changes, there is no user event in mapeditor
661 // which could collect requests for a reposition.
662 // Then we have to call forceReposition()
663 // But no rule without exception: While loading a map or undoing it,
664 // we want to block expensive repositioning, but just do it once at
665 // the end, thus check first:
667 if (mapEditor->isRepositionBlocked()) return;
669 // Pass on the request to parental objects, if this hasn't been done yet
672 parObj->forceReposition();
677 bool LinkableMapObj::repositionRequested()
679 return repositionRequest;
683 void LinkableMapObj::setSelBox()
685 selbox->setRect (clickBox);
688 void LinkableMapObj::select()
693 setVisibility (visible);
697 void LinkableMapObj::unselect()
701 // Maybe we have to hide the link:
702 setVisibility (visible);
705 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
708 double vx=p2x - p1x; // V=P2-P1
711 double dx; // delta x during calculation of parabel
713 double pnx; // next point
717 if (vx > -0.0001 && vx < 0.0001)
723 ya<<QPointF (qRound(p1x),qRound(p1y));
724 for (int i=1;i<=arcsegs;i++)
727 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
728 ya<<QPointF (qRound(pnx),qRound(pny));
734 QString LinkableMapObj::getLinkAttr ()
736 if (hideLinkUnselected)
737 return attribut ("hideLink","true");
739 return attribut ("hideLink","false");