4 #include "linkablemapobj.h"
10 /////////////////////////////////////////////////////////////////
12 /////////////////////////////////////////////////////////////////
15 LinkableMapObj::LinkableMapObj():MapObj()
17 // cout << "Const LinkableMapObj ()\n";
22 LinkableMapObj::LinkableMapObj(QGraphicsScene* s, TreeItem *ti) :MapObj(s,ti)
24 // cout << "Const LinkableMapObj s="<<s<<" ti="<<ti<<" treeItem="<<treeItem<<endl;
28 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
33 LinkableMapObj::~LinkableMapObj()
35 //cout << "Destructor LMO\n";
40 void LinkableMapObj::delLink()
49 while (!segment.isEmpty()) delete segment.takeFirst();
62 void LinkableMapObj::init ()
68 childPos=QPointF(0,0);
72 orientation=UndefinedOrientation;
79 // TODO instead of linkcolor pen.color() could be used all around
81 pen.setColor (linkcolor);
82 pen.setCapStyle ( Qt::RoundCap );
85 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
86 bottomline->setZValue(Z_LINK);
89 topPad=botPad=leftPad=rightPad=0;
91 repositionRequest=false;
98 void LinkableMapObj::copy (LinkableMapObj* other)
101 bboxTotal=other->bboxTotal;
102 setLinkStyle(other->style);
103 setLinkColor (other->linkcolor);
104 relPos=other->relPos;
105 treeItem=other->treeItem;
108 void LinkableMapObj::setParObj(LinkableMapObj* o)
113 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int) // FIXME-3 make pure virtual
117 void LinkableMapObj::unsetParObjTmp() // FIXME-3 make pure virtual
121 bool LinkableMapObj::hasParObjTmp()
126 void LinkableMapObj::setUseRelPos (const bool &b)
131 void LinkableMapObj::setRelPos()
135 relPos.setX (absPos.x() - parObj->getChildPos().x() );
136 relPos.setY (absPos.y() - parObj->getChildPos().y() );
137 parObj->calcBBoxSize();
141 void LinkableMapObj::setRelPos(const QPointF &p)
146 parObj->calcBBoxSize();
151 QPointF LinkableMapObj::getRelPos()
153 if (!parObj) return QPointF();
157 qreal LinkableMapObj::getTopPad()
162 qreal LinkableMapObj::getLeftPad()
167 qreal LinkableMapObj::getRightPad()
172 LinkableMapObj::Style LinkableMapObj::getDefLinkStyle (TreeItem *parent)
174 VymModel *model=treeItem->getModel();
177 qWarning ("LMO::getDefLinkStyle model=NULL");
178 //return UndefinedStyle;
180 Style ls=model->getMapLinkStyle();
181 int depth=1+parent->depth();
182 if (depth==0) return UndefinedStyle;
206 return UndefinedStyle;
209 void LinkableMapObj::setLinkStyle(Style newstyle)
217 QGraphicsLineItem *cl;
224 l = scene->addLine(QLineF(1,1,1,1),pen);
225 l->setZValue(Z_LINK);
232 for (int i=0;i<arcsegs;i++)
234 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
235 cl->setZValue(Z_LINK);
242 pa0.resize (arcsegs+1);
245 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
246 p->setZValue(Z_LINK);
254 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
255 p->setZValue(Z_LINK);
260 pa0.resize (arcsegs*2+2);
261 pa1.resize (arcsegs+1);
262 pa2.resize (arcsegs+1);
270 LinkableMapObj::Style LinkableMapObj::getLinkStyle()
275 void LinkableMapObj::setHideLinkUnselected()
277 setVisibility (visible);
278 updateLinkGeometry();
281 void LinkableMapObj::setLinkPos(Position lp)
286 LinkableMapObj::Position LinkableMapObj::getLinkPos()
291 void LinkableMapObj::setLinkColor()
293 // Overloaded in BranchObj and children
294 // here only set default color
295 VymModel *model=treeItem->getModel();
297 setLinkColor (model->getMapDefLinkColor());
300 void LinkableMapObj::setLinkColor(QColor col)
304 bottomline->setPen( pen );
311 for (int i=0; i<segment.size(); ++i)
312 segment.at(i)->setPen( pen);
315 p->setBrush( QBrush(col));
319 p->setBrush( QBrush(col));
327 QColor LinkableMapObj::getLinkColor()
332 void LinkableMapObj::setVisibility (bool v)
334 MapObj::setVisibility (v);
338 void LinkableMapObj::setOrientation()
340 Orientation orientOld=orientation;
344 orientation=UndefinedOrientation;
348 // Set orientation, first look for orientation of parent
349 if (parObj->getOrientation() != UndefinedOrientation )
350 // use the orientation of the parent:
351 orientation=parObj->getOrientation();
354 // calc orientation depending on position rel to parent
355 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
356 orientation=LeftOfCenter;
358 orientation=RightOfCenter;
360 if (orientOld!=orientation) requestReposition();
363 void LinkableMapObj::updateVisibility()
367 if (((MapItem*)treeItem)->getHideLinkUnselected()
368 && treeItem->getModel()->getSelectedLMO() !=this)
384 for (int i=0; i<segment.size(); ++i)
385 segment.at(i)->show();
388 if (!p) cout << "LMO::updateVis p==0 (PolyLine)\n"; //FIXME-3
392 if (!p) cout << "LMO::updateVis p==0 (PolyParabel) "<<treeItem->getHeading().toStdString()<<endl; //FIXME-3
407 for (int i=0; i<segment.size(); ++i)
408 segment.at(i)->hide();
422 void LinkableMapObj::updateLinkGeometry()
425 // childPos of parent
431 // childPos (by calling setDockPos())
432 // parPos (by calling setDockPos())
434 // drawing of the link itself
436 // updateLinkGeometry is called from move, but called from constructor we don't
437 // have parents yet...
439 //cout <<"LMO::updateLinkGeometry: "<<treeItem->getHeadingStd()<<" "<<parObj<<endl;
442 // If I am a mapcenter, set childPos to middle of MapCenterObj
443 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
444 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
446 // Redraw links to children
447 for (int i=0; i<treeItem->branchCount(); ++i)
448 treeItem->getBranchObjNum(i)->updateLinkGeometry();
452 if (style==UndefinedStyle) return;
457 bottomlineY=bbox.top() + bbox.height()/2; // draw link to middle (of frame)
460 //bottomlineY=bbox.bottom()-1; // draw link to bottom of box
461 bottomlineY=bbox.bottom()-botPad;
465 double p2x,p2y; // Set P2 Before setting
468 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
469 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
472 p2x=QPointF( parObj->getParPos() ).x();
473 p2y=QPointF( parObj->getParPos() ).y();
476 setDockPos(); // Call overloaded method
479 double p1x=parPos.x(); // Link is drawn from P1 to P2
480 double p1y=parPos.y();
482 double vx=p2x - p1x; // V=P2-P1
485 // Draw the horizontal line below heading (from ChildPos to ParPos)
486 bottomline->setLine (QLine (qRound(childPos.x()),
487 qRound(childPos.y()),
492 if (vx > -0.000001 && vx < 0.000001)
496 // "turning point" for drawing polygonal links
497 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
503 l->setLine( QLine(qRound (parPos.x()),
509 parabel (pa0, p1x,p1y,p2x,p2y);
510 for (int i=0; i<segment.size(); ++i)
511 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
515 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
516 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
517 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
518 p->setPolygon(QPolygonF (pa0));
521 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
522 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
524 for (int i=0;i<=arcsegs;i++)
525 pa0 << QPointF (pa1.at(i));
526 for (int i=0;i<=arcsegs;i++)
527 pa0 << QPointF (pa2.at(arcsegs-i));
528 p->setPolygon(QPolygonF (pa0));
535 LinkableMapObj* LinkableMapObj::getParObj()
540 QPointF LinkableMapObj::getChildPos()
545 QPointF LinkableMapObj::getParPos()
550 LinkableMapObj::Orientation LinkableMapObj::getOrientation()
555 QPointF LinkableMapObj::getRandPos()
557 // Choose a random position with given distance to parent:
558 double a=rand()%360 * 2 * M_PI / 360;
559 return QPointF ( (int)( + 150*cos (a)),
560 (int)( + 150*sin (a)));
563 void LinkableMapObj::reposition()
567 void LinkableMapObj::requestReposition() //FIXME-3 needed?
569 if (!repositionRequest)
571 // Pass on the request to parental objects, if this hasn't
573 repositionRequest=true;
574 if (parObj) parObj->requestReposition();
578 void LinkableMapObj::forceReposition()
580 // Sometimes a reposition has to be done immediatly: For example
581 // if the note editor flag changes, there is no user event in mapeditor
582 // which could collect requests for a reposition.
583 // Then we have to call forceReposition()
584 // But no rule without exception: While loading a map or undoing it,
585 // we want to block expensive repositioning, but just do it once at
586 // the end, thus check first:
588 VymModel *model=treeItem->getModel();
589 if (model->isRepositionBlocked()) return;
591 // Pass on the request to parent objects, if this hasn't been done yet
593 parObj->forceReposition();
598 bool LinkableMapObj::repositionRequested()
600 return repositionRequest;
603 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
606 double vx=p2x - p1x; // V=P2-P1
609 double dx; // delta x during calculation of parabel
611 double pnx; // next point
615 if (vx > -0.0001 && vx < 0.0001)
621 ya<<QPointF (p1x,p1y);
622 for (int i=1;i<=arcsegs;i++)
625 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
626 ya<<QPointF (pnx,pny);