本文整理汇总了C++中QQuickItem::height方法的典型用法代码示例。如果您正苦于以下问题:C++ QQuickItem::height方法的具体用法?C++ QQuickItem::height怎么用?C++ QQuickItem::height使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QQuickItem
的用法示例。
在下文中一共展示了QQuickItem::height方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: implicitFill
void tst_applicationwindow::implicitFill()
{
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("fill.qml"));
QObject* created = component.create();
QScopedPointer<QObject> cleanup(created);
QVERIFY(created);
QQuickWindow* window = qobject_cast<QQuickWindow*>(created);
QVERIFY(window);
QVERIFY(!window->isVisible());
QCOMPARE(window->width(), 400);
QCOMPARE(window->height(), 400);
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
QQuickItem *stackView = window->property("stackView").value<QQuickItem*>();
QVERIFY(stackView);
QCOMPARE(stackView->width(), 400.0);
QCOMPARE(stackView->height(), 400.0);
QQuickItem *nextItem = window->property("nextItem").value<QQuickItem*>();
QVERIFY(nextItem);
QVERIFY(QMetaObject::invokeMethod(window, "pushNextItem"));
QCOMPARE(nextItem->width(), 400.0);
QCOMPARE(nextItem->height(), 400.0);
}
示例2: QPointF
QQuickItem *GlobalFunctions::itemAt(QQuickItem* parent, int x, int y, QJSValue matcher)
{
if (!parent) return nullptr;
QList<QQuickItem *> children = QQuickItemPrivate::get(parent)->paintOrderChildItems();
for (int i = children.count() - 1; i >= 0; --i) {
QQuickItem *child = children.at(i);
// Map coordinates to the child element's coordinate space
QPointF point = parent->mapToItem(child, QPointF(x, y));
if (child->isVisible() && point.x() >= 0
&& child->width() >= point.x()
&& point.y() >= 0
&& child->height() >= point.y()) {
if (!matcher.isCallable()) return child;
QQmlEngine* engine = qmlEngine(child);
if (!engine) return child;
QJSValue newObj = engine->newQObject(child);
if (matcher.call(QJSValueList() << newObj).toBool()) {
return child;
}
}
}
return nullptr;
}
示例3: updatePositionMarker
void Tracking::updatePositionMarker()
{
if ( m_marbleQuickItem && m_positionMarker && m_positionMarkerType == Circle ) {
Coordinate* position = 0;
bool visible = (m_marbleQuickItem->model()->planetId() == QLatin1String("earth"));
if ( m_positionSource && m_positionSource->hasPosition() ) {
position = m_positionSource->position();
} else if ( hasLastKnownPosition() ) {
position = lastKnownPosition();
} else {
visible = false;
}
qreal x(0), y(0);
if ( position ) {
Marble::GeoDataCoordinates const pos( position->longitude(), position->latitude(), 0.0, GeoDataCoordinates::Degree );
visible = visible && m_marbleQuickItem->map()->viewport()->screenCoordinates( pos.longitude(), pos.latitude(), x, y );
QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker );
if ( item ) {
item->setVisible( visible );
if ( visible ) {
item->setX( x - item->width() / 2.0 );
item->setY( y - item->height() / 2.0 );
}
}
}
} else if ( m_positionMarkerType != Circle ) {
QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker );
if ( item ) {
item->setVisible( false );
}
}
}
示例4: TEST_FILE
void TestSimpleQmlLoad::loadScript1()
{
QQmlEngine *engine = new QQmlEngine;
const QString TEST_FILE(":/testqml/testscript1.qml");
QQmlComponent* component = load(engine, TEST_FILE);
QVERIFY(component);
QObject *myObject = component->create();
QQuickItem *item = qobject_cast<QQuickItem*>(myObject);
int width = item->width();
QVERIFY(width == 100);
int height = item->height();
QVERIFY(height == 201);
item->setWidth(15);
height = item->height();
QVERIFY(height == 31);
delete component;
delete engine;
}
示例5: layoutChildrenWithDefaultSize
void StretchColumn::layoutChildrenWithDefaultSize() {
//static int count = 0;
//qDebug() << "Column Default Size" << ++count;
Q_ASSERT(m_defaultSize != 0);
const QList<QQuickItem *> childrenList = childItems();
if (childrenList.isEmpty()) return;
const int contentWidth = width() - m_leftMargin - m_rightMargin;
qreal currY = 0;
for (QList<QQuickItem *>::const_iterator it = childrenList.constBegin(); it != childrenList.constEnd(); ++it) {
QQuickItem* child = (*it);
if (child == Q_NULLPTR || !child->isVisible()) {
continue;
}
// add spacing if it is not the first item:
if (currY > 0) {
currY += m_spacing;
}
if (currY != child->y()) child->setY(currY);
// check if item has a stretch proportion set:
if (child->implicitHeight() < 0) {
// yes -> set it to default size multiplied by relative size:
qreal newHeight = m_defaultSize * child->implicitHeight() * -1;
if (newHeight != child->height()) child->setHeight(newHeight);
}
// set width of all items to fill the layout:
if (m_leftMargin != child->x()) child->setX(m_leftMargin);
if (contentWidth != child->width()) child->setWidth(contentWidth);
currY += child->height();
}
// set implicit size to fit all items:
if (currY != implicitHeight()) setImplicitHeight(currY);
}
示例6: updatePolish
void QQuickStretchColumnContainer::updatePolish (void) {
const QList<QQuickItem *> childrenList = childItems ();
/// find items and stretchers
qreal tmpW = 0;
qreal tmpH = 0;
int nbItems = 0;
int nbStretch = 0;
for (QList<QQuickItem *>::const_iterator it = childrenList.constBegin (); it != childrenList.constEnd (); it++) {
QQuickItem * child = (* it);
if (child != Q_NULLPTR && !child->inherits ("QQuickRepeater") && child->isVisible ()) {
if (child->implicitWidth () > tmpW) {
tmpW = child->implicitWidth ();
}
if (child->implicitHeight () >= 0) {
tmpH += child->implicitHeight ();
}
else {
nbStretch++;
}
nbItems++;
}
}
/// resize layout
if (nbItems > 1) {
tmpH += (m_spacing * (nbItems -1));
}
setImplicitWidth (tmpW);
setImplicitHeight (tmpH);
const qreal layoutWidth = width ();
const qreal layoutHeight = height ();
const qreal autoSize = (nbStretch > 0 ? (layoutHeight - tmpH) / qreal (nbStretch) : 0);
/// position children
int currY = 0;
for (QList<QQuickItem *>::const_iterator it = childrenList.constBegin (); it != childrenList.constEnd (); it++) {
QQuickItem * child = (* it);
if (child != Q_NULLPTR && !child->inherits ("QQuickRepeater") && child->isVisible ()) {
if (currY) {
currY += m_spacing;
}
child->setY (currY);
child->setWidth (layoutWidth);
child->setHeight (child->implicitHeight () >= 0 ? child->implicitHeight () : autoSize);
currY += child->height ();
}
}
}
示例7: traverseObject
/*!
Traverse QObject based items.
*/
void SceneGraphTraverse::traverseObject(TasObject* objectInfo, QObject* object, TasCommand* command)
{
Q_UNUSED(command);
QQuickItem* item = qobject_cast<QQuickItem*>(object);
if (item) {
QQmlContext* context = QQmlEngine::contextForObject(object);
if (context) {
QString name = context->nameForObject(object);
objectInfo->addAttribute("QML_ID", name);
}
#ifdef USE_QTQML_PRIVATE_HEADERS
addTypeInfo(item, objectInfo);
#endif
mTraverseUtils->addObjectDetails(objectInfo, object);
objectInfo->addAttribute("objectType", TYPE_QSCENEGRAPH);
QPointF point = item->mapToScene(QPoint());
// needed for visualizer
objectInfo->addAttribute("x", (int)point.x());
objectInfo->addAttribute("y", (int)point.y());
objectInfo->addAttribute("x_absolute", (int)point.x());
objectInfo->addAttribute("y_absolute", (int)point.y());
objectInfo->addAttribute("x_relative", item->x());
objectInfo->addAttribute("y_relative", item->y());
// TODO already included?
objectInfo->addAttribute("width", item->width());
objectInfo->addAttribute("height", item->height());
}
}
示例8: layoutChildrenWithProportions
void StretchRow::layoutChildrenWithProportions() {
//static int count = 0;
//qDebug() << "Row Proportions" << ++count;
const QList<QQuickItem*> childrenList = childItems();
if (childrenList.isEmpty()) return;
if (width() <= 0) return;
int visibleItems = 0;
qreal availableForStretch = width() - m_leftMargin - m_rightMargin;
qreal sumStretchProportions = 0.0;
// iterate over all children and calculate available size to stretch items:
for (QList<QQuickItem *>::const_iterator it = childrenList.constBegin(); it != childrenList.constEnd(); ++it) {
QQuickItem* child = (*it);
if (child == Q_NULLPTR || !child->isVisible()) {
continue;
}
if (child->implicitWidth() >= 0) {
// no stretch proportion set -> leave size and remove it from available space:
availableForStretch -= child->width();
} else {
// a stretch proportion is set -> add it to sum:
sumStretchProportions += (child->implicitWidth() * -1);
}
visibleItems++;
}
// remove spacing from available space:
availableForStretch -= m_spacing * (visibleItems - 1);
const int layoutHeight = height();
QPointer<QQuickItem> lastStretchItem = nullptr;
qreal currX = m_leftMargin;
for (QList<QQuickItem *>::const_iterator it = childrenList.constBegin(); it != childrenList.constEnd(); ++it) {
QQuickItem* child = (*it);
if (child == Q_NULLPTR || !child->isVisible()) {
continue;
}
// add spacing if it is not the first item:
if (currX > 0) {
currX += m_spacing;
}
if (currX != child->x()) child->setX(currX);
// check if item has a stretch proportion set (if not do nothing):
if (child->implicitWidth() < 0) {
// get the stretch proportion:
qreal stretchProportion = (child->implicitWidth() * -1);
// calculate the relation of the total space available for stretched items
// that this item will use:
// (sumStretchProportion can not be 0 (in divison) because if this "if" is executed,
// there has been at least one item with a stretch proportion set)
qreal relationOfSpaceAvailableForStretch = stretchProportion / sumStretchProportions;
qreal newWidth = qRound(availableForStretch * relationOfSpaceAvailableForStretch);
if (newWidth != child->width()) child->setWidth(newWidth);
lastStretchItem = child;
}
// set height of all items to fill the layout:
if (layoutHeight != child->height()) child->setHeight(layoutHeight);
currX += child->width();
}
currX += m_rightMargin;
// check if last item fills whole remaining space in this layout:
// (can happen because of rounding mistakes)
if (lastStretchItem) {
double pxMissing = width() - currX;
if (pxMissing > 0.0001) {
// qInfo() << "StretchRow layout mismatch: " << pxMissing;
// it does not -> adjust it:
lastStretchItem->setWidth(lastStretchItem->width() + pxMissing);
}
}
}
示例9: reconfigureLayout
void QQuickComponentsLinearLayout::reconfigureLayout()
{
if (!isComponentComplete())
return;
const int count = m_items.count();
if (count == 0)
return;
qreal totalSpacing = 0;
qreal totalSizeHint = 0;
qreal totalMinimumSize = 0;
qreal totalMaximumSize = 0;
QVector<QQuickComponentsLayoutInfo> itemData;
for (int i = 0; i < count; i++) {
QQuickItem *item = m_items.at(i);
QObject *attached = qmlAttachedPropertiesObject<QQuickComponentsLayout>(item);
QQuickComponentsLayoutAttached *info = static_cast<QQuickComponentsLayoutAttached *>(attached);
QQuickComponentsLayoutInfo data;
if (m_orientation == Horizontal) {
data.sizeHint = item->implicitWidth();
data.minimumSize = info->minimumWidth();
data.maximumSize = info->maximumWidth();
data.expansive = (info->horizontalSizePolicy() == QQuickComponentsLayout::Expanding);
data.stretch = info->horizontalSizePolicy() == Expanding ? 1.0 : 0;
} else {
data.sizeHint = item->implicitHeight();
data.minimumSize = info->minimumHeight();
data.maximumSize = info->maximumHeight();
data.expansive = (info->verticalSizePolicy() == QQuickComponentsLayout::Expanding);
data.stretch = info->verticalSizePolicy() == Expanding ? 1.0 : 0;
}
itemData.append(data);
// sum
totalSizeHint += data.sizeHint;
totalMinimumSize += data.minimumSize;
totalMaximumSize += data.maximumSize;
// don't count last spacing
if (i < count - 1)
totalSpacing += data.spacing + m_spacing;
}
if (m_orientation == Horizontal) {
qDeclarativeLayoutCalculate(itemData, 0, count, 0, width(), m_spacing);
for (int i = 0; i < count; i++) {
QQuickItem *item = m_items.at(i);
const QQuickComponentsLayoutInfo &data = itemData.at(i);
item->setX(data.pos);
item->setY(height()/2 - item->height()/2);
item->setWidth(data.size);
}
} else {
qDeclarativeLayoutCalculate(itemData, 0, count, 0, height(), m_spacing);
for (int i = 0; i < count; i++) {
QQuickItem *item = m_items.at(i);
const QQuickComponentsLayoutInfo &data = itemData.at(i);
item->setY(data.pos);
item->setX(width()/2 - item->width()/2);
item->setHeight(data.size);
}
}
// propagate hints to upper levels
QObject *attached = qmlAttachedPropertiesObject<QQuickComponentsLayout>(this);
QQuickComponentsLayoutAttached *info = static_cast<QQuickComponentsLayoutAttached *>(attached);
if (m_orientation == Horizontal) {
setImplicitWidth(totalSizeHint);
info->setMinimumWidth(totalMinimumSize + totalSpacing);
info->setMaximumWidth(totalMaximumSize + totalSpacing);
} else {
setImplicitHeight(totalSizeHint);
info->setMinimumHeight(totalMinimumSize + totalSpacing);
info->setMaximumHeight(totalMaximumSize + totalSpacing);
}
}
示例10: transition
//.........这里部分代码省略.........
}
qreal scale = 1;
qreal rotation = 0;
bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
if (ok && !isRotate) {
if (transform.m11() == transform.m22())
scale = transform.m11();
else {
qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
} else if (ok && isRotate) {
if (transform.m11() == transform.m22())
scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
else {
qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
if (scale != 0)
rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
else {
qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
ok = false;
}
}
const QPointF &point = transform.map(QPointF(xAction.toValue.toReal(),yAction.toValue.toReal()));
qreal x = point.x();
qreal y = point.y();
if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
qreal w = target->width();
qreal h = target->height();
if (pc->widthIsSet() && i < actions.size() - 1)
w = actions[++i].toValue.toReal();
if (pc->heightIsSet() && i < actions.size() - 1)
h = actions[++i].toValue.toReal();
const QPointF &transformOrigin
= d->computeTransformOrigin(target->transformOrigin(), w,h);
qreal tempxt = transformOrigin.x();
qreal tempyt = transformOrigin.y();
QTransform t;
t.translate(-tempxt, -tempyt);
t.rotate(rotation);
t.scale(scale, scale);
t.translate(tempxt, tempyt);
const QPointF &offset = t.map(QPointF(0,0));
x += offset.x();
y += offset.y();
}
if (ok) {
//qDebug() << x << y << rotation << scale;
xAction.toValue = x;
yAction.toValue = y;
sAction.toValue = sAction.toValue.toReal() * scale;
rAction.toValue = rAction.toValue.toReal() + rotation;
}
}
}
}
if (data->actions.count()) {
QSequentialAnimationGroupJob *topLevelGroup = new QSequentialAnimationGroupJob;
QActionAnimation *viaAction = d->via ? new QActionAnimation : 0;
示例11: getScreenshot
void ScreenshotService::getScreenshot(TasCommandModel& model, TasResponse& response)
{
QListIterator<TasTarget*> i(model.targetList());
QString errorMsg = PARSE_ERROR;
QImage screenshot;
QString pictureFormat = "PNG";
while (i.hasNext()) {
TasTarget* commandTarget = i.next();
QString targetId = commandTarget->id();
QString targetType = commandTarget->type();
TasCommand* command = commandTarget->findCommand("Screenshot");
// are required for command completion
if (targetId.isEmpty() || targetType.isEmpty() || !command) {
continue;
}
if (!command->parameter("format").isEmpty()) {
pictureFormat = command->parameter("format");
}
if (!isFormatSupported(pictureFormat)) {
errorMsg = "Given format " + pictureFormat + "is not supported. Supported formats are: PNG, JPEG and BMP.";
break;
}
bool draw = (command->parameter("draw") == "true");
QWidget* widget = 0;
QQuickWindow* qtQuickWindow = 0;
WId winId = 0;
QRect rect(0,0,-1,-1);
errorMsg = "Taking screenshot failed!";
if (targetType == TYPE_GRAPHICS_VIEW) {
//TasLogger::logger()->debug("TYPE_GRAPHICS_VIEW Target id:" + targetId);
QGraphicsItem* item = findGraphicsItem(targetId);
if (item) {
QGraphicsView* view = getViewForItem(item);
if(view) {
ItemLocationDetails locationDetails = TestabilityUtils::getItemLocationDetails(item);
rect = QRect(locationDetails.windowPoint.x(),
locationDetails.windowPoint.y(),
locationDetails.width,
locationDetails.height);
if (draw) {
widget = view->window();
} else {
winId = view->window()->winId();
}
} else {
errorMsg = "Could not find a GraphicsView for the GraphicsItem!";
}
} else {
errorMsg = "Could not find the GraphicsItem!";
}
} else if (targetType == TYPE_STANDARD_VIEW) {
//TasLogger::logger()->debug("TYPE_STANDARD_VIEW about to find widget Target id:" + targetId);
widget = findWidget(targetId);
if (widget) {
if ((widget->isWindow() && !draw) || widget->inherits("QDesktopWidget")) {
winId = widget->winId();
widget = 0;
} else if (!draw) {
QPoint point = widget->mapToGlobal(QPoint(0,0));
QPoint windowPoint = widget->window()->mapFromGlobal(point);
rect = QRect(windowPoint.x(),
windowPoint.y(),
widget->rect().width(),
widget->rect().width());
winId = widget->window()->winId();
widget = 0;
}
} else {
TasLogger::logger()->debug("ScreenshotService::executeService application has no visible ui!");
errorMsg = "Application has no visible ui!";
}
} else if (targetType == TYPE_QSCENEGRAPH) {
QQuickItem* item = TestabilityUtils::findQuickItem(targetId);
if (item) {
QPointF offset = item->mapToScene(QPointF(0,0));
rect = QRect(-offset.x(), -offset.y(), item->width(), item->height());
qtQuickWindow = item->window();
}
} else {
//TasLogger::logger()->debug("TYPE_APPLICATION_VIEW about to find application window Target id:" + targetId);
widget = getApplicationWidget();
if (!widget) {
QWindow *window = getApplicationWindow();
//in case no window false, return the desktop
qtQuickWindow = qobject_cast<QQuickWindow *>(window);
if (!window) {
//.........这里部分代码省略.........
示例12: resizemodeitem
void tst_qquickwidget::resizemodeitem()
{
QWidget window;
window.setGeometry(0, 0, 400, 400);
QScopedPointer<QQuickWidget> view(new QQuickWidget);
view->setParent(&window);
view->setResizeMode(QQuickWidget::SizeRootObjectToView);
QCOMPARE(QSize(0,0), view->initialSize());
view->setSource(testFileUrl("resizemodeitem.qml"));
QQuickItem* item = qobject_cast<QQuickItem*>(view->rootObject());
QVERIFY(item);
window.show();
view->showNormal();
// initial size from root object
QCOMPARE(item->width(), 200.0);
QCOMPARE(item->height(), 200.0);
QCOMPARE(view->size(), QSize(200, 200));
QCOMPARE(view->size(), view->sizeHint());
QCOMPARE(view->size(), view->initialSize());
// size update from view
view->resize(QSize(80,100));
QTRY_COMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
QCOMPARE(view->size(), QSize(80, 100));
QCOMPARE(view->size(), view->sizeHint());
view->setResizeMode(QQuickWidget::SizeViewToRootObject);
// size update from view disabled
view->resize(QSize(60,80));
QCOMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
QTRY_COMPARE(view->size(), QSize(60, 80));
// size update from root object
item->setWidth(250);
item->setHeight(350);
QCOMPARE(item->width(), 250.0);
QCOMPARE(item->height(), 350.0);
QTRY_COMPARE(view->size(), QSize(250, 350));
QCOMPARE(view->size(), QSize(250, 350));
QCOMPARE(view->size(), view->sizeHint());
// reset window
window.hide();
view.reset(new QQuickWidget(&window));
view->setResizeMode(QQuickWidget::SizeViewToRootObject);
view->setSource(testFileUrl("resizemodeitem.qml"));
item = qobject_cast<QQuickItem*>(view->rootObject());
QVERIFY(item);
window.show();
view->showNormal();
// initial size for root object
QCOMPARE(item->width(), 200.0);
QCOMPARE(item->height(), 200.0);
QCOMPARE(view->size(), view->sizeHint());
QCOMPARE(view->size(), view->initialSize());
// size update from root object
item->setWidth(80);
item->setHeight(100);
QCOMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
QTRY_COMPARE(view->size(), QSize(80, 100));
QCOMPARE(view->size(), view->sizeHint());
// size update from root object disabled
view->setResizeMode(QQuickWidget::SizeRootObjectToView);
item->setWidth(60);
item->setHeight(80);
QCOMPARE(view->width(), 80);
QCOMPARE(view->height(), 100);
QCOMPARE(QSize(item->width(), item->height()), view->sizeHint());
// size update from view
view->resize(QSize(200,300));
QTRY_COMPARE(item->width(), 200.0);
QCOMPARE(item->height(), 300.0);
QCOMPARE(view->size(), QSize(200, 300));
QCOMPARE(view->size(), view->sizeHint());
window.hide();
// if we set a specific size for the view then it should keep that size
// for SizeRootObjectToView mode.
view.reset(new QQuickWidget(&window));
view->resize(300, 300);
view->setResizeMode(QQuickWidget::SizeRootObjectToView);
QCOMPARE(QSize(0,0), view->initialSize());
view->setSource(testFileUrl("resizemodeitem.qml"));
view->resize(300, 300);
item = qobject_cast<QQuickItem*>(view->rootObject());
QVERIFY(item);
window.show();
//.........这里部分代码省略.........
示例13: updatePaintNode
QSGNode* NodeConnectionLines::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) {
if (!m_nodeObject) return nullptr;
const QVector<QPointer<NodeBase>>& connectedNodes = m_nodeObject->getConnectedNodes();
int connectionCount = connectedNodes.size();
// -------------------- Prepare QSG Nodes:
QSGNode* parentNode = oldNode;
if (!oldNode) {
parentNode = new QSGNode();
} else {
// update color in case it changed:
// FIXME: is there a more efficient way to do this?
for (int i=0; i<parentNode->childCount(); ++i) {
QSGGeometryNode* childNode = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(i));
if (!childNode) continue;
QSGFlatColorMaterial* material = static_cast<QSGFlatColorMaterial*>(childNode->material());
if (!material) continue;
material->setColor(m_color);
}
}
// adapt child count:
int childCount = parentNode->childCount();
if (childCount < connectionCount) {
for (int i=0; i<(connectionCount - childCount); ++i) {
QSGGeometryNode* node = new QSGGeometryNode;
QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3);
geometry->setDrawingMode(GL_TRIANGLE_STRIP);
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
QSGFlatColorMaterial* material = new QSGFlatColorMaterial;
material->setColor(m_color);
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
parentNode->appendChildNode(node);
}
} else if (childCount > connectionCount) {
for (int i=0; i<(childCount - connectionCount); ++i) {
parentNode->removeChildNode(parentNode->childAtIndex(0));
}
}
Q_ASSERT(parentNode->childCount() == connectionCount);
// calculate common start point:
const QPointF p0(width(), height() / 2);
double widthOffset = m_lineWidth / 2;
//const QPointF posInScene = mapToScene(QPointF(0, 0));
for (int i=0; i<connectionCount; ++i) {
NodeBase* otherNode = connectedNodes[i];
if (!otherNode) continue;
QQuickItem* otherGuiItem = otherNode->getGuiItem();
if (!otherGuiItem) continue;
const QPointF p3 = mapFromItem(otherGuiItem, QPointF(-otherGuiItem->width() / 2, otherGuiItem->height() / 2));
int handleLength = std::max(50, std::min(int(p3.x() - p0.x()), 80));
const QPointF p1(p0.x() + handleLength, p0.y());
const QPointF p2(p3.x() - handleLength, p3.y());
// calculate reasonable segment count:
int segmentCount = qMax(16.0, qMin(qAbs(p3.y() - p0.y()) / 25, 50.0));
int verticesCount = segmentCount * 2;
QSGGeometryNode* qsgNode = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(i));
if (!qsgNode) continue;
QSGGeometry* geometry = qsgNode->geometry();
if (!geometry) continue;
geometry->allocate(verticesCount);
QSGGeometry::Point2D* vertices = geometry->vertexDataAsPoint2D();
// triangulate cubic bezier curve:
for (int i = 0; i < segmentCount; ++i) {
// t is the position on the line:
const qreal t = i / qreal(segmentCount - 1);
// pos is the point on the curve at "t":
const QPointF pos = calculateBezierPoint(t, p0, p1, p2, p3);
// normal is the normal vector at that point
const QPointF normal = normalFromTangent(calculateBezierTangent(t, p0, p1, p2, p3));
// first is a point offsetted in the normal direction by lineWidth / 2 from pos
const QPointF first = pos - normal * widthOffset;
// ssecond is a point offsetted in the negative normal direction by lineWidth / 2 from pos
const QPointF second = pos + normal * widthOffset;
// add first and second as vertices to this geometry:
vertices[i*2].set(first.x(), first.y());
vertices[i*2+1].set(second.x(), second.y());
}
// tell Scene Graph that this items needs to be drawn:
qsgNode->markDirty(QSGNode::DirtyGeometry);
}
return parentNode;
}