Qt 6.x
The Qt SDK
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
144{
146}
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 setGridScaledImage(QQuickGridScaledImage(&file));
281 } else {
282#if QT_CONFIG(qml_network)
283 d->setProgress(0);
284 d->setStatus(Loading);
285
286 QNetworkRequest req(d->url);
287 d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
288 qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
289 this, QQuickBorderImage, SLOT(sciRequestFinished()));
290#endif
291 }
292 } else {
293 loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
294 }
295 }
296}
297
329{
331 return d->getScaleGrid();
332}
333
347{
348 Q_D(const QQuickBorderImage);
349 return d->horizontalTileMode;
350}
351
353{
355 if (t != d->horizontalTileMode) {
356 d->horizontalTileMode = t;
358 update();
359 }
360}
361
363{
364 Q_D(const QQuickBorderImage);
365 return d->verticalTileMode;
366}
367
369{
371 if (t != d->verticalTileMode) {
372 d->verticalTileMode = t;
374 update();
375 }
376}
377
378void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
379{
381 if (!sci.isValid()) {
382 d->setStatus(Error);
383 } else {
384 QQuickScaleGrid *sg = border();
385 sg->setTop(sci.gridTop());
386 sg->setBottom(sci.gridBottom());
387 sg->setLeft(sci.gridLeft());
388 sg->setRight(sci.gridRight());
389 d->horizontalTileMode = sci.horizontalTileRule();
390 d->verticalTileMode = sci.verticalTileRule();
391
392 d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
393 loadPixmap(d->sciurl);
394 }
395}
396
398{
400
401 QSize impsize = d->pix.implicitSize();
402 if (d->pix.isError()) {
403 qmlWarning(this) << d->pix.error();
404 d->setStatus(Error);
405 d->setProgress(0);
406 } else {
407 d->setStatus(Ready);
408 d->setProgress(1);
409 }
410
411 setImplicitSize(impsize.width() / d->devicePixelRatio, impsize.height() / d->devicePixelRatio);
412
413 if (sourceSize() != d->oldSourceSize) {
414 d->oldSourceSize = sourceSize();
416 }
417 if (d->frameCount != d->pix.frameCount()) {
418 d->frameCount = d->pix.frameCount();
419 emit frameCountChanged();
420 }
421
422 pixmapChange();
423}
424
425#if QT_CONFIG(qml_network)
426void QQuickBorderImage::sciRequestFinished()
427{
429
430 if (d->sciReply->error() != QNetworkReply::NoError) {
431 d->setStatus(Error);
432 d->sciReply->deleteLater();
433 d->sciReply = nullptr;
434 } else {
435 QQuickGridScaledImage sci(d->sciReply);
436 d->sciReply->deleteLater();
437 d->sciReply = nullptr;
438 setGridScaledImage(sci);
439 }
440}
441#endif // qml_network
442
443void QQuickBorderImage::doUpdate()
444{
445 update();
446}
447
449 const QSize &sourceSize,
450 const QSizeF &targetSize,
451 int horizontalTileMode,
452 int verticalTileMode,
453 qreal devicePixelRatio,
454 QRectF *targetRect,
455 QRectF *innerTargetRect,
456 QRectF *innerSourceRect,
457 QRectF *subSourceRect)
458{
459 *innerSourceRect = QRectF(0, 0, 1, 1);
460 *targetRect = QRectF(0, 0, targetSize.width(), targetSize.height());
461 *innerTargetRect = *targetRect;
462
463 if (border) {
464 qreal borderLeft = border->left() * devicePixelRatio;
465 qreal borderRight = border->right() * devicePixelRatio;
466 qreal borderTop = border->top() * devicePixelRatio;
467 qreal borderBottom = border->bottom() * devicePixelRatio;
468 if (borderLeft + borderRight > sourceSize.width() && borderLeft < sourceSize.width())
469 borderRight = sourceSize.width() - borderLeft;
470 if (borderTop + borderBottom > sourceSize.height() && borderTop < sourceSize.height())
471 borderBottom = sourceSize.height() - borderTop;
472 *innerSourceRect = QRectF(QPointF(borderLeft / qreal(sourceSize.width()),
473 borderTop / qreal(sourceSize.height())),
474 QPointF((sourceSize.width() - borderRight) / qreal(sourceSize.width()),
475 (sourceSize.height() - borderBottom) / qreal(sourceSize.height()))),
476 *innerTargetRect = QRectF(border->left(),
477 border->top(),
478 qMax<qreal>(0, targetSize.width() - (border->right() + border->left())),
479 qMax<qreal>(0, targetSize.height() - (border->bottom() + border->top())));
480 }
481
482 qreal hTiles = 1;
483 qreal vTiles = 1;
484 const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio;
485 if (innerSourceRect->width() <= 0)
486 hTiles = 0;
488 hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width());
490 hTiles = qCeil(hTiles);
491 }
492 if (innerSourceRect->height() <= 0)
493 vTiles = 0;
495 vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height());
497 vTiles = qCeil(vTiles);
498 }
499
500 *subSourceRect = QRectF(0, 0, hTiles, vTiles);
501}
502
503
505{
507
508 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
509
510 if (!texture || width() <= 0 || height() <= 0) {
511 delete oldNode;
512 return nullptr;
513 }
514
515 QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode);
516
517 bool updatePixmap = d->pixmapChanged;
518 d->pixmapChanged = false;
519 if (!node) {
520 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
521 updatePixmap = true;
522 }
523
524 if (updatePixmap)
525 node->setTexture(texture);
526
527 // Don't implicitly create the scalegrid in the rendering thread...
528 QRectF targetRect;
529 QRectF innerTargetRect;
530 QRectF innerSourceRect;
531 QRectF subSourceRect;
532 d->calculateRects(d->border,
533 QSize(d->pix.width(), d->pix.height()), QSizeF(width(), height()),
534 d->horizontalTileMode, d->verticalTileMode, d->devicePixelRatio,
535 &targetRect, &innerTargetRect,
536 &innerSourceRect, &subSourceRect);
537
538 node->setTargetRect(targetRect);
539 node->setInnerSourceRect(innerSourceRect);
540 node->setInnerTargetRect(innerTargetRect);
541 node->setSubSourceRect(subSourceRect);
542 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
543
546 if (innerSourceRect == QRectF(0, 0, 1, 1) && (subSourceRect.width() > 1 || subSourceRect.height() > 1)) {
549 } else {
552 }
553 node->setAntialiasing(d->antialiasing);
554 node->update();
555
556 return node;
557}
558
560{
562 d->pixmapChanged = true;
563 update();
564}
565
579
580#include "moc_qquickborderimage_p.cpp"
\inmodule QtCore
Definition qfile.h:93
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:881
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:214
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 QFile.
Definition qqmlfile.cpp:643
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
QQuickBorderImage::TileMode horizontalTileRule() const
QQuickBorderImage::TileMode verticalTileRule() const
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:64
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:76
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:77
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:483
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:496
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:721
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:207
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
Definition qurl.h:94
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:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
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:76
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:71
#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:92
QFile file
[0]
QUrl url("example.com")
[constructor-url-reference]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent