/* area.cc */ #include #include #include "area.hpp" #include "area.ipp" #include "palette.h" // FieldPaletteItem #include #include #if QT_VERSION >= 0x040400 #define QT_4_4 #endif #if QT_VERSION >= 0x040600 #define QT_4_6 #endif /* ---------------------------------------------------------------------- */ void Area::initialize () { setRect (0, 0, 100, 100); setFlag (QGraphicsItem::ItemIsMovable); setFlag (QGraphicsItem::ItemIsSelectable); #ifdef QT_4_6 // setFlag (QGraphicsItem::ItemIsPanel); setFlag (QGraphicsItem::ItemSendsScenePositionChanges); #endif // setPen (QPen (Qt::blue)); // setBrush (QBrush (Qt::yellow)); setAcceptDrops (true); } void Area::initializeTopLevel () { setPen (QPen (Qt::NoPen)); setBrush (QBrush (Qt::NoBrush)); setFlags (0); } void Area::connected () { Area * above = getAboveArea (); if (above != NULL) { setParentItem (above); /* Source * source = getFirstSource (); while (source != NULL) { source->connected (); source = source->getNextSource (); } Target * target = getFirstTarget (); while (target != NULL) { target->connected (); target = target->getNextSource (); } */ } } void Area::disconnected () { // scene = NULL; // setScene (scene); } /* ---------------------------------------------------------------------- */ void Source::initialize () { setRect (0, 0, 10, 10); setPen (QPen (Qt::red)); setBrush (QBrush (Qt::green)); setFlag (QGraphicsItem::ItemIsMovable); // !? setFlag (QGraphicsItem::ItemIsSelectable); // !? } void Source::connected () { setParentItem (getArea ()); } void Source::disconnected () { } /* ---------------------------------------------------------------------- */ void Target::initialize () { setRect (0, 0, 10, 10); setPen (QPen (Qt::red)); setBrush (QBrush (Qt::yellow)); setFlag (QGraphicsItem::ItemIsMovable); // !? setFlag (QGraphicsItem::ItemIsSelectable); // !? } void Target::connected () { setParentItem (getArea ()); } void Target::disconnected () { } /* ---------------------------------------------------------------------- */ void Connection::initialize () { group = NULL; } void Connection::connected () { // setParentItem (getSource ()); } void Connection::disconnected () { } /* ---------------------------------------------------------------------- */ void Connection::addLine (qreal x2, qreal y2) { if (x1 != x2 || y1 != y2) { QGraphicsLineItem * line = new QGraphicsLineItem; line->setLine (x1, y1, x2, y2); // line->setPen (QPen (Qt::red)); line->setPen (pen); line->setParentItem (group); x1 = x2; y1 = y2; } } void Connection::horizLine (qreal x2) { addLine (x2, y1); } void Connection::vertLine (qreal y2) { addLine (x1, y2); } void Connection::updateConnection () { Source * source = this->getSource (); Target * target = this->getTarget (); // delete previous group if (group != NULL) { delete group; group = NULL; } // create new group group = new QGraphicsItemGroup; #ifdef QT_4_6 group->setFlag (QGraphicsItem::ItemHasNoContents); #endif QPointF pt1 = source->mapToScene (source->rect().center ()); QPointF pt2 = target->mapToScene (target->rect().center ()); // pt1 = source->mapFromScene (pt1); // pt2 = source->mapFromScene (pt2); Area * a1 = source->getArea (); QRectF r1 = a1->rect(); QPointF tr1 = a1->mapToScene (r1.topRight()); QPointF br1 = a1->mapToScene (r1.bottomRight()); qreal src_right = tr1.x(); qreal src_top = tr1.y(); qreal src_bottom = br1.y(); Area * a2 = target->getArea (); QRectF r2 = a2->rect(); QPointF tr2 =a2->mapToScene (r2.topRight()); QPointF br2 = a2->mapToScene (r2.bottomRight()); qreal tgt_right = tr2.x(); qreal tgt_top = tr2.y(); qreal tgt_bottom = br2.y(); this->x1 = pt1.x(); this->y1 = pt1.y(); qreal x2 = pt2.x(); qreal y2 = pt2.y(); pen = QPen (Qt::red); const int delta = 20; if (x1 + 2*delta < x2) { qreal x = (x1 + x2) / 2; horizLine (x); // half way in horizontal direction vertLine (y2); horizLine (x2); } else { // real target qreal x3 = x2; qreal y3 = y2; // point behind target x2 -= delta; // y2 -= delta; horizLine (x1+delta); // small starting line qreal y = (y1 + y2) / 2; if (src_bottom + delta <= tgt_top) { qreal y = (src_bottom + tgt_top)/2; vertLine (y); // half way in vertical direction horizLine (x2); // line in horizontal direction } else if (tgt_bottom + delta <= src_top) { qreal y = (tgt_bottom + src_top)/2; vertLine (y); // half way in vertical direction horizLine (x2); // line in horizontal direction } else if (y1 < y2) { // go below target if (tgt_right > src_right) horizLine (tgt_right + delta); else horizLine (src_right + delta); vertLine (tgt_bottom + delta); horizLine (x2); } else { // go above target if (tgt_right > src_right) horizLine (tgt_right + delta); else horizLine (src_right + delta); vertLine (tgt_top - delta); horizLine (x2); } // to center of target vertLine (y3); horizLine (x3); } QGraphicsScene * scene = source->scene (); if (scene != NULL) scene->addItem (group); } void Area::updateConnections () { for (Source * src = this->getFirstSource (); src != NULL; src = src->getNextSource ()) for (Connection * conn = src->getFirstConnection (); conn != NULL; conn = conn->getNextConnection ()) conn->updateConnection (); for (Area * item = this->getFirstItem (); item != NULL; item = item->getNextItem ()) item->updateConnections (); } void Area::updateTargets (Area * target_area) { for (Source * src = this->getFirstSource (); src != NULL; src = src->getNextSource ()) for (Connection * conn = src->getFirstConnection (); conn != NULL; conn = conn->getNextConnection ()) { Target * target = conn->getTarget (); if (target != NULL && target->getArea () == target_area) conn->updateConnection (); } for (Area * item = this->getFirstItem (); item != NULL; item = item->getNextItem ()) item->updateTargets (target_area); } QVariant Area::itemChange (GraphicsItemChange change, const QVariant & value) { if (change == ItemPositionChange /* && scene () */) { // setBrush (QBrush (Qt::red)); // update connections with source in this area for (Source * src = this->getFirstSource (); src != NULL; src = src->getNextSource ()) for (Connection * conn = src->getFirstConnection (); conn != NULL; conn = conn->getNextConnection ()) conn->updateConnection (); // update connections with targets in this area Area * a = this; Area * above = a->getAboveArea (); while (above != NULL) { a = above; above = a->getAboveArea (); } a->updateTargets (this); } return QGraphicsItem::itemChange(change, value); } /* ---------------------------------------------------------------------- */ void Area::dragEnterEvent (QGraphicsSceneDragDropEvent * event) { const QMimeData * mime = event->mimeData (); if (mime->hasColor ()) { event->setAccepted (true); } else if (mime->hasFormat ("application/x-qview-area")) { event->setAccepted (true); } else if (mime->hasFormat ("application/x-qview-shape")) { event->setAccepted (true); } else if (mime->hasFormat ("application/x-qview-field")) { event->setAccepted (true); } else { event->setAccepted (false); } } void Area::dropEvent (QGraphicsSceneDragDropEvent * event) { const QMimeData * mime = event->mimeData (); if (mime->hasColor()) { QColor c = qVariantValue (event->mimeData()->colorData()); setBrush (c); } else if (mime->hasFormat ("application/x-qview-area")) { AreaPaletteItem * source = dynamic_cast (event->source()); if (source != NULL) { Area * area = source->createArea (); if (area != NULL) insertLastItem (area); } } else if (mime->hasFormat ("application/x-qview-shape")) { ShapePaletteItem * source = dynamic_cast (event->source()); if (source != NULL) { QGraphicsItem * shape = source->createShape (); if (shape != NULL) shape->setParentItem (this); } } else if (mime->hasFormat ("application/x-qview-field")) { FieldPaletteItem * source = dynamic_cast (event->source()); if (source != NULL) { Field * field = source->createField (); if (field != NULL) insertLastField (field); } } } /* ---------------------------------------------------------------------- */