Add a "refreshing" icon overlay for layout items which are

being redrawn/updated in the background

Gives immediate visual feedback to users that the current appearance
of those items are outdated and to wait while they update.
This commit is contained in:
Nyall Dawson 2023-03-09 13:52:59 +10:00
parent bf11dc1777
commit 885c0b6136
6 changed files with 62 additions and 0 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1960.148" height="1881.596" viewBox="0 0 1470.111 1411.197"><path d="M733.188 0C658.67 0 592.634 42.28 556.674 102.913c-9.04-1.247-18.174-2.116-27.474-2.116h-324C93.232 100.795 0 195.995 0 305.995c0 56.07 22.427 107.361 60.734 145.668 13.96 13.96 31.8 26.463 51.564 36.552-31.083 78.07-47.495 161.929-47.495 247.383v1.2c0 130.236 37.202 257.711 108.112 367.16a150.015 150.015 0 0 0 19.822 24.505c-4.844-4.843-6.84-6.975-9.6-9.836 1.161 1.673 1.937 2.799 3.326 4.789 6.072 8.696 12.683 18.426 22.82 31.095a150.028 150.028 0 0 0 11.054 12.349c-17.093-17.094-4.426-4.64-1.689-1.474 2.738 3.166 6.644 7.707 10.915 12.665 8.543 9.916 17.912 20.833 26.656 30.45 1.6 1.759 3.24 3.48 4.922 5.16 125.992 125.993 297.148 197.535 476.865 197.535 74.448 0 140.43-42.203 176.412-102.746 8.68 1.148 17.447 1.946 26.365 1.946h324c110.278 0 202.316-92.36 205.07-200.243 2.38-55.62-19.252-111.305-59.2-150.412l-.194-.21c-.18-.18-.401-.343-.582-.522-1.92-1.86-3.828-3.732-5.832-5.512l-.01.27c-12.866-11.633-28.183-22.132-45.139-30.788 31.083-78.07 47.495-161.928 47.495-247.382v-2.4c0-130.236-37.202-257.711-108.111-367.16a150.015 150.015 0 0 0-19.823-24.505c4.222 4.222 5.989 6.085 8.366 8.535-1.213-1.678-2.164-2.982-3.63-5.026a2824.753 2824.753 0 0 1-15.533-21.88 150.018 150.018 0 0 0-16.805-20.027c21.512 21.512 6.133 6.55 3.381 3.265-2.752-3.285-6.762-8.092-11.288-13.441-9.052-10.699-18.258-21.99-32.893-36.626l-.643-.639C1082.622 70.427 912.048 0 733.188 0Zm3.543 410.48c69.824.868 132.035 27.228 181.99 77.184h.003c23.96 26.345 24.378 28.39 34.406 43.045 8.922 13.686 16.276 28.062 22.312 42.85-14.669-3.1-29.207-4.76-43.057-4.76-1.92 0-3.84.037-5.76.111-108.838 4.184-202.641 99.119-198.119 212.277l-.085-2.731 4.779 219.83c-69.314-1.168-131.083-27.497-180.739-77.153l-.003-.003c-24.323-24.775-35.707-39.88-55.886-83.661 14.257 3.154 28.214 4.932 41.026 4.932 55.328 0 108.31-20.77 148.879-65.407 38.96-41.602 55.12-94.987 55.12-140.996 0-1.087-.011-2.174-.035-3.26zm461.662 760.211a149.933 149.933 0 0 0 4.226 4.685c-.543-.44-1.01-.874-1.517-1.313-.926-.915-1.864-1.818-2.75-2.767z" style="color:#000;fill:#fff;fill-opacity:.70069897;stroke:none;stroke-width:300;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.468781;-inkscape-stroke:none;paint-order:stroke fill markers"/><g style="fill:#000;fill-opacity:.700699;stroke:none;stroke-width:100;stroke-dasharray:none;stroke-opacity:.468781;paint-order:stroke fill markers"><path d="M604.8 1042.8c-110.4 0-213.6-43.199-291.6-121.2-9.602-9.602-31.199-34.801-32.398-37.199-7.2-8.398-21.602-28.801-21.602-30-105.6-162-82.801-379.2 54-516 1.2-1.2 22.801-21.602 31.199-27.602l3.602 220.8c0 14.398 6 28.801 16.8 39.602 10.802 10.801 24 15.602 39.603 15.602 14.398 0 28.8-6 38.398-16.801 10.8-10.801 15.602-25.199 15.602-39.602l-7.2-331.2c0-30-25.199-54-55.199-54h-324c-31.199 0-55.199 25.199-55.199 55.199 0 14.398 6 28.801 16.801 39.602 10.801 10.801 24 16.801 39.602 16.801h165.6l-12 13.199c-93.602 97.199-145.2 225.6-145.2 360v1.2c0 102 28.801 200.4 84 285.6 1.2 1.198 18 26.397 27.602 38.397 2.399 2.399 28.801 33.602 40.801 46.801 98.398 98.398 230.4 153.6 370.8 153.6 31.2 0 55.2-25.199 55.2-55.199-.012-30.008-24.013-57.605-55.212-57.605zM1171.2 960c-10.801-10.801-24-16.801-39.602-16.801h-165.6l12-13.199c93.602-97.199 145.2-225.6 145.2-360v-2.398c0-102-28.801-200.4-84-285.6-1.2-1.2-19.199-26.398-27.602-38.398-2.398-2.399-27.602-33.602-40.801-46.801-99.598-98.402-230.4-152.4-370.8-152.4-31.199 0-55.199 25.199-55.199 55.199 0 31.199 25.199 55.199 55.199 55.199 110.4 0 213.6 43.199 291.6 121.2 9.602 9.601 31.199 34.8 32.398 37.199 7.2 8.398 21.602 28.8 21.602 30 105.6 162 82.801 379.2-54 516-1.2 1.199-22.801 21.602-31.199 27.602l-4.8-219.6c0-14.398-6-28.801-16.802-38.398-10.8-10.801-25.199-15.602-39.602-15.602-31.199 1.199-55.199 26.398-54 56.398l7.2 331.2c0 30 25.198 54 55.198 54h324c31.2 0 55.2-25.2 55.2-55.2 1.203-15.593-4.797-29.991-15.599-39.593z" style="fill:#000;fill-opacity:.700699;stroke:none;stroke-width:100;stroke-dasharray:none;stroke-opacity:.468781;paint-order:stroke fill markers" transform="translate(133.194 105.597)"/></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -979,6 +979,7 @@
<file>themes/default/mIconFieldGeometry.svg</file>
<file>themes/default/algorithms/mAlgorithmRectanglesOvalsDiamonds.svg</file>
<file>themes/default/algorithms/mAlgorithmOffsetLines.svg</file>
<file>composer/refreshing_item.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>

View File

@ -1072,6 +1072,13 @@ Returns the clipping path generated by this item, in layout coordinates.
indicates if a particular item can function as a clipping path provider.
.. versionadded:: 3.16
%End
virtual bool isRefreshing() const;
%Docstring
Returns ``True`` if the item is currently refreshing content in the background.
.. versionadded:: 3.32
%End
public slots:
@ -1205,6 +1212,13 @@ Draws the frame around the item.
Draws the background for the item.
.. seealso:: :py:func:`framePath`
%End
void drawRefreshingOverlay( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle );
%Docstring
Draws a "refreshing" overlay icon on the item.
.. versionadded:: 3.2
%End
virtual void setFixedSize( const QgsLayoutSize &size );

View File

@ -30,6 +30,7 @@
#include "qgsimageoperation.h"
#include "qgsexpressioncontextutils.h"
#include "qgslayoutrendercontext.h"
#include "qgssvgcache.h"
#include <QPainter>
#include <QStyleOptionGraphicsItem>
@ -416,6 +417,11 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
painter->scale( context.scaleFactor(), context.scaleFactor() );
drawFrame( context );
}
if ( isRefreshing() && previewRender )
{
drawRefreshingOverlay( painter, itemStyle );
}
}
void QgsLayoutItem::setReferencePoint( const QgsLayoutItem::ReferencePoint point )
@ -1162,6 +1168,11 @@ void QgsLayoutItem::rotateItem( const double angle, const QPointF transformOrigi
refreshItemRotation( &itemTransformOrigin );
}
bool QgsLayoutItem::isRefreshing() const
{
return false;
}
QgsExpressionContext QgsLayoutItem::createExpressionContext() const
{
QgsExpressionContext context = QgsLayoutObject::createExpressionContext();
@ -1255,6 +1266,18 @@ void QgsLayoutItem::drawBackground( QgsRenderContext &context )
p->drawPath( framePath() );
}
void QgsLayoutItem::drawRefreshingOverlay( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle )
{
const QgsScopedQPainterState painterState( painter );
bool fitsInCache = false;
const int xSize = QFontMetrics( QFont() ).horizontalAdvance( 'X' );
const QImage refreshingImage = QgsApplication::svgCache()->svgAsImage( QStringLiteral( ":/images/composer/refreshing_item.svg" ), xSize * 3, QColor(), QColor(), 1, 1, fitsInCache );
const double previewScaleFactor = QgsLayoutUtils::scaleFactorFromItemStyle( itemStyle, painter );
painter->scale( 1.0 / previewScaleFactor, 1.0 / previewScaleFactor );
painter->drawImage( xSize, xSize, refreshingImage );
}
void QgsLayoutItem::setFixedSize( const QgsLayoutSize &size )
{
mFixedSize = size;

View File

@ -1012,6 +1012,13 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
virtual QgsGeometry clipPath() const;
/**
* Returns TRUE if the item is currently refreshing content in the background.
*
* \since QGIS 3.32
*/
virtual bool isRefreshing() const;
public slots:
/**
@ -1136,6 +1143,13 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
virtual void drawBackground( QgsRenderContext &context );
/**
* Draws a "refreshing" overlay icon on the item.
*
* \since QGIS 3.2
*/
void drawRefreshingOverlay( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle );
/**
* Sets a fixed \a size for the layout item, which prevents it from being freely
* resized. Set an empty size if item can be freely resized.

View File

@ -908,6 +908,8 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
if ( mLayout->renderContext().isPreviewRender() )
{
bool renderInProgress = false;
QgsScopedQPainterState painterState( painter );
painter->setClipRect( thisPaintRect );
if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
@ -933,6 +935,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
mPreviewScaleFactor = QgsLayoutUtils::scaleFactorFromItemStyle( style, painter );
mBackgroundUpdateTimer->start( 1 );
}
renderInProgress = true;
}
else
{
@ -941,6 +944,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
// cache was invalidated - trigger a background update
mPreviewScaleFactor = QgsLayoutUtils::scaleFactorFromItemStyle( style, painter );
mBackgroundUpdateTimer->start( 1 );
renderInProgress = true;
}
//Background color is already included in cached image, so no need to draw
@ -963,6 +967,11 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
mGridStack->drawItems( painter );
drawAnnotations( painter );
drawMapFrame( painter );
if ( renderInProgress )
{
drawRefreshingOverlay( painter, style );
}
}
else
{