Files
nodeeditor/src/NodeGeometry.cpp
T

272 lines
4.9 KiB
C++
Raw Normal View History

2015-12-13 21:42:10 +01:00
#include "NodeGeometry.hpp"
#include <iostream>
2016-10-06 12:06:10 +02:00
#include <cmath>
2016-04-20 23:18:10 +02:00
#include "PortType.hpp"
2015-12-20 17:46:00 +01:00
#include "NodeState.hpp"
#include "NodeDataModel.hpp"
2015-12-20 17:46:00 +01:00
2016-12-01 16:55:10 +01:00
#include "StyleCollection.hpp"
2015-12-13 21:42:10 +01:00
NodeGeometry::
NodeGeometry(std::unique_ptr<NodeDataModel> const &dataModel)
2015-12-13 21:42:10 +01:00
: _width(100)
, _height(150)
2016-06-05 22:16:43 +02:00
, _inputPortWidth(70)
, _outputPortWidth(70)
2015-12-13 21:42:10 +01:00
, _entryHeight(20)
, _spacing(20)
2015-12-13 21:42:10 +01:00
, _hovered(false)
, _nSources(dataModel->nPorts(PortType::Out))
, _nSinks(dataModel->nPorts(PortType::In))
2015-12-13 22:39:37 +01:00
, _draggingPos(-1000, -1000)
, _dataModel(dataModel)
, _fontMetrics(QFont())
2016-12-22 13:17:40 +01:00
, _boldFontMetrics(QFont())
{
QFont f; f.setBold(true);
_boldFontMetrics = QFontMetrics(f);
}
2015-12-13 21:42:10 +01:00
QRectF
NodeGeometry::
entryBoundingRect() const
{
double const addon = 0.0;
2015-12-13 21:42:10 +01:00
return QRectF(0 - addon,
0 - addon,
_entryWidth + 2 * addon,
_entryHeight + 2 * addon);
}
QRectF
NodeGeometry::
boundingRect() const
{
2016-12-01 16:55:10 +01:00
auto const &nodeStyle = StyleCollection::nodeStyle();
double addon = 4 * nodeStyle.ConnectionPointDiameter;
2015-12-13 21:42:10 +01:00
return QRectF(0 - addon,
0 - addon,
_width + 2 * addon,
_height + 2 * addon);
}
void
NodeGeometry::
recalculateSize() const
2015-12-13 21:42:10 +01:00
{
_entryHeight = _fontMetrics.height();
2015-12-13 21:42:10 +01:00
{
unsigned int maxNumOfEntries = std::max(_nSinks, _nSources);
unsigned int step = _entryHeight + _spacing;
_height = step * maxNumOfEntries;
}
2015-12-20 22:49:55 +01:00
if (auto w = _dataModel->embeddedWidget())
{
_height = std::max(_height, static_cast<unsigned>(w->height()));
}
2016-12-22 13:17:40 +01:00
_height += captionHeight();
2016-08-22 22:20:34 +02:00
_inputPortWidth = portWidth(PortType::In);
_outputPortWidth = portWidth(PortType::Out);
2015-12-13 21:42:10 +01:00
2016-06-05 22:16:43 +02:00
_width = _inputPortWidth +
_outputPortWidth +
2 * _spacing;
2016-05-30 16:37:11 +02:00
if (auto w = _dataModel->embeddedWidget())
{
_width += w->width();
}
2016-12-22 13:17:40 +01:00
_width = std::max(_width, captionWidth());
}
void
NodeGeometry::
2016-12-22 13:17:40 +01:00
recalculateSize(QFont const & font) const
{
2016-12-22 13:17:40 +01:00
QFontMetrics fontMetrics(font);
QFont boldFont = font;
boldFont.setBold(true);
QFontMetrics boldFontMetrics(boldFont);
if (_boldFontMetrics != boldFontMetrics)
{
_fontMetrics = fontMetrics;
2016-12-22 13:17:40 +01:00
_boldFontMetrics = boldFontMetrics;
recalculateSize();
}
2015-12-13 21:42:10 +01:00
}
QPointF
NodeGeometry::
portScenePosition(int index,
PortType portType,
QTransform t) const
2015-12-13 21:42:10 +01:00
{
2016-12-01 16:55:10 +01:00
auto const &nodeStyle = StyleCollection::nodeStyle();
2015-12-13 21:42:10 +01:00
unsigned int step = _entryHeight + _spacing;
2015-12-20 17:46:00 +01:00
QPointF result;
2016-08-22 22:20:34 +02:00
double totalHeight = 0.0;
2016-12-22 13:17:40 +01:00
totalHeight += captionHeight();
2016-08-22 22:20:34 +02:00
totalHeight += step * index;
// TODO: why?
totalHeight += step / 2.0;
2016-04-20 23:18:10 +02:00
switch (portType)
2015-12-13 21:42:10 +01:00
{
case PortType::Out:
2015-12-13 21:42:10 +01:00
{
double x = _width + nodeStyle.ConnectionPointDiameter;
2015-12-13 21:42:10 +01:00
2015-12-20 17:46:00 +01:00
result = QPointF(x, totalHeight);
2015-12-13 21:42:10 +01:00
break;
}
case PortType::In:
2015-12-13 21:42:10 +01:00
{
double x = 0.0 - nodeStyle.ConnectionPointDiameter;
2015-12-13 21:42:10 +01:00
2015-12-20 17:46:00 +01:00
result = QPointF(x, totalHeight);
2015-12-13 21:42:10 +01:00
break;
}
default:
break;
}
2015-12-20 17:46:00 +01:00
return t.map(result);
2015-12-13 21:42:10 +01:00
}
2015-12-13 22:39:37 +01:00
2016-04-20 23:18:10 +02:00
PortIndex
2015-12-20 17:46:00 +01:00
NodeGeometry::
2016-04-20 23:18:10 +02:00
checkHitScenePoint(PortType portType,
2016-04-15 22:40:45 +02:00
QPointF const scenePoint,
QTransform sceneTransform) const
2015-12-20 17:46:00 +01:00
{
2016-12-01 16:55:10 +01:00
auto const &nodeStyle = StyleCollection::nodeStyle();
2016-04-20 23:18:10 +02:00
PortIndex result = INVALID;
2015-12-20 17:46:00 +01:00
if (portType == PortType::None)
2015-12-20 17:46:00 +01:00
return result;
double const tolerance = 2.0 * nodeStyle.ConnectionPointDiameter;
2015-12-20 17:46:00 +01:00
2016-06-05 22:16:43 +02:00
size_t const nItems = _dataModel->nPorts(portType);
2015-12-20 17:46:00 +01:00
for (size_t i = 0; i < nItems; ++i)
{
auto pp = portScenePosition(i, portType, sceneTransform);
QPointF p = pp - scenePoint;
auto distance = std::sqrt(QPointF::dotProduct(p, p));
2015-12-20 17:46:00 +01:00
if (distance < tolerance)
{
2016-04-20 23:18:10 +02:00
result = PortIndex(i);
2015-12-20 17:46:00 +01:00
break;
}
}
return result;
}
2016-05-31 22:55:28 +02:00
2016-09-18 15:05:14 +02:00
QRect
NodeGeometry::
resizeRect() const
{
unsigned int rectSize = 7;
return QRect(_width - rectSize,
_height - rectSize,
rectSize,
rectSize);
}
2016-05-31 22:55:28 +02:00
QPointF
NodeGeometry::
widgetPosition() const
{
if (auto w = _dataModel->embeddedWidget())
{
return QPointF(_spacing + portWidth(PortType::In),
2016-12-22 13:17:40 +01:00
(captionHeight() + _height - w->height()) / 2.0);
2016-05-31 22:55:28 +02:00
}
return QPointF();
}
2016-08-22 22:20:34 +02:00
unsigned int
NodeGeometry::
2016-12-22 13:17:40 +01:00
captionHeight() const
2016-08-22 22:20:34 +02:00
{
2016-09-23 09:45:07 +02:00
if (!_dataModel->captionVisible())
2016-08-22 22:20:34 +02:00
return 0;
2016-09-23 09:45:07 +02:00
QString name = _dataModel->caption();
2016-12-22 13:17:40 +01:00
return _boldFontMetrics.boundingRect(name).height();
}
unsigned int
NodeGeometry::
captionWidth() const
{
if (!_dataModel->captionVisible())
return 0;
QString name = _dataModel->caption();
return _boldFontMetrics.boundingRect(name).width();
2016-08-22 22:20:34 +02:00
}
2016-05-31 22:55:28 +02:00
unsigned int
NodeGeometry::
portWidth(PortType portType) const
{
unsigned width = 0;
2016-06-05 22:16:43 +02:00
for (auto i = 0ul; i < _dataModel->nPorts(portType); ++i)
2016-05-31 22:55:28 +02:00
{
QString name;
if (_dataModel->portCaptionVisible(portType, i))
name = _dataModel->portCaption(portType, i);
else
name = _dataModel->dataType(portType, i).name;
2016-05-31 22:55:28 +02:00
width = std::max(unsigned(_fontMetrics.width(name)),
width);
}
return width;
}