4 #include "linkablemapobj.h"
6 #include "mapeditor.h" // FIXME needed?
11 /////////////////////////////////////////////////////////////////
13 /////////////////////////////////////////////////////////////////
15 LinkableMapObj::LinkableMapObj():MapObj()
17 // cout << "Const LinkableMapObj ()\n";
21 LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
23 // cout << "Const LinkableMapObj (s)\n";
27 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
32 LinkableMapObj::~LinkableMapObj()
38 void LinkableMapObj::delLink()
46 while (!segment.isEmpty()) delete segment.takeFirst();
59 void LinkableMapObj::init ()
69 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 );
83 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
84 bottomline->setZValue(Z_LINK);
87 // Prepare showing the selection of a MapObj
90 hideLinkUnselected=false;
92 topPad=botPad=leftPad=rightPad=0;
94 repositionRequest=false;
105 void LinkableMapObj::copy (LinkableMapObj* other)
109 bboxTotal=other->bboxTotal;
110 setLinkStyle(other->style);
111 setLinkColor (other->linkcolor);
112 relPos=other->relPos;
113 useOrientation=other->useOrientation;
117 void LinkableMapObj::setModel (VymModel *vm)
122 VymModel* LinkableMapObj::getModel()
127 void LinkableMapObj::setChildObj(LinkableMapObj* o)
132 void LinkableMapObj::setParObj(LinkableMapObj* o)
135 mapEditor=parObj->getMapEditor();
136 model=parObj->getModel(); // FIXME makes painting slow, but that's obvious because there are no links to paint, hmmm....
139 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int) // FIXME make pure virtual
143 void LinkableMapObj::unsetParObjTmp() // FIXME make pure virtual
147 bool LinkableMapObj::hasParObjTmp()
149 if (parObjTmpBuf) return true;
153 void LinkableMapObj::setUseRelPos (const bool &b)
158 void LinkableMapObj::setRelPos()
162 relPos.setX (absPos.x() - parObj->getChildPos().x() );
163 relPos.setY (absPos.y() - parObj->getChildPos().y() );
164 parObj->calcBBoxSize();
168 void LinkableMapObj::setRelPos(const QPointF &p)
173 parObj->calcBBoxSize();
178 QPointF LinkableMapObj::getRelPos()
180 if (!parObj) return QPointF();
184 qreal LinkableMapObj::getTopPad()
189 qreal LinkableMapObj::getLeftPad()
194 qreal LinkableMapObj::getRightPad()
199 LinkableMapObj::Style LinkableMapObj::getDefLinkStyle ()
203 qWarning ("LMO::getDefLinkStyle model=NULL");
204 return UndefinedStyle;
206 Style ls=model->getMapLinkStyle();
230 return UndefinedStyle;
233 void LinkableMapObj::setLinkStyle(Style newstyle)
235 //if (newstyle=style) return;
240 if (childObj!=NULL && parObj != NULL)
242 QGraphicsLineItem *cl;
249 l = scene->addLine(QLineF(1,1,1,1),pen);
250 l->setZValue(Z_LINK);
257 for (int i=0;i<arcsegs;i++)
259 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
260 cl->setZValue(Z_LINK);
267 pa0.resize (arcsegs+1);
270 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
271 p->setZValue(Z_LINK);
279 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
280 p->setZValue(Z_LINK);
285 pa0.resize (arcsegs*2+2);
286 pa1.resize (arcsegs+1);
287 pa2.resize (arcsegs+1);
295 LinkableMapObj::Style LinkableMapObj::getLinkStyle()
300 void LinkableMapObj::setHideLinkUnselected(bool b)
302 hideLinkUnselected=b;
303 setVisibility (visible);
307 bool LinkableMapObj::getHideLinkUnselected()
309 return hideLinkUnselected;
312 void LinkableMapObj::setLinkPos(Position lp)
317 LinkableMapObj::Position LinkableMapObj::getLinkPos()
322 void LinkableMapObj::setID (const QString &s)
327 QString LinkableMapObj::getID()
332 void LinkableMapObj::setLinkColor()
334 // Overloaded in BranchObj and children
335 // here only set default color
337 setLinkColor (model->getMapDefLinkColor());
340 void LinkableMapObj::setLinkColor(QColor col)
344 bottomline->setPen( pen );
351 for (int i=0; i<segment.size(); ++i)
352 segment.at(i)->setPen( pen);
355 p->setBrush( QBrush(col));
359 p->setBrush( QBrush(col));
367 QColor LinkableMapObj::getLinkColor()
372 void LinkableMapObj::setVisibility (bool v)
374 MapObj::setVisibility (v);
377 // We can hide the link, while object is not selected
378 if (hideLinkUnselected && !selected)
390 for (int i=0; i<segment.size(); ++i)
391 segment.at(i)->show();
411 for (int i=0; i<segment.size(); ++i)
412 segment.at(i)->hide();
426 void LinkableMapObj::setOrientation()
428 Orientation orientOld=orientation;
432 orientation=UndefinedOrientation;
436 // Set orientation, first look for orientation of parent
437 if (parObj->getOrientation() != UndefinedOrientation )
438 // use the orientation of the parent:
439 orientation=parObj->getOrientation();
442 // calc orientation depending on position rel to parent
443 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
444 orientation=LeftOfCenter;
446 orientation=RightOfCenter;
448 if (orientOld!=orientation) requestReposition();
451 void LinkableMapObj::updateLink()
454 // childPos of parent
460 // childPos (by calling setDockPos())
461 // parPos (by calling setDockPos())
463 // drawing of the link itself
465 // updateLink is called from move, but called from constructor we don't
466 // have parents yet...
467 if (style==UndefinedStyle) return;
472 bottomlineY=bbox.top() + bbox.height()/2; // draw link to middle (of frame)
475 bottomlineY=bbox.bottom()-1; // draw link to bottom of box
479 double p2x,p2y; // Set P2 Before setting
482 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
483 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
486 p2x=QPointF( parObj->getParPos() ).x();
487 p2y=QPointF( parObj->getParPos() ).y();
490 setDockPos(); // Call overloaded method
493 double p1x=parPos.x(); // Link is drawn from P1 to P2
494 double p1y=parPos.y();
496 double vx=p2x - p1x; // V=P2-P1
499 // Draw the horizontal line below heading (from ChildPos to ParPos)
500 //bottomline->prepareGeometryChange();
501 bottomline->setLine (QLine (qRound(childPos.x()),
502 qRound(childPos.y()),
507 if (vx > -0.000001 && vx < 0.000001)
511 // "turning point" for drawing polygonal links
512 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
518 //l->prepareGeometryChange();
519 l->setLine( QLine(qRound (parPos.x()),
525 parabel (pa0, p1x,p1y,p2x,p2y);
526 for (int i=0; i<segment.size(); ++i)
528 //segment.at(i)->prepareGeometryChange();
529 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
534 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
535 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
536 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
537 //p->prepareGeometryChange();
538 p->setPolygon(QPolygonF (pa0));
541 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
542 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
544 for (int i=0;i<=arcsegs;i++)
545 pa0 << QPointF (pa1.at(i));
546 for (int i=0;i<=arcsegs;i++)
547 pa0 << QPointF (pa2.at(arcsegs-i));
548 //p->prepareGeometryChange();
549 p->setPolygon(QPolygonF (pa0));
556 LinkableMapObj* LinkableMapObj::getChildObj()
561 LinkableMapObj* LinkableMapObj::getParObj()
566 LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
568 LinkableMapObj *lmo=this;
572 while (!s.isEmpty() )
574 part=s.section(",",0,0);
576 num=part.right(part.length() - 3);
580 return false; // in a subtree there is no center
585 lmo=((BranchObj*)lmo)->getBranchNum (num.toInt());
588 lmo=((BranchObj*)lmo)->getFloatImageNum (num.toUInt());
592 s=s.right(s.length() - part.length() -1 );
599 QPointF LinkableMapObj::getChildPos()
604 QPointF LinkableMapObj::getParPos()
609 void LinkableMapObj::setUseOrientation (const bool &b)
611 if (useOrientation!=b)
618 LinkableMapObj::Orientation LinkableMapObj::getOrientation()
623 int LinkableMapObj::getDepth()
628 void LinkableMapObj::setMapEditor (MapEditor *me)
631 model=mapEditor->getModel();
634 MapEditor* LinkableMapObj::getMapEditor ()
639 QPointF LinkableMapObj::getRandPos()
641 // Choose a random position with given distance to parent:
642 double a=rand()%360 * 2 * M_PI / 360;
643 return QPointF ( (int)( + 150*cos (a)),
644 (int)( + 150*sin (a)));
647 void LinkableMapObj::reposition()
651 void LinkableMapObj::requestReposition()
653 if (!repositionRequest)
655 // Pass on the request to parental objects, if this hasn't
657 repositionRequest=true;
658 if (parObj) parObj->requestReposition();
662 void LinkableMapObj::forceReposition()
664 // Sometimes a reposition has to be done immediatly: For example
665 // if the note editor flag changes, there is no user event in mapeditor
666 // which could collect requests for a reposition.
667 // Then we have to call forceReposition()
668 // But no rule without exception: While loading a map or undoing it,
669 // we want to block expensive repositioning, but just do it once at
670 // the end, thus check first:
672 if (mapEditor->getModel()->isRepositionBlocked()) return; // FIXME better go to model directly, maybe via a signal
674 // Pass on the request to parental objects, if this hasn't been done yet
677 parObj->forceReposition();
682 bool LinkableMapObj::repositionRequested()
684 return repositionRequest;
688 void LinkableMapObj::select()
690 // select and unselect are still needed to
691 // handle hiding of links
693 setVisibility (visible);
697 void LinkableMapObj::unselect()
700 // Maybe we have to hide the link:
701 setVisibility (visible);
704 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
707 double vx=p2x - p1x; // V=P2-P1
710 double dx; // delta x during calculation of parabel
712 double pnx; // next point
716 if (vx > -0.0001 && vx < 0.0001)
722 ya<<QPointF (p1x,p1y);
723 for (int i=1;i<=arcsegs;i++)
726 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
727 ya<<QPointF (pnx,pny);
733 QString LinkableMapObj::getLinkAttr ()
735 if (hideLinkUnselected)
736 return attribut ("hideLink","true");
738 return attribut ("hideLink","false");