Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickborderimage.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtQml/qqmlinfo.h>
8#include <QtQml/qqmlfile.h>
9#include <QtQml/qqmlengine.h>
10#if QT_CONFIG(qml_network)
11#include <QtNetwork/qnetworkreply.h>
12#endif
13#include <QtCore/qfile.h>
14#include <QtCore/qmath.h>
15#include <QtGui/qguiapplication.h>
16
17#include <private/qqmlglobal_p.h>
18#include <private/qsgadaptationlayer_p.h>
19
21
22
147
149{
150#if QT_CONFIG(qml_network)
152 if (d->sciReply)
153 d->sciReply->deleteLater();
154#endif
155}
156
245{
247
248 if (url == d->url)
249 return;
250
251#if QT_CONFIG(qml_network)
252 if (d->sciReply) {
253 d->sciReply->deleteLater();
254 d->sciReply = nullptr;
255 }
256#endif
257
258 d->url = url;
259 d->sciurl = QUrl();
260 emit sourceChanged(d->url);
261
263 load();
264}
265
267{
269
270 if (d->url.isEmpty()) {
271 loadEmptyUrl();
272 } else {
273 if (d->url.path().endsWith(QLatin1String("sci"))) {
274 const QQmlContext *context = qmlContext(this);
275 QString lf = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(d->url)
276 : d->url);
277 if (!lf.isEmpty()) {
278 QFile file(lf);
280 d->setStatus(Error);
281 else
282 setGridScaledImage(QQuickGridScaledImage(&file));
283 } else {
284#if QT_CONFIG(qml_network)
285 d->setProgress(0);
286 d->setStatus(Loading);
287
288 QNetworkRequest req(d->url);
289 d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
290 qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
291 this, QQuickBorderImage, SLOT(sciRequestFinished()));
292#endif
293 }
294 } else {
295 loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
296 }
297 }
298}
299
331{
333 return d->getScaleGrid();
334}
335
349{
350 Q_D(const QQuickBorderImage);
351 return d->horizontalTileMode;
352}
353
355{
357 if (t != d->horizontalTileMode) {
358 d->horizontalTileMode = t;
360 update();
361 }
362}
363
365{
366 Q_D(const QQuickBorderImage);
367 return d->verticalTileMode;
368}
369
371{
373 if (t != d->verticalTileMode) {
374 d->verticalTileMode = t;
376 update();
377 }
378}
379
380void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
381{
383 if (!sci.isValid()) {
384 d->setStatus(Error);
385 } else {
386 QQuickScaleGrid *sg = border();
387 sg->setTop(sci.gridTop());
388 sg->setBottom(sci.gridBottom());
389 sg->setLeft(sci.gridLeft());
390 sg->setRight(sci.gridRight());
391 d->horizontalTileMode = sci.horizontalTileRule();
392 d->verticalTileMode = sci.verticalTileRule();
393
394 d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
395 loadPixmap(d->sciurl);
396 }
397}
398
400{
402
403 if (d->pendingPix != d->currentPix) {
404 std::swap(d->pendingPix, d->currentPix);
405 d->pendingPix->clear(this); // Clear the old image
406 }
407
408 const QSize impsize = d->currentPix->implicitSize();
409 setImplicitSize(impsize.width() / d->devicePixelRatio, impsize.height() / d->devicePixelRatio);
410
411 if (d->currentPix->isError()) {
412 qmlWarning(this) << d->currentPix->error();
413 d->setStatus(Error);
414 d->setProgress(0);
415 } else {
416 d->setStatus(Ready);
417 d->setProgress(1);
418 }
419
420 if (sourceSize() != d->oldSourceSize) {
421 d->oldSourceSize = sourceSize();
423 }
424 if (d->frameCount != d->currentPix->frameCount()) {
425 d->frameCount = d->currentPix->frameCount();
426 emit frameCountChanged();
427 }
428
429 pixmapChange();
430}
431
432#if QT_CONFIG(qml_network)
433void QQuickBorderImage::sciRequestFinished()
434{
436
437 if (d->sciReply->error() != QNetworkReply::NoError) {
438 d->setStatus(Error);
439 d->sciReply->deleteLater();
440 d->sciReply = nullptr;
441 } else {
442 QQuickGridScaledImage sci(d->sciReply);
443 d->sciReply->deleteLater();
444 d->sciReply = nullptr;
445 setGridScaledImage(sci);
446 }
447}
448#endif // qml_network
449
450void QQuickBorderImage::doUpdate()
451{
452 update();
453}
454
456 const QSize &sourceSize,
457 const QSizeF &targetSize,
458 int horizontalTileMode,
459 int verticalTileMode,
460 qreal devicePixelRatio,
461 QRectF *targetRect,
462 QRectF *innerTargetRect,
463 QRectF *innerSourceRect,
464 QRectF *subSourceRect)
465{
466 *innerSourceRect = QRectF(0, 0, 1, 1);
467 *targetRect = QRectF(0, 0, targetSize.width(), targetSize.height());
468 *innerTargetRect = *targetRect;
469
470 if (border) {
471 qreal borderLeft = border->left() * devicePixelRatio;
472 qreal borderRight = border->right() * devicePixelRatio;
473 qreal borderTop = border->top() * devicePixelRatio;
474 qreal borderBottom = border->bottom() * devicePixelRatio;
475 if (borderLeft + borderRight > sourceSize.width() && borderLeft < sourceSize.width())
476 borderRight = sourceSize.width() - borderLeft;
477 if (borderTop + borderBottom > sourceSize.height() && borderTop < sourceSize.height())
478 borderBottom = sourceSize.height() - borderTop;
479 *innerSourceRect = QRectF(QPointF(borderLeft / qreal(sourceSize.width()),
480 borderTop / qreal(sourceSize.height())),
481 QPointF((sourceSize.width() - borderRight) / qreal(sourceSize.width()),
482 (sourceSize.height() - borderBottom) / qreal(sourceSize.height()))),
483 *innerTargetRect = QRectF(border->left(),
484 border->top(),
485 qMax<qreal>(0, targetSize.width() - (border->right() + border->left())),
486 qMax<qreal>(0, targetSize.height() - (border->bottom() + border->top())));
487 }
488
489 qreal hTiles = 1;
490 qreal vTiles = 1;
491 const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio;
492 if (innerSourceRect->width() <= 0)
493 hTiles = 0;
495 hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width());
497 hTiles = qCeil(hTiles);
498 }
499 if (innerSourceRect->height() <= 0)
500 vTiles = 0;
502 vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height());
504 vTiles = qCeil(vTiles);
505 }
506
507 *subSourceRect = QRectF(0, 0, hTiles, vTiles);
508}
509
510
512{
514
515 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
516
517 if (!texture || width() <= 0 || height() <= 0) {
518 delete oldNode;
519 return nullptr;
520 }
521
522 QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode);
523
524 bool updatePixmap = d->pixmapChanged;
525 d->pixmapChanged = false;
526 if (!node) {
527 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
528 updatePixmap = true;
529 }
530
531 if (updatePixmap)
532 node->setTexture(texture);
533
534 // Don't implicitly create the scalegrid in the rendering thread...
535 QRectF targetRect;
536 QRectF innerTargetRect;
537 QRectF innerSourceRect;
538 QRectF subSourceRect;
539 d->calculateRects(d->border,
540 QSize(d->currentPix->width(), d->currentPix->height()), QSizeF(width(), height()),
541 d->horizontalTileMode, d->verticalTileMode, d->devicePixelRatio,
542 &targetRect, &innerTargetRect,
543 &innerSourceRect, &subSourceRect);
544
545 node->setTargetRect(targetRect);
546 node->setInnerSourceRect(innerSourceRect);
547 node->setInnerTargetRect(innerTargetRect);
548 node->setSubSourceRect(subSourceRect);
549 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
550
553 if (innerSourceRect == QRectF(0, 0, 1, 1) && (subSourceRect.width() > 1 || subSourceRect.height() > 1)) {
556 } else {
559 }
560 node->setAntialiasing(d->antialiasing);
561 node->update();
562
563 return node;
564}
565
567{
569 d->pixmapChanged = true;
570 update();
571}
572
593
594#include "moc_qquickborderimage_p.cpp"
\inmodule QtCore
Definition qfile.h:93
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:904
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
\inmodule QtCore\reentrant
Definition qpoint.h:217
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
QQuickBorderImage::TileMode verticalTileMode
static void calculateRects(const QQuickScaleGrid *border, const QSize &sourceSize, const QSizeF &targetSize, int horizontalTileMode, int verticalTileMode, qreal devicePixelRatio, QRectF *targetRect, QRectF *innerTargetRect, QRectF *innerSourceRect, QRectF *subSourceRect)
QQuickBorderImage::TileMode horizontalTileMode
void sourceSizeChanged()
void setHorizontalTileMode(TileMode)
void verticalTileModeChanged()
QQuickBorderImage(QQuickItem *parent=nullptr)
\qmltype BorderImage \instantiates QQuickBorderImage \inqmlmodule QtQuick
QSGNode * updatePaintNode(QSGNode *, UpdatePaintNodeData *) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void pixmapChange() override
void setSource(const QUrl &url) override
\qmlproperty enumeration QtQuick::BorderImage::status
void requestFinished() override
void horizontalTileModeChanged()
void setVerticalTileMode(TileMode)
QQuickScaleGrid * border
void sourceSizeChanged()
void loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions=NoOption)
void sourceChanged(const QUrl &)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
qreal height
This property holds the height of this item.
Definition qquickitem.h:76
void update()
Schedules a call to updatePaintNode() for this item.
void setImplicitSize(qreal, qreal)
The QQuickScaleGrid class allows you to specify a 3x3 grid to use in scaling an image.
\inmodule QtCore\reentrant
Definition qrect.h:484
virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)=0
virtual void setTexture(QSGTexture *texture)=0
virtual void setTargetRect(const QRectF &rect)=0
virtual void setFiltering(QSGTexture::Filtering filtering)=0
virtual void setInnerSourceRect(const QRectF &rect)=0
virtual void update()=0
virtual void setSubSourceRect(const QRectF &rect)=0
virtual void setInnerTargetRect(const QRectF &rect)=0
virtual void setAntialiasing(bool antialiasing)
virtual void setMipmapFiltering(QSGTexture::Filtering filtering)=0
virtual void setMirror(bool horizontally, bool vertically)=0
virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode)=0
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
\inmodule QtQuick
Definition qsgtexture.h:20
\inmodule QtCore
Definition qsize.h:208
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:332
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:335
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
Definition qurl.h:94
QString url(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2817
Combined button and popup list for selecting options.
static void * context
int qCeil(T v)
Definition qmath.h:36
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLenum GLsizei GLsizei GLsizei GLint border
GLenum GLuint texture
GLdouble GLdouble t
Definition qopenglext.h:243
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method)
Connect Signal of Sender to Method of Receiver.
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define emit
double qreal
Definition qtypes.h:187
QFile file
[0]
QUrl url("example.com")
[constructor-url-reference]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)