50#include <QGraphicsSceneMouseEvent>
51#include <QGraphicsLinearLayout>
52#include <QGraphicsProxyWidget>
53#include <QGraphicsGridLayout>
54#include <QGraphicsView>
55#include <QRegularExpression>
59#include "sceneElement.hh"
60#include "graphicsScene.hh"
64#include "connectionPoint.hh"
65#include "connection.hh"
67#include "elementInput.hh"
68#include "elementOutput.hh"
69#include "elementFunction.hh"
71#include "config/configDialog.hh"
73#include "../parser/element.hh"
74#include "../parser/context.hh"
75#include "../parser/function.hh"
77#define BACKGROUND_RED 0x00
78#define BACKGROUND_GREEN 0x00
79#define BACKGROUND_BLUE 0x00
80#define BACKGROUND_ALPHA 0xff
82#define SELECTED_BACKGROUND_RED 0x00
83#define SELECTED_BACKGROUND_GREEN 0x00
84#define SELECTED_BACKGROUND_BLUE 0x6f
85#define SELECTED_BACKGROUND_ALPHA 0xff
102 id_ (_element->getNewId ())
105 bool hasConfig =
false;
107 QGraphicsLinearLayout *layout =
new QGraphicsLinearLayout (Qt::Vertical);
108 layout->setSpacing (0);
110 nameLayout_ =
new QGraphicsLinearLayout (Qt::Vertical);
111 nameLayout_->setSpacing(0);
112 nameLayout_->setContentsMargins(15, 0, 15, 0);
118 QFont font = name_->font ();
119 if (font.pointSize () != -1)
120 font.setPointSize (font.pointSize () + 1);
122 font.setPixelSize (font.pixelSize () + 1);
124 name_->setFont (font);
126 nameLayout_->addItem(name_);
127 nameLayout_->setAlignment (name_, Qt::AlignCenter);
130 font = elementName_->font ();
131 if (font.pointSize () != -1)
132 font.setPointSize (font.pointSize () - 2);
134 font.setPixelSize (font.pixelSize () - 2);
135 elementName_->setFont (font);
137 nameLayout_->addItem(elementName_);
138 nameLayout_->setAlignment (elementName_, Qt::AlignCenter);
140 elementName_->hide ();
142 layout->addItem(nameLayout_);
146 QGraphicsGridLayout *inGrid =
new QGraphicsGridLayout;
147 inGrid->setContentsMargins (0,0,5,0);
157 if (!(in->state () & Input::NoUserInput))
160 configInputs_.append (i);
163 if (in->state () & Input::NoExternalInput)
172 inGrid->addItem (i->
typeTextItem (), row, 1, Qt::AlignLeft | Qt::AlignVCenter);
175 height = qMin (height, i->
typeTextItem ()->preferredHeight () / 2);
176 typeWidth = qMax (i->
typeTextItem ()->preferredWidth (), typeWidth);
180 if (!element_->
inputs ().isEmpty ())
182 inGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
183 inGrid->setHorizontalSpacing (1);
184 layout->insertItem (index, inGrid);
185 layout->setAlignment (inGrid, Qt::AlignLeft);
186 layout->setItemSpacing (index - 1, 10);
191 QGraphicsGridLayout *outGrid =
new QGraphicsGridLayout;
192 outGrid->setContentsMargins (5,0,0,0);
202 outGrid->addItem (o->
typeTextItem (), row, 1, Qt::AlignRight | Qt::AlignVCenter);
205 height = qMin (height, o->
typeTextItem ()->preferredHeight () / 2);
206 typeWidth = qMax (o->
typeTextItem ()->preferredWidth (), typeWidth);
212 if (!element_->
outputs ().isEmpty ())
214 outGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
215 outGrid->setHorizontalSpacing (1);
216 layout->insertItem(index, outGrid);
217 layout->setAlignment (outGrid, Qt::AlignRight);
218 layout->setItemSpacing (index - 1, 10);
222 if (hasConfig || !element_->
functions ().isEmpty ())
224 QGraphicsLinearLayout *hl =
new QGraphicsLinearLayout (Qt::Horizontal);
225 QGraphicsLinearLayout *vl =
new QGraphicsLinearLayout (Qt::Vertical);
226 hl->setContentsMargins(15, 0, 15, 0);
232 configButton->setBrush (Qt::black);
238 vl->addItem (configButton);
240 connect (configButton, SIGNAL (pressed()),
this, SLOT (showInputConfig()));
249 config->setBrush (Qt::black);
254 vl->addItem (config);
256 connect (config, SIGNAL (pressed()), ef, SLOT (editFunction ()));
258 functions_.append (ef);
265 layout->insertItem (index, hl);
266 layout->setAlignment (hl, Qt::AlignCenter);
267 layout->setItemSpacing (index - 1, 10);
274 QGraphicsGridLayout *sIO =
new QGraphicsGridLayout ();
283 sIO->addItem (dataIn_->
connectionPointItem (), 0, col++, Qt::AlignLeft | Qt::AlignVCenter);
302 sIO->addItem (dataOut_->
connectionPointItem (), 0, col, Qt::AlignRight | Qt::AlignVCenter);
306 sIO->setContentsMargins (lo, 0, ro, 0);
307 sIO->setHorizontalSpacing (1);
309 layout->insertItem (index, sIO);
310 layout->setAlignment (sIO, Qt::AlignCenter);
311 layout->setItemSpacing (index - 1, 10);
315 layout->setItemSpacing (0, 1);
317 layout->setContentsMargins (0, 2, 0, 6);
321 if (layout->preferredWidth() < 200)
322 setMinimumWidth (layout->preferredWidth());
324 setMinimumWidth (200);
326 setZValue (scene_->
getNewZ ());
328 setFlag (QGraphicsItem::ItemIsSelectable,
true);
329 setFlag (QGraphicsItem::ItemIsMovable,
true);
331 setMaximumWidth (200);
357 int w = geometry().width() - 20;
358 int h = geometry().height();
360 _painter->setRenderHint(QPainter::Antialiasing,
true);
362 _painter->setBrush(QBrush(QColor(SELECTED_BACKGROUND_RED,
363 SELECTED_BACKGROUND_GREEN,
364 SELECTED_BACKGROUND_BLUE,
365 SELECTED_BACKGROUND_ALPHA)));
367 _painter->setBrush(QBrush(QColor(BACKGROUND_RED,
372 _painter->setPen (Qt::NoPen);
373 _painter->drawRoundedRect(10, 0, w, h, 5, 5);
382 path.moveTo (10, 20);
384 path.arcTo (10, 0, 10, 10, 180, -90);
385 path.lineTo (w + 6, 0);
386 path.arcTo (w, 0, 10, 10, 90, -90);
387 path.lineTo (w + 10, 10);
389 path.cubicTo (QPointF (10 + wH, 10), QPointF (10 + wH, 20), QPointF (10, 20));
391 rG.setCenter (10 + wT, 0);
392 rG.setFocalPoint(10 + wT, 0);
394 rG.setColorAt(0, QColor (255, 255, 255, 128));
395 rG.setColorAt(1, Qt::transparent);
396 _painter->setBrush (rG);
397 _painter->setPen (Qt::NoPen);
398 _painter->drawPath(path);
400 path = QPainterPath ();
401 path.moveTo (w + 5, 0);
402 path.arcTo (w, 0, 10, 10, 90, -90);
403 path.lineTo (w + 10, h - 5);
404 path.lineTo (w + 5, h - 5);
405 path.lineTo (w + 5, 0);
407 lG.setStart (w + 5, 0);
408 lG.setFinalStop(w + 10, 0);
409 lG.setColorAt(0, Qt::transparent);
410 lG.setColorAt(1, QColor (255, 255, 255, 128));
411 _painter->setBrush (lG);
412 _painter->drawPath(path);
414 path = QPainterPath ();
415 path.moveTo (10, h - 5);
416 path.arcTo (10, h - 10, 10, 10, 180, 90);
417 path.lineTo (w + 5, h);
418 path.lineTo (w + 5, h - 5);
419 path.lineTo (10, h - 5);
420 lG.setStart (0, h - 5);
421 lG.setFinalStop (0, h);
422 _painter->setBrush (lG);
423 _painter->drawPath (path);
425 path = QPainterPath ();
426 path.moveTo (w + 5, h);
427 path.arcTo (w, h - 10, 10, 10, -90, 90);
428 path.lineTo (w + 5, h - 5);
429 path.lineTo (w + 5, h);
430 rG.setCenter (w + 5, h - 5);
431 rG.setFocalPoint(w + 5, h - 5);
433 rG.setColorAt (0, Qt::transparent);
434 rG.setColorAt (1, QColor (255, 255, 255, 128));
435 _painter->setBrush (rG);
436 _painter->drawPath(path);
438 QGraphicsWidget::paint (_painter, _option, _widget);
444void SceneElement::mousePressEvent (QGraphicsSceneMouseEvent *_event)
446 QGraphicsWidget::mousePressEvent (_event);
447 setZValue (scene_->
getNewZ ());
453void SceneElement::mouseMoveEvent (QGraphicsSceneMouseEvent *_event)
455 QGraphicsWidget::mouseMoveEvent (_event);
461void SceneElement::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
463 QGraphicsWidget::mouseReleaseEvent (_event);
472 QPointF _scenePos = _event->scenePos ();
473 if (name_->
boundingRect ().contains (name_->mapFromScene (_scenePos)) ||
474 elementName_->
boundingRect ().contains (elementName_->mapFromScene (_scenePos)))
476 ConfigDialog d (QVector<ElementInput *> (), name_->
text (), scene ()->views ()[0]);
477 d.setWindowTitle (
"Element Name Configuration");
478 if (d.exec () == QDialog::Accepted)
480 if (d.
name ().isEmpty())
486 elementName_->hide ();
488 elementName_->show ();
490 nameLayout_->invalidate ();
511 if (configInputs_.contains (i))
513 QVector<ElementInput *>
inputs;
521 QMessageBox msgBox (scene ()->views ()[0]);
522 msgBox.setText(
"No configuration available.");
532void SceneElement::moveEvent (QGraphicsSceneMoveEvent *_event)
534 QGraphicsWidget::moveEvent (_event);
551 c->updatePositions ();
567 code_ = element_->
code ();
575 QString regex =
"\\[\\s*" + _name +
"\\s*=\\s*\"" + _id +
"\"\\s*\\]";
576 code_ = code_.replace (QRegularExpression (regex), _value);
584 return element_->
name () +
"_" + QString::number (id_);
590void SceneElement::showInputConfig()
593 d.setWindowTitle (name_->
text () +
" Input Configuration");
594 if (d.exec () == QDialog::Accepted)
596 if (d.name ().isEmpty())
602 elementName_->hide ();
604 elementName_->show ();
606 nameLayout_->invalidate ();
673void VSI::SceneElement::invalidateConnections()
685 foreach (
Connection *c, dataIn_->connections ())
690 foreach (Connection *c, dataOut_->connections ())
702 QDomElement main = _doc.createElement(
"element");
703 _root.appendChild(main);
704 main.setAttribute (
"name",element_->
name ());
708 QDomElement name = _doc.createElement(
"visible_name");
709 main.appendChild(name);
710 t = _doc.createTextNode(name_->
text ());
714 QDomElement
id = _doc.createElement(
"id");
715 main.appendChild(
id);
716 t = _doc.createTextNode(QString::number (id_));
719 QDomElement px = _doc.createElement(
"x");
720 main.appendChild(px);
721 t = _doc.createTextNode(QString::number (pos ().x ()));
724 QDomElement py = _doc.createElement(
"y");
725 main.appendChild(py);
726 t = _doc.createTextNode(QString::number (pos ().y ()));
729 if (!inputs_.isEmpty() || dataIn_)
731 QDomElement
inputs = _doc.createElement(
"inputs");
738 if (!functions_.isEmpty ())
740 QDomElement
functions = _doc.createElement(
"functions");
763 elementName_->hide ();
765 elementName_->show ();
767 nameLayout_->invalidate ();
771 id = val.toUInt (&ok1);
780 x = val.toDouble (&ok1);
783 y = val.toDouble (&ok2);
789 for(QDomElement n = _domElement.firstChildElement(); !n.isNull(); n = n.nextSiblingElement() )
792 if (n.tagName() ==
"inputs") {
795 for(QDomElement inputElement = n.firstChildElement(); !inputElement.isNull(); inputElement = inputElement.nextSiblingElement() )
797 val = inputElement.attribute(
"name");
802 if (val ==
"data" && dataIn_) {
815 for(QDomElement connectionElement = inputElement.firstChildElement(); !connectionElement.isNull(); connectionElement = connectionElement.nextSiblingElement() )
817 if (connectionElement.tagName() ==
"connection") {
818 QString tmp = _domElement.attribute(
"name") +
";"+
Context::getXmlString (_domElement,
"id") +
";" + inputElement.attribute(
"name") +
";" + connectionElement.attribute(
"element") +
";" + connectionElement.attribute(
"element_id") +
";" + connectionElement.attribute(
"output");
819 _connections.push_back(tmp);
827 if (n.tagName() ==
"functions") {
830 for(QDomElement functionElement = n.firstChildElement(); !functionElement.isNull(); functionElement = functionElement.nextSiblingElement() )
832 val = functionElement.attribute(
"name");
QString name()
return entered name
ElementInput * input()
Input of this connection.
void updatePositions()
called to update position on element movement
void invalidate()
invalidate way
ElementOutput * output()
Output of this connection.
static QString getXmlString(QDomElement &_element, const QString &_tag, QString _default="")
Gets the string of a xml query.
void loadElementFunctionFromXml(QDomElement &_domElement)
Load from xml.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
Function * function()
Function class.
Text * descriptionTextItem() const
Short description widget.
Text * typeTextItem() const
Type text widget.
InOut * inOut() const
InOut context object.
QList< Connection * > connections() const
Connections.
SceneElement * element()
Scene element.
ConnectionPoint * connectionPointItem() const
Connection point widget.
Output * dataOut()
Scenegraph output.
const QString & shortDescription() const
Short description.
const QVector< Input * > & inputs() const
Inputs.
QString name() const
Element name.
QString code() const
Code segment.
const QVector< Function * > & functions() const
Functions.
const QString & longDescription() const
Long description.
void setMinId(unsigned int _id)
sets the minimum for an unused id
const QVector< Output * > & outputs() const
Outputs.
Input * dataIn()
Scenegraph input.
const QString & shortDescription() const
Short description.
QString name() const
Name.
void contentChange()
handle content changes
qreal getNewZ()
Returns a new Z value that is above all elements.
void mouseRelease(QPointF _pos, QGraphicsItem *_item)
Redirect mouse release to tools area.
const QString & shortDescription() const
Short description.
const QString & name() const
Name.
QString variableId()
Unique variable name for code generation.
~SceneElement()
Destructor.
SceneElement(GraphicsScene *_scene, Element *_element)
Constructor.
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
Double click occured. We can't use mouseDoubleClickEvent because we won't get one for the ConecctionP...
void paint(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget=0)
Background painting.
void replaceCodeBlock(const QString &_name, const QString &_id, const QString &_value)
Replace block with name _name and id _id with _value.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
void loadFromXml(QDomElement &_domElement, std::vector< QString > &_connections)
Load one scene Element from xml.
ElementInput * dataIn()
Scene input.
bool isBefore(SceneElement *_e)
Will this element be executed before _e bacause of its connections?
void resetCodeGeneration()
Reset code block for code generation.
ElementOutput * dataOut()
Scene output.
bool isAfter(SceneElement *_e)
Will this element be executed after _e bacause of its connections?
QVector< ElementFunction * > functions()
Functions.
int id()
Unique id for identification.
QVector< ElementInput * > inputs()
Inputs.
virtual QRectF boundingRect() const
Bounding rectangle.
QString text()
Get displayed text.
void setAlignment(Qt::Alignment _alignment)
Placement of the text in a stretched widget.
void setText(QString _text)
Set displayed text.
void setHorizontalStretch(bool _stretch)
Should this widget be stretchable in horizontal direction.
void setBackground(bool _leftOut, bool _rightOut)
Enables background painting.
QPainterPath shape() const
Returns the shape for proper repainting/event handling.