bool nodeOutsideRange(const NodeGeometry& node_geom, const double* range_mid, const double* range_size) { return node_geom.getHi(0) <= (range_mid[0] - range_size[0]/2) || node_geom.getLo(0) >= (range_mid[0] + range_size[0]/2) || node_geom.getHi(1) <= (range_mid[1] - range_size[1]/2) || node_geom.getLo(1) >= (range_mid[1] + range_size[1]/2) || node_geom.getHi(2) <= (range_mid[2] - range_size[2]/2) || node_geom.getLo(2) >= (range_mid[2] + range_size[2]/2); }
bool nodeInsideRange(const NodeGeometry& node_geom, const double* range_mid, const double* range_size) { return (range_mid[0] - range_size[0]/2) <= node_geom.getLo(0) && node_geom.getHi(0) <= (range_mid[0] + range_size[0]/2) && (range_mid[1] - range_size[1]/2) <= node_geom.getLo(1) && node_geom.getHi(1) <= (range_mid[1] + range_size[1]/2) && (range_mid[2] - range_size[2]/2) <= node_geom.getLo(2) && node_geom.getHi(2) <= (range_mid[2] + range_size[2]/2); }
void NodePainter:: drawEntryLabels(QPainter * painter, NodeGeometry const & geom, NodeState const & state, NodeDataModel const * model) { QFontMetrics const & metrics = painter->fontMetrics(); for(PortType portType: {PortType::Out, PortType::In}) { auto const &nodeStyle = model->nodeStyle(); auto& entries = state.getEntries(portType); size_t n = entries.size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); if (entries[i].empty()) painter->setPen(nodeStyle.FontColorFaded); else painter->setPen(nodeStyle.FontColor); QString s; if (model->portCaptionVisible(portType, i)) { s = model->portCaption(portType, i); } else { s = model->dataType(portType, i).name; } auto rect = metrics.boundingRect(s); p.setY(p.y() + rect.height() / 4.0); switch (portType) { case PortType::In: p.setX(5.0); break; case PortType::Out: p.setX(geom.width() - 5.0 - rect.width()); break; default: break; } painter->drawText(p, s); } } }
void NodePainter:: drawFilledConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state) { painter->setPen(Qt::cyan); painter->setBrush(Qt::cyan); auto diameter = geom.connectionPointDiameter(); auto drawPoints = [&](PortType portType) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); if (!state.connectionID(portType, i).isNull()) { painter->drawEllipse(p, diameter * 0.4, diameter * 0.4); } } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
void NodePainter:: drawModelName(QPainter * painter, NodeGeometry const & geom, NodeState const & state, NodeDataModel const * model) { NodeStyle const& nodeStyle = model->nodeStyle(); Q_UNUSED(state); if (!model->captionVisible()) return; QString const &name = model->caption(); QFont f = painter->font(); f.setBold(true); QFontMetrics metrics(f); auto rect = metrics.boundingRect(name); QPointF position((geom.width() - rect.width()) / 2.0, (geom.spacing() + geom.entryHeight()) / 3.0); painter->setFont(f); painter->setPen(nodeStyle.FontColor); painter->drawText(position, name); f.setBold(false); painter->setFont(f); }
void NodePainter:: drawEntryLabels(QPainter* painter, NodeGeometry const& geom, NodeState const& state, std::unique_ptr<NodeDataModel> const & model) { QFontMetrics const & metrics = painter->fontMetrics(); auto drawPoints = [&](PortType portType) { auto& entries = state.getEntries(portType); size_t n = entries.size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); if (entries[i].isNull()) painter->setPen(Qt::darkGray); else painter->setPen(QColor(Qt::lightGray).lighter()); QString s = model->data(portType, i)->name(); auto rect = metrics.boundingRect(s); p.setY(p.y() + rect.height() / 4.0); if (portType == PortType::IN) p.setX(5.0); else p.setX(geom.width() - 5.0 - rect.width()); painter->drawText(p, s); } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
void NodePainter:: drawConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state) { painter->setBrush(QColor(Qt::darkGray)); auto diameter = geom.connectionPointDiameter(); auto reducedDiameter = diameter * 0.6; auto drawPoints = [&](PortType portType) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); double r = 1.0; if (state.isReacting() && state.getEntries(portType)[i].isNull()) { auto diff = geom.draggingPos() - p; double dist = std::sqrt(QPointF::dotProduct(diff, diff)); double const thres = 40.0; r = (dist < thres) ? (2.0 - dist / thres ) : 1.0; } painter->drawEllipse(p, reducedDiameter * r, reducedDiameter * r); } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
void NodePainter:: drawNodeRect(QPainter* painter, NodeGeometry const& geom, NodeDataModel const* model, NodeGraphicsObject const & graphicsObject) { NodeStyle const& nodeStyle = model->nodeStyle(); auto color = graphicsObject.isSelected() ? nodeStyle.SelectedBoundaryColor : nodeStyle.NormalBoundaryColor; if (geom.hovered()) { QPen p(color, nodeStyle.HoveredPenWidth); painter->setPen(p); } else { QPen p(color, nodeStyle.PenWidth); painter->setPen(p); } QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(2.0, geom.height())); gradient.setColorAt(0.0, nodeStyle.GradientColor0); gradient.setColorAt(0.03, nodeStyle.GradientColor1); gradient.setColorAt(0.97, nodeStyle.GradientColor2); gradient.setColorAt(1.0, nodeStyle.GradientColor3); painter->setBrush(gradient); float diam = nodeStyle.ConnectionPointDiameter; QRectF boundary( -diam, -diam, 2.0 * diam + geom.width(), 2.0 * diam + geom.height()); double const radius = 3.0; painter->drawRoundedRect(boundary, radius, radius); }
void NodePainter:: drawResizeRect(QPainter * painter, NodeGeometry const & geom, NodeDataModel const * model) { if (model->resizable()) { painter->setBrush(Qt::gray); painter->drawEllipse(geom.resizeRect()); } }
void NodePainter:: drawNodeRect(QPainter* painter, NodeGeometry const& geom) { if (geom.hovered()) { QPen p(Qt::white, 2.0); painter->setPen(p); } else { QPen p(Qt::white, 1.5); painter->setPen(p); } QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(2.0, geom.height())); QColor darkGray1 = QColor(Qt::gray).darker(200); QColor darkGray2 = QColor(Qt::gray).darker(250); gradient.setColorAt(0.0, Qt::darkGray); gradient.setColorAt(0.03, darkGray1); gradient.setColorAt(0.97, darkGray2); gradient.setColorAt(1.0, darkGray2.darker(110)); painter->setBrush(gradient); unsigned int diam = geom.connectionPointDiameter(); QRectF boundary(0.0, 0.0, geom.width(), geom.height()); QMargins m(diam, diam, diam, diam); double const radius = 3.0; painter->drawRoundedRect(boundary.marginsAdded(m), radius, radius); }
void NodePainter:: drawFilledConnectionPoints(QPainter * painter, NodeGeometry const & geom, NodeState const & state, NodeDataModel const * model) { NodeStyle const& nodeStyle = model->nodeStyle(); auto const & connectionStyle = StyleCollection::connectionStyle(); auto diameter = nodeStyle.ConnectionPointDiameter; for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); if (!state.getEntries(portType)[i].empty()) { auto const & dataType = model->dataType(portType, i); if (connectionStyle.useDataDefinedColors()) { QColor const c = connectionStyle.normalColor(dataType.id); painter->setPen(c); painter->setBrush(c); } else { painter->setPen(nodeStyle.FilledConnectionPointColor); painter->setBrush(nodeStyle.FilledConnectionPointColor); } painter->drawEllipse(p, diameter * 0.4, diameter * 0.4); } } } }
void NodePainter:: drawValidationRect(QPainter * painter, NodeGeometry const & geom, NodeDataModel const * model, NodeGraphicsObject const & graphicsObject) { auto modelValidationState = model->validationState(); if (modelValidationState != NodeValidationState::Valid) { NodeStyle const& nodeStyle = model->nodeStyle(); auto color = graphicsObject.isSelected() ? nodeStyle.SelectedBoundaryColor : nodeStyle.NormalBoundaryColor; if (geom.hovered()) { QPen p(color, nodeStyle.HoveredPenWidth); painter->setPen(p); } else { QPen p(color, nodeStyle.PenWidth); painter->setPen(p); } //Drawing the validation message background if (modelValidationState == NodeValidationState::Error) { painter->setBrush(nodeStyle.ErrorColor); } else { painter->setBrush(nodeStyle.WarningColor); } double const radius = 3.0; float diam = nodeStyle.ConnectionPointDiameter; QRectF boundary(-diam, -diam + geom.height() - geom.validationHeight(), 2.0 * diam + geom.width(), 2.0 * diam + geom.validationHeight()); painter->drawRoundedRect(boundary, radius, radius); painter->setBrush(Qt::gray); //Drawing the validation message itself QString const &errorMsg = model->validationMessage(); QFont f = painter->font(); QFontMetrics metrics(f); auto rect = metrics.boundingRect(errorMsg); QPointF position((geom.width() - rect.width()) / 2.0, geom.height() - (geom.validationHeight() - diam) / 2.0); painter->setFont(f); painter->setPen(nodeStyle.FontColor); painter->drawText(position, errorMsg); } }
void NodePainter:: drawConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state, NodeDataModel const * model, FlowScene const & scene) { NodeStyle const& nodeStyle = model->nodeStyle(); auto const &connectionStyle = StyleCollection::connectionStyle(); float diameter = nodeStyle.ConnectionPointDiameter; auto reducedDiameter = diameter * 0.6; for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); for (unsigned int i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); auto const & dataType = model->dataType(portType, i); bool canConnect = (state.getEntries(portType)[i].empty() || (portType == PortType::Out && model->portOutConnectionPolicy(i) == NodeDataModel::ConnectionPolicy::Many) ); double r = 1.0; if (state.isReacting() && canConnect && portType == state.reactingPortType()) { auto diff = geom.draggingPos() - p; double dist = std::sqrt(QPointF::dotProduct(diff, diff)); bool typeConvertable = false; { if (portType == PortType::In) { typeConvertable = scene.registry().getTypeConverter(state.reactingDataType(), dataType) != nullptr; } else { typeConvertable = scene.registry().getTypeConverter(dataType, state.reactingDataType()) != nullptr; } } if (state.reactingDataType().id == dataType.id || typeConvertable) { double const thres = 40.0; r = (dist < thres) ? (2.0 - dist / thres ) : 1.0; } else { double const thres = 80.0; r = (dist < thres) ? (dist / thres) : 1.0; } } if (connectionStyle.useDataDefinedColors()) { painter->setBrush(connectionStyle.normalColor(dataType.id)); } else { painter->setBrush(nodeStyle.ConnectionPointColor); } painter->drawEllipse(p, reducedDiameter * r, reducedDiameter * r); } }; }