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;
}
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 ();
        }
    }
}
bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *item,const QPointF &sp, PropagateType sig)
{
    //Based off of QQuickWindow::deliverInitialMousePressEvent
    //But specific to MouseArea, so doesn't belong in window
    Q_Q(const QQuickMouseArea);
    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);

    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
        QPointF p = item->mapFromScene(sp);
        if (!item->contains(p))
            return false;
    }

    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
    for (int ii = children.count() - 1; ii >= 0; --ii) {
        QQuickItem *child = children.at(ii);
        if (!child->isVisible() || !child->isEnabled())
            continue;
        if (propagateHelper(ev, child, sp, sig))
            return true;
    }

    QQuickMouseArea* ma = qobject_cast<QQuickMouseArea*>(item);
    if (ma && ma != q && ma->isEnabled() && itemPrivate->acceptedMouseButtons() & ev->button()) {
        switch (sig) {
        case Click:
            if (!ma->d_func()->isClickConnected())
                return false;
            break;
        case DoubleClick:
            if (!ma->d_func()->isDoubleClickConnected())
                return false;
            break;
        case PressAndHold:
            if (!ma->d_func()->isPressAndHoldConnected())
                return false;
            break;
        }
        QPointF p = item->mapFromScene(sp);
        if (item->contains(p)) {
            ev->setX(p.x());
            ev->setY(p.y());
            ev->setAccepted(true);//It is connected, they have to explicitly ignore to let it slide
            switch (sig) {
            case Click: emit ma->clicked(ev); break;
            case DoubleClick: emit ma->doubleClicked(ev); break;
            case PressAndHold: emit ma->pressAndHold(ev); break;
            }
            if (ev->isAccepted())
                return true;
        }
    }
    return false;

}
Exemple #4
0
QVariant QuickItemModel::data(const QModelIndex& index, int role) const
{
  if (!index.isValid())
    return QVariant();

  QQuickItem *item = reinterpret_cast<QQuickItem*>(index.internalPointer());

  if (role == QuickItemModelRole::Visibility)
    return item->isVisible();

  return dataForObject(item, index, role);
}
void StretchRow::layoutChildrenWithDefaultSize() {
	//static int count = 0;
	//qDebug() << "Row Default Size" << ++count;
	Q_ASSERT(m_defaultSize != 0);

	const QList<QQuickItem *> childrenList = childItems();
	if (childrenList.isEmpty()) return;

    const int layoutHeight = height();
	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 (child->implicitWidth() < 0) {
			// yes -> set it to default size:
			qreal newWidth = m_defaultSize * child->implicitWidth() * -1;
			if (newWidth != child->width()) child->setWidth(newWidth);
		}
		// set height of all items to fill the layout:
		if (layoutHeight != child->height()) child->setHeight(layoutHeight);
		currX += child->width();
	}
	currX += m_rightMargin;

	// set implicit size to fit all items:
	if (currX != implicitWidth()) setImplicitWidth(currX);
}
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);
}
void TouchDispatcher::dispatchTouchBegin(
            QTouchDevice *device,
            Qt::KeyboardModifiers modifiers,
            const QList<QTouchEvent::TouchPoint> &touchPoints,
            QWindow *window,
            ulong timestamp)
{
    Q_ASSERT(m_status == NoActiveTouch);
    QQuickItem *targetItem = m_targetItem.data();

    if (!targetItem->isEnabled() || !targetItem->isVisible()) {
        ugDebug("Cannot dispatch touch event to " << targetItem << " because it's disabled or invisible.");
        return;
    }

    // Map touch points to targetItem coordinates
    QList<QTouchEvent::TouchPoint> targetTouchPoints = touchPoints;
    transformTouchPoints(targetTouchPoints, QQuickItemPrivate::get(targetItem)->windowToItemTransform());

    QScopedPointer<QTouchEvent> touchEvent(
            createQTouchEvent(QEvent::TouchBegin, device, modifiers, targetTouchPoints, window, timestamp));


    ugDebug("dispatching " << qPrintable(touchEventToString(touchEvent.data()))
            << " to " << targetItem);
    QCoreApplication::sendEvent(targetItem, touchEvent.data());


    if (touchEvent->isAccepted()) {
        ugDebug("Item accepted the touch event.");
        setStatus(DeliveringTouchEvents);
    } else if (targetItem->acceptedMouseButtons() & Qt::LeftButton) {
        ugDebug("Item rejected the touch event. Trying a QMouseEvent");
        // NB: Arbitrarily chose the first touch point to emulate the mouse pointer
        QScopedPointer<QMouseEvent> mouseEvent(
                touchToMouseEvent(QEvent::MouseButtonPress, targetTouchPoints.at(0), timestamp,
                                  modifiers, false /* transformNeeded */));
        Q_ASSERT(targetTouchPoints.at(0).state() == Qt::TouchPointPressed);

        ugDebug("dispatching " << qPrintable(mouseEventToString(mouseEvent.data()))
                << " to " << m_targetItem.data());
        QCoreApplication::sendEvent(targetItem, mouseEvent.data());
        if (mouseEvent->isAccepted()) {
            ugDebug("Item accepted the QMouseEvent.");
            setStatus(DeliveringMouseEvents);
            m_touchMouseId = targetTouchPoints.at(0).id();

            if (checkIfDoubleClicked(timestamp)) {
                QScopedPointer<QMouseEvent> doubleClickEvent(
                        touchToMouseEvent(QEvent::MouseButtonDblClick, targetTouchPoints.at(0), timestamp,
                                          modifiers, false /* transformNeeded */));
                ugDebug("dispatching " << qPrintable(mouseEventToString(doubleClickEvent.data()))
                        << " to " << m_targetItem.data());
                QCoreApplication::sendEvent(targetItem, doubleClickEvent.data());
            }

        } else {
            ugDebug("Item rejected the QMouseEvent.");
            setStatus(TargetRejectedTouches);
        }
    } else {
        ugDebug("Item rejected the touch event and does not accept mouse buttons.");
        setStatus(TargetRejectedTouches);
    }
}
Exemple #8
0
void Stats::updateStats(bool force) {
    QQuickItem* parent = parentItem();
    if (!force) {
        if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
            if (parent->isVisible()) {
                parent->setVisible(false);
            }
            return;
        } else if (!parent->isVisible()) {
            parent->setVisible(true);
        }
    }

    auto nodeList = DependencyManager::get<NodeList>();
    auto avatarManager = DependencyManager::get<AvatarManager>();
    // we need to take one avatar out so we don't include ourselves
    STAT_UPDATE(avatarCount, avatarManager->size() - 1);
    STAT_UPDATE(updatedAvatarCount, avatarManager->getNumAvatarsUpdated());
    STAT_UPDATE(notUpdatedAvatarCount, avatarManager->getNumAvatarsNotUpdated());
    STAT_UPDATE(serverCount, (int)nodeList->size());
    STAT_UPDATE_FLOAT(renderrate, qApp->getRenderLoopRate(), 0.1f);
    if (qApp->getActiveDisplayPlugin()) {
        auto displayPlugin = qApp->getActiveDisplayPlugin();
        auto stats = displayPlugin->getHardwareStats();
        STAT_UPDATE(appdropped, stats["app_dropped_frame_count"].toInt());
        STAT_UPDATE(longrenders, stats["long_render_count"].toInt());
        STAT_UPDATE(longsubmits, stats["long_submit_count"].toInt());
        STAT_UPDATE(longframes, stats["long_frame_count"].toInt());
        STAT_UPDATE_FLOAT(presentrate, displayPlugin->presentRate(), 0.1f);
        STAT_UPDATE_FLOAT(presentnewrate, displayPlugin->newFramePresentRate(), 0.1f);
        STAT_UPDATE_FLOAT(presentdroprate, displayPlugin->droppedFrameRate(), 0.1f);
        STAT_UPDATE_FLOAT(stutterrate, displayPlugin->stutterRate(), 0.1f);
    } else {
        STAT_UPDATE(appdropped, -1);
        STAT_UPDATE(longrenders, -1);
        STAT_UPDATE(longsubmits, -1);
        STAT_UPDATE(presentrate, -1);
        STAT_UPDATE(presentnewrate, -1);
        STAT_UPDATE(presentdroprate, -1);
    }
    STAT_UPDATE(gameLoopRate, (int)qApp->getGameLoopRate());

    auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
    STAT_UPDATE(packetInCount, (int)bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond());
    STAT_UPDATE(packetOutCount, (int)bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond());
    STAT_UPDATE_FLOAT(mbpsIn, (float)bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond() / 1000.0f, 0.01f);
    STAT_UPDATE_FLOAT(mbpsOut, (float)bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond() / 1000.0f, 0.01f);

    STAT_UPDATE_FLOAT(assetMbpsIn, (float)bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f);
    STAT_UPDATE_FLOAT(assetMbpsOut, (float)bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f);

    // Second column: ping
    SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
    SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
    SharedNodePointer assetServerNode = nodeList->soloNodeOfType(NodeType::AssetServer);
    SharedNodePointer messageMixerNode = nodeList->soloNodeOfType(NodeType::MessagesMixer);
    STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1); 
    const int mixerLossRate = (int)roundf(_audioStats->data()->getMixerStream()->lossRateWindow() * 100.0f);
    const int clientLossRate = (int)roundf(_audioStats->data()->getClientStream()->lossRateWindow() * 100.0f);
    const int largestLossRate = mixerLossRate > clientLossRate ? mixerLossRate : clientLossRate;
    STAT_UPDATE(audioPacketLoss, audioMixerNode ? largestLossRate : -1);
    STAT_UPDATE(avatarPing, avatarMixerNode ? avatarMixerNode->getPingMs() : -1);
    STAT_UPDATE(assetPing, assetServerNode ? assetServerNode->getPingMs() : -1);
    STAT_UPDATE(messagePing, messageMixerNode ? messageMixerNode->getPingMs() : -1);

    //// Now handle entity servers, since there could be more than one, we average their ping times
    int totalPingOctree = 0;
    int octreeServerCount = 0;
    int pingOctreeMax = 0;
    int totalEntityKbps = 0;
    nodeList->eachNode([&](const SharedNodePointer& node) {
        // TODO: this should also support entities
        if (node->getType() == NodeType::EntityServer) {
            totalPingOctree += node->getPingMs();
            totalEntityKbps += node->getInboundBandwidth();
            octreeServerCount++;
            if (pingOctreeMax < node->getPingMs()) {
                pingOctreeMax = node->getPingMs();
            }
        }
    });

    // update the entities ping with the average for all connected entity servers
    STAT_UPDATE(entitiesPing, octreeServerCount ? totalPingOctree / octreeServerCount : -1);

    // Third column, avatar stats
    auto myAvatar = avatarManager->getMyAvatar();
    glm::vec3 avatarPos = myAvatar->getWorldPosition();
    STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
    STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
    STAT_UPDATE_FLOAT(yaw, myAvatar->getBodyYaw(), 0.1f);
    if (_expanded || force) {
        SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
        if (avatarMixer) {
            STAT_UPDATE(avatarMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer)));
            STAT_UPDATE(avatarMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer)));
            STAT_UPDATE(avatarMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer)));
            STAT_UPDATE(avatarMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer)));
        } else {
            STAT_UPDATE(avatarMixerInKbps, -1);
            STAT_UPDATE(avatarMixerInPps, -1);
            STAT_UPDATE(avatarMixerOutKbps, -1);
            STAT_UPDATE(avatarMixerOutPps, -1);
        }
        STAT_UPDATE_FLOAT(myAvatarSendRate, avatarManager->getMyAvatarSendRate(), 0.1f);

        SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
        auto audioClient = DependencyManager::get<AudioClient>();
        if (audioMixerNode || force) {
            STAT_UPDATE(audioMixerKbps, (int)roundf(
                bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) +
                bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)));
            STAT_UPDATE(audioMixerPps, (int)roundf(
                bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer) +
                bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));

            STAT_UPDATE(audioMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer)));
            STAT_UPDATE(audioMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer)));
            STAT_UPDATE(audioMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)));
            STAT_UPDATE(audioMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));
            STAT_UPDATE(audioAudioInboundPPS, (int)audioClient->getAudioInboundPPS());
            STAT_UPDATE(audioSilentInboundPPS, (int)audioClient->getSilentInboundPPS());
            STAT_UPDATE(audioOutboundPPS, (int)audioClient->getAudioOutboundPPS());
            STAT_UPDATE(audioSilentOutboundPPS, (int)audioClient->getSilentOutboundPPS());
        } else {
            STAT_UPDATE(audioMixerKbps, -1);
            STAT_UPDATE(audioMixerPps, -1);
            STAT_UPDATE(audioMixerInKbps, -1);
            STAT_UPDATE(audioMixerInPps, -1);
            STAT_UPDATE(audioMixerOutKbps, -1);
            STAT_UPDATE(audioMixerOutPps, -1);
            STAT_UPDATE(audioOutboundPPS, -1);
            STAT_UPDATE(audioSilentOutboundPPS, -1);
            STAT_UPDATE(audioAudioInboundPPS, -1);
            STAT_UPDATE(audioSilentInboundPPS, -1);
        }
        STAT_UPDATE(audioCodec, audioClient->getSelectedAudioFormat());
        STAT_UPDATE(audioNoiseGate, audioClient->getNoiseGateOpen() ? "Open" : "Closed");

        STAT_UPDATE(entityPacketsInKbps, octreeServerCount ? totalEntityKbps / octreeServerCount : -1);

        auto loadingRequests = ResourceCache::getLoadingRequests();
        STAT_UPDATE(downloads, loadingRequests.size());
        STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit())
        STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
        STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
        STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
        

        // See if the active download urls have changed
        bool shouldUpdateUrls = _downloads != _downloadUrls.size();
        if (!shouldUpdateUrls) {
            for (int i = 0; i < _downloads; i++) {
                if (loadingRequests[i]->getURL().toString() != _downloadUrls[i]) {
                    shouldUpdateUrls = true;
                    break;
                }
            }
        }
        // If the urls have changed, update the list
        if (shouldUpdateUrls) {
            _downloadUrls.clear();
            foreach (const auto& resource, loadingRequests) {
                _downloadUrls << resource->getURL().toString();
            }
            emit downloadUrlsChanged();
        }
        // TODO fix to match original behavior
        //stringstream downloads;
        //downloads << "Downloads: ";
        //foreach(Resource* resource, ) {
        //    downloads << (int)(resource->getProgress() * 100.0f) << "% ";
        //}
        //downloads << "(" <<  << " pending)";
    } // expanded avatar column
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);
		}
	}
}
void QmlProfilerTraceView::setZoomSliderVisible(bool visible)
{
    QQuickItem *zoomSlider = d->m_mainView->rootObject()->findChild<QQuickItem*>(QLatin1String("zoomSliderToolBar"));
    if (zoomSlider->isVisible() != visible)
        zoomSlider->setVisible(visible);
}