52 #include <QVBoxLayout>
54 #include <QMessageBox>
56 #include <QGraphicsSceneMouseEvent>
57 #include <QGraphicsLinearLayout>
58 #include <QGraphicsProxyWidget>
59 #include <QGraphicsGridLayout>
60 #include <QGraphicsView>
63 #include <QXmlResultItems>
65 #include "sceneElement.hh"
66 #include "graphicsScene.hh"
70 #include "connectionPoint.hh"
71 #include "connection.hh"
73 #include "elementInput.hh"
74 #include "elementOutput.hh"
75 #include "elementFunction.hh"
77 #include "config/configDialog.hh"
79 #include "../parser/element.hh"
80 #include "../parser/context.hh"
81 #include "../parser/function.hh"
83 #define BACKGROUND_RED 0x00
84 #define BACKGROUND_GREEN 0x00
85 #define BACKGROUND_BLUE 0x00
86 #define BACKGROUND_ALPHA 0xff
88 #define SELECTED_BACKGROUND_RED 0x00
89 #define SELECTED_BACKGROUND_GREEN 0x00
90 #define SELECTED_BACKGROUND_BLUE 0x6f
91 #define SELECTED_BACKGROUND_ALPHA 0xff
109 id_ (_element->getNewId ())
112 bool hasConfig =
false;
114 QGraphicsLinearLayout *layout =
new QGraphicsLinearLayout (Qt::Vertical);
115 layout->setSpacing (0);
117 nameLayout_ =
new QGraphicsLinearLayout (Qt::Vertical);
118 nameLayout_->setSpacing(0);
119 nameLayout_->setContentsMargins(15, 0, 15, 0);
125 QFont font = name_->font ();
126 if (font.pointSize () != -1)
127 font.setPointSize (font.pointSize () + 1);
129 font.setPixelSize (font.pixelSize () + 1);
131 name_->setFont (font);
133 nameLayout_->addItem(name_);
134 nameLayout_->setAlignment (name_, Qt::AlignCenter);
137 font = elementName_->font ();
138 if (font.pointSize () != -1)
139 font.setPointSize (font.pointSize () - 2);
141 font.setPixelSize (font.pixelSize () - 2);
142 elementName_->setFont (font);
144 nameLayout_->addItem(elementName_);
145 nameLayout_->setAlignment (elementName_, Qt::AlignCenter);
147 elementName_->hide ();
149 layout->addItem(nameLayout_);
153 QGraphicsGridLayout *inGrid =
new QGraphicsGridLayout;
154 inGrid->setContentsMargins (0,0,5,0);
164 if (!(in->state () & Input::NoUserInput))
167 configInputs_.append (i);
170 if (in->state () & Input::NoExternalInput)
179 inGrid->addItem (i->
typeTextItem (), row, 1, Qt::AlignLeft | Qt::AlignVCenter);
182 height = qMin (height, i->
typeTextItem ()->preferredHeight () / 2);
183 typeWidth = qMax (i->
typeTextItem ()->preferredWidth (), typeWidth);
187 if (!element_->
inputs ().isEmpty ())
189 inGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
190 inGrid->setHorizontalSpacing (1);
191 layout->insertItem (index, inGrid);
193 layout->setItemSpacing (index - 1, 10);
198 QGraphicsGridLayout *outGrid =
new QGraphicsGridLayout;
199 outGrid->setContentsMargins (5,0,0,0);
209 outGrid->addItem (o->
typeTextItem (), row, 1, Qt::AlignRight | Qt::AlignVCenter);
212 height = qMin (height, o->
typeTextItem ()->preferredHeight () / 2);
213 typeWidth = qMax (o->
typeTextItem ()->preferredWidth (), typeWidth);
219 if (!element_->
outputs ().isEmpty ())
221 outGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
222 outGrid->setHorizontalSpacing (1);
223 layout->insertItem(index, outGrid);
224 layout->setAlignment (outGrid, Qt::AlignRight);
225 layout->setItemSpacing (index - 1, 10);
229 if (hasConfig || !element_->
functions ().isEmpty ())
231 QGraphicsLinearLayout *hl =
new QGraphicsLinearLayout (Qt::Horizontal);
232 QGraphicsLinearLayout *vl =
new QGraphicsLinearLayout (Qt::Vertical);
233 hl->setContentsMargins(15, 0, 15, 0);
239 configButton->setBrush (Qt::black);
245 vl->addItem (configButton);
247 connect (configButton, SIGNAL (pressed()),
this, SLOT (showInputConfig()));
256 config->setBrush (Qt::black);
261 vl->addItem (config);
263 connect (config, SIGNAL (pressed()), ef, SLOT (editFunction ()));
265 functions_.append (ef);
272 layout->insertItem (index, hl);
273 layout->setAlignment (hl, Qt::AlignCenter);
274 layout->setItemSpacing (index - 1, 10);
281 QGraphicsGridLayout *sIO =
new QGraphicsGridLayout ();
290 sIO->addItem (dataIn_->
connectionPointItem (), 0, col++, Qt::AlignLeft | Qt::AlignVCenter);
309 sIO->addItem (dataOut_->
connectionPointItem (), 0, col, Qt::AlignRight | Qt::AlignVCenter);
313 sIO->setContentsMargins (lo, 0, ro, 0);
314 sIO->setHorizontalSpacing (1);
316 layout->insertItem (index, sIO);
317 layout->setAlignment (sIO, Qt::AlignCenter);
318 layout->setItemSpacing (index - 1, 10);
322 layout->setItemSpacing (0, 1);
324 layout->setContentsMargins (0, 2, 0, 6);
328 if (layout->preferredWidth() < 200)
329 setMinimumWidth (layout->preferredWidth());
331 setMinimumWidth (200);
333 setZValue (scene_->
getNewZ ());
335 setFlag (QGraphicsItem::ItemIsSelectable,
true);
336 setFlag (QGraphicsItem::ItemIsMovable,
true);
338 setMaximumWidth (200);
364 int w = geometry().width() - 20;
365 int h = geometry().height();
367 _painter->setRenderHint(QPainter::Antialiasing,
true);
369 _painter->setBrush(QBrush(QColor(SELECTED_BACKGROUND_RED,
370 SELECTED_BACKGROUND_GREEN,
371 SELECTED_BACKGROUND_BLUE,
372 SELECTED_BACKGROUND_ALPHA)));
374 _painter->setBrush(QBrush(QColor(BACKGROUND_RED,
379 _painter->setPen (Qt::NoPen);
380 _painter->drawRoundedRect(10, 0, w, h, 5, 5);
389 path.moveTo (10, 20);
391 path.arcTo (10, 0, 10, 10, 180, -90);
392 path.lineTo (w + 6, 0);
393 path.arcTo (w, 0, 10, 10, 90, -90);
394 path.lineTo (w + 10, 10);
396 path.cubicTo (QPointF (10 + wH, 10), QPointF (10 + wH, 20), QPointF (10, 20));
398 rG.setCenter (10 + wT, 0);
399 rG.setFocalPoint(10 + wT, 0);
401 rG.setColorAt(0, QColor (255, 255, 255, 128));
402 rG.setColorAt(1, Qt::transparent);
403 _painter->setBrush (rG);
404 _painter->setPen (Qt::NoPen);
405 _painter->drawPath(path);
407 path = QPainterPath ();
408 path.moveTo (w + 5, 0);
409 path.arcTo (w, 0, 10, 10, 90, -90);
410 path.lineTo (w + 10, h - 5);
411 path.lineTo (w + 5, h - 5);
412 path.lineTo (w + 5, 0);
414 lG.setStart (w + 5, 0);
415 lG.setFinalStop(w + 10, 0);
416 lG.setColorAt(0, Qt::transparent);
417 lG.setColorAt(1, QColor (255, 255, 255, 128));
418 _painter->setBrush (lG);
419 _painter->drawPath(path);
421 path = QPainterPath ();
422 path.moveTo (10, h - 5);
423 path.arcTo (10, h - 10, 10, 10, 180, 90);
424 path.lineTo (w + 5, h);
425 path.lineTo (w + 5, h - 5);
426 path.lineTo (10, h - 5);
427 lG.setStart (0, h - 5);
428 lG.setFinalStop (0, h);
429 _painter->setBrush (lG);
430 _painter->drawPath (path);
432 path = QPainterPath ();
433 path.moveTo (w + 5, h);
434 path.arcTo (w, h - 10, 10, 10, -90, 90);
435 path.lineTo (w + 5, h - 5);
436 path.lineTo (w + 5, h);
437 rG.setCenter (w + 5, h - 5);
438 rG.setFocalPoint(w + 5, h - 5);
440 rG.setColorAt (0, Qt::transparent);
441 rG.setColorAt (1, QColor (255, 255, 255, 128));
442 _painter->setBrush (rG);
443 _painter->drawPath(path);
445 QGraphicsWidget::paint (_painter, _option, _widget);
451 void SceneElement::mousePressEvent (QGraphicsSceneMouseEvent *_event)
453 QGraphicsWidget::mousePressEvent (_event);
454 setZValue (scene_->
getNewZ ());
460 void SceneElement::mouseMoveEvent (QGraphicsSceneMouseEvent *_event)
462 QGraphicsWidget::mouseMoveEvent (_event);
468 void SceneElement::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
470 QGraphicsWidget::mouseReleaseEvent (_event);
479 QPointF _scenePos = _event->scenePos ();
480 if (name_->
boundingRect ().contains (name_->mapFromScene (_scenePos)) ||
481 elementName_->
boundingRect ().contains (elementName_->mapFromScene (_scenePos)))
483 ConfigDialog d (QVector<ElementInput *> (), name_->
text (), scene ()->views ()[0]);
484 d.setWindowTitle (
"Element Name Configuration");
485 if (d.exec () == QDialog::Accepted)
487 if (d.name ().isEmpty())
493 elementName_->hide ();
495 elementName_->show ();
497 nameLayout_->invalidate ();
518 if (configInputs_.contains (i))
520 QVector<ElementInput *>
inputs;
523 ConfigDialog d (inputs, QString (), scene ()->views ()[0]);
528 QMessageBox msgBox (scene ()->views ()[0]);
529 msgBox.setText(
"No configuration available.");
539 void SceneElement::moveEvent (QGraphicsSceneMoveEvent *_event)
541 QGraphicsWidget::moveEvent (_event);
572 code_ = element_->
code ();
580 QString regex =
"\\[\\s*" + _name +
"\\s*=\\s*\"" + _id +
"\"\\s*\\]";
581 code_ = code_.replace (QRegExp (regex), _value);
589 return element_->
name () +
"_" + QString::number (id_);
595 void SceneElement::showInputConfig()
598 d.setWindowTitle (name_->
text () +
" Input Configuration");
599 if (d.exec () == QDialog::Accepted)
601 if (d.name ().isEmpty())
607 elementName_->hide ();
609 elementName_->show ();
611 nameLayout_->invalidate ();
676 void VSI::SceneElement::invalidateConnections()
688 foreach (
Connection *c, dataIn_->connections ())
692 foreach (
Connection *c, dataOut_->connections ())
703 QDomElement main = _doc.createElement(
"element");
704 _root.appendChild(main);
705 main.setAttribute (
"name",element_->
name ());
709 QDomElement name = _doc.createElement(
"visible_name");
710 main.appendChild(name);
711 t = _doc.createTextNode(name_->
text ());
715 QDomElement
id = _doc.createElement(
"id");
716 main.appendChild(
id);
717 t = _doc.createTextNode(QString::number (id_));
720 QDomElement px = _doc.createElement(
"x");
721 main.appendChild(px);
722 t = _doc.createTextNode(QString::number (pos ().x ()));
725 QDomElement py = _doc.createElement(
"y");
726 main.appendChild(py);
727 t = _doc.createTextNode(QString::number (pos ().y ()));
730 if (!inputs_.isEmpty() || dataIn_)
732 QDomElement
inputs = _doc.createElement(
"inputs");
733 main.appendChild(inputs);
739 if (!functions_.isEmpty ())
741 QDomElement
functions = _doc.createElement(
"functions");
742 main.appendChild(functions);
764 elementName_->hide ();
766 elementName_->show ();
768 nameLayout_->invalidate ();
772 id = val.toUInt (&ok1);
781 x = val.toDouble (&ok1);
784 y = val.toDouble (&ok2);
791 _xml.setQuery (
"inputs/input");
797 _xml.evaluateTo (&i);
798 QXmlItem item (i.next ());
799 while (!item.isNull ())
808 if (val ==
"data" && dataIn_)
826 _xml.setQuery (
"functions/function");
830 _xml.evaluateTo (&i);
831 QXmlItem item (i.next ());
832 while (!item.isNull ())
int id()
Unique id for identification.
void loadFromXml(QXmlQuery &_xml)
Load from xml.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
void setBackground(bool _leftOut, bool _rightOut)
Enables background painting.
void setHorizontalStretch(bool _stretch)
Should this widget be stretchable in horizontal direction.
const QString & shortDescription() const
Short description.
const QString & name() const
Name.
QVector< ElementInput * > inputs()
Inputs.
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
Double click occured. We can't use mouseDoubleClickEvent because we won't get one for the ConecctionP...
const QString & shortDescription() const
Short description.
const QVector< Input * > & inputs() const
Inputs.
virtual QRectF boundingRect() const
Bounding rectangle.
const QString & longDescription() const
Long description.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
InOut * inOut() const
InOut context object.
QString name() const
Name.
Text * descriptionTextItem() const
Short description widget.
SceneElement(GraphicsScene *_scene, Element *_element)
Constructor.
static QString getXmlString(QXmlQuery &_xml, QString _expr, QString _default="")
Gets the string of a xml query.
bool isBefore(SceneElement *_e)
Will this element be executed before _e bacause of its connections?
const QVector< Output * > & outputs() const
Outputs.
~SceneElement()
Destructor.
void paint(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget=0)
Background painting.
void loadFromXml(QXmlQuery &_xml)
Load from xml.
QString name() const
Element name.
void setValid(bool _value)
Sets the valid flag (needed during code generation)
ElementInput * input()
Input of this connection.
void setMinId(unsigned int _id)
sets the minimum for an unused id
QList< Connection * > connections() const
Connections.
ConnectionPoint * connectionPointItem() const
Connection point widget.
Output * dataOut()
Scenegraph output.
SceneElement * element()
Scene element.
QVector< ElementFunction * > functions()
Functions.
Function * function()
Function class.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
void contentChange()
handle content changes
const QString & shortDescription() const
Short description.
qreal getNewZ()
Returns a new Z value that is above all elements.
ElementInput * dataIn()
Scene input.
ElementOutput * output()
Output of this connection.
QString code() const
Code segment.
Text * typeTextItem() const
Type text widget.
void setAlignment(Qt::Alignment _alignment)
Placement of the text in a stretched widget.
void setBackgroundBrush(QBrush _brush)
Sets the background brush.
void setText(QString _text)
Set displayed text.
void loadFromXml(QXmlQuery &_xml)
Load from xml.
ElementOutput * dataOut()
Scene output.
void replaceCodeBlock(QString _name, QString _id, QString _value)
Replace block with name _name and id _id with _value.
QString variableId()
Unique variable name for code generation.
void updatePositions()
called to update position on element movement
Input * dataIn()
Scenegraph input.
QString text()
Get displayed text.
void invalidate()
invalidate way
bool isAfter(SceneElement *_e)
Will this element be executed after _e bacause of its connections?
QPainterPath shape() const
Returns the shape for proper repainting/event handling.
void mouseRelease(QPointF _pos, QGraphicsItem *_item)
Redirect mouse release to tools area.
const QVector< Function * > & functions() const
Functions.
void resetCodeGeneration()
Reset code block for code generation.