123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #include "DefaultNodePainter.hpp"
- #include <cmath>
- #include <QtCore/QMargins>
- #include "AbstractGraphModel.hpp"
- #include "AbstractNodeGeometry.hpp"
- #include "BasicGraphicsScene.hpp"
- #include "ConnectionGraphicsObject.hpp"
- #include "ConnectionIdUtils.hpp"
- #include "NodeGraphicsObject.hpp"
- #include "NodeState.hpp"
- #include "StyleCollection.hpp"
- namespace QtNodes {
- void DefaultNodePainter::paint(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- // TODO?
- // AbstractNodeGeometry & geometry = ngo.nodeScene()->nodeGeometry();
- // geometry.recomputeSizeIfFontChanged(painter->font());
- drawNodeRect(painter, ngo);
- // drawConnectionPoints(painter, ngo);
- // drawFilledConnectionPoints(painter, ngo);
- drawNodeCaption(painter, ngo);
- drawEntryLabels(painter, ngo);
- drawResizeRect(painter, ngo);
- }
- void DefaultNodePainter::drawNodeRect(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- QSize size = geometry.size(nodeId);
- QJsonDocument json = QJsonDocument::fromVariant(model.nodeData(nodeId, NodeRole::Style));
- NodeStyle nodeStyle(json.object());
- auto color = ngo.isSelected() ? nodeStyle.SelectedBoundaryColor : nodeStyle.NormalBoundaryColor;
- if (ngo.nodeState().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, size.height()));
- gradient.setColorAt(0.0, nodeStyle.GradientColor0);
- gradient.setColorAt(0.10, nodeStyle.GradientColor1);
- gradient.setColorAt(0.90, nodeStyle.GradientColor2);
- gradient.setColorAt(1.0, nodeStyle.GradientColor3);
- painter->setBrush(gradient);
- QRectF boundary(0, 0, size.width(), size.height());
- double const radius = 3.0;
- painter->drawRoundedRect(boundary, radius, radius);
- }
- void DefaultNodePainter::drawConnectionPoints(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- QJsonDocument json = QJsonDocument::fromVariant(model.nodeData(nodeId, NodeRole::Style));
- NodeStyle nodeStyle(json.object());
- auto const &connectionStyle = StyleCollection::connectionStyle();
- float diameter = nodeStyle.ConnectionPointDiameter;
- auto reducedDiameter = diameter * 0.6;
- for (PortType portType : { PortType::Out, PortType::In }) {
- size_t const n =
- model.nodeData(nodeId, (portType == PortType::Out) ? NodeRole::OutPortCount : NodeRole::InPortCount)
- .toUInt();
- for (PortIndex portIndex = 0; portIndex < n; ++portIndex) {
- QPointF p = geometry.portPosition(nodeId, portType, portIndex);
- auto const &dataType =
- model.portData(nodeId, portType, portIndex, PortRole::DataType).value<NodeDataType>();
- double r = 1.0;
- NodeState const &state = ngo.nodeState();
- if (auto const *cgo = state.connectionForReaction()) {
- PortType requiredPort = cgo->connectionState().requiredPort();
- if (requiredPort == portType) {
- ConnectionId possibleConnectionId =
- makeCompleteConnectionId(cgo->connectionId(), nodeId, portIndex);
- bool const possible = model.connectionPossible(possibleConnectionId);
- auto cp = cgo->sceneTransform().map(cgo->endPoint(requiredPort));
- cp = ngo.sceneTransform().inverted().map(cp);
- auto diff = cp - p;
- double dist = std::sqrt(QPointF::dotProduct(diff, diff));
- if (possible) {
- 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);
- }
- }
- if (ngo.nodeState().connectionForReaction()) {
- ngo.nodeState().resetConnectionForReaction();
- }
- }
- void DefaultNodePainter::drawFilledConnectionPoints(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- QJsonDocument json = QJsonDocument::fromVariant(model.nodeData(nodeId, NodeRole::Style));
- NodeStyle nodeStyle(json.object());
- auto diameter = nodeStyle.ConnectionPointDiameter;
- for (PortType portType : { PortType::Out, PortType::In }) {
- size_t const n =
- model.nodeData(nodeId, (portType == PortType::Out) ? NodeRole::OutPortCount : NodeRole::InPortCount)
- .toUInt();
- for (PortIndex portIndex = 0; portIndex < n; ++portIndex) {
- QPointF p = geometry.portPosition(nodeId, portType, portIndex);
- auto const &connected = model.connections(nodeId, portType, portIndex);
- if (!connected.empty()) {
- auto const &dataType =
- model.portData(nodeId, portType, portIndex, PortRole::DataType).value<NodeDataType>();
- auto const &connectionStyle = StyleCollection::connectionStyle();
- 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 DefaultNodePainter::drawNodeCaption(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- if (!model.nodeData(nodeId, NodeRole::CaptionVisible).toBool())
- return;
- QString const name = model.nodeData(nodeId, NodeRole::Caption).toString();
- QFont f = painter->font();
- f.setBold(true);
- QPointF position = geometry.captionPosition(nodeId);
- QJsonDocument json = QJsonDocument::fromVariant(model.nodeData(nodeId, NodeRole::Style));
- NodeStyle nodeStyle(json.object());
- painter->setFont(f);
- painter->setPen(nodeStyle.FontColor);
- painter->drawText(position, name);
- f.setBold(false);
- painter->setFont(f);
- }
- void DefaultNodePainter::drawEntryLabels(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- QJsonDocument json = QJsonDocument::fromVariant(model.nodeData(nodeId, NodeRole::Style));
- NodeStyle nodeStyle(json.object());
- for (PortType portType : { PortType::Out, PortType::In }) {
- unsigned int n = model.nodeData<unsigned int>(
- nodeId, (portType == PortType::Out) ? NodeRole::OutPortCount : NodeRole::InPortCount);
- for (PortIndex portIndex = 0; portIndex < n; ++portIndex) {
- auto const &connected = model.connections(nodeId, portType, portIndex);
- QPointF p = geometry.portTextPosition(nodeId, portType, portIndex);
- if (connected.empty())
- painter->setPen(nodeStyle.FontColorFaded);
- else
- painter->setPen(nodeStyle.FontColor);
- QString s;
- if (model.portData<bool>(nodeId, portType, portIndex, PortRole::CaptionVisible)) {
- s = model.portData<QString>(nodeId, portType, portIndex, PortRole::Caption);
- } else {
- auto portData = model.portData(nodeId, portType, portIndex, PortRole::DataType);
- s = portData.value<NodeDataType>().name;
- }
- painter->drawText(p, s);
- }
- }
- }
- void DefaultNodePainter::drawResizeRect(QPainter *painter, NodeGraphicsObject &ngo) const
- {
- AbstractGraphModel &model = ngo.graphModel();
- NodeId const nodeId = ngo.nodeId();
- AbstractNodeGeometry &geometry = ngo.nodeScene()->nodeGeometry();
- if (model.nodeFlags(nodeId) & NodeFlag::Resizable) {
- painter->setBrush(Qt::gray);
- painter->drawEllipse(geometry.resizeHandleRect(nodeId));
- }
- }
- } // namespace QtNodes
|