void QgsLayoutItemGroup::setSceneRect( const QRectF &rectangle ) { mItemPosition = mLayout->convertFromLayoutUnits( rectangle.topLeft(), positionWithUnits().units() ); mItemSize = mLayout->convertFromLayoutUnits( rectangle.size(), sizeWithUnits().units() ); setScenePos( rectangle.topLeft() ); setRect( 0, 0, rectangle.width(), rectangle.height() ); }
void QgsLayoutItemScaleBar::resizeToMinimumWidth() { if ( !mStyle ) return; double widthMM = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); QgsLayoutSize currentSize = sizeWithUnits(); currentSize.setWidth( mLayout->renderContext().measurementConverter().convert( QgsLayoutMeasurement( widthMM, QgsUnitTypes::LayoutMillimeters ), currentSize.units() ).length() ); attemptResize( currentSize ); update(); emit changed(); }
void QgsLayoutItemLegend::adjustBoxSize() { if ( !mSizeToContents ) return; if ( !mInitialMapScaleCalculated ) { // this is messy - but until we have painted the item we have no knowledge of the current DPI // and so cannot correctly calculate the map scale. This results in incorrect size calculations // for marker symbols with size in map units, causing the legends to initially expand to huge // sizes if we attempt to calculate the box size first. return; } QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings ); QSizeF size = legendRenderer.minimumSize(); QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) ); if ( size.isValid() ) { QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( size, sizeWithUnits().units() ); //set new rect, respecting position mode and data defined size/position attemptResize( newSize ); } }
void QgsLayoutItemLegend::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) { if ( !painter ) return; if ( mFilterAskedForUpdate ) { mFilterAskedForUpdate = false; doUpdateFilterByMap(); } int dpi = painter->device()->logicalDpiX(); double dotsPerMM = dpi / 25.4; if ( mLayout ) { mSettings.setUseAdvancedEffects( mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagUseAdvancedEffects ); mSettings.setDpi( dpi ); } if ( mMap && mLayout ) { mSettings.setMmPerMapUnit( mLayout->convertFromLayoutUnits( mMap->mapUnitsToLayoutUnits(), QgsUnitTypes::LayoutMillimeters ).length() ); // use a temporary QgsMapSettings to find out real map scale QSizeF mapSizePixels = QSizeF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM ); QgsRectangle mapExtent = mMap->extent(); QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi, false ); mSettings.setMapScale( ms.scale() ); } mInitialMapScaleCalculated = true; QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings ); legendRenderer.setLegendSize( mForceResize && mSizeToContents ? QSize() : rect().size() ); //adjust box if width or height is too small if ( mSizeToContents ) { QSizeF size = legendRenderer.minimumSize(); if ( mForceResize ) { mForceResize = false; //set new rect, respecting position mode and data defined size/position QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( size, sizeWithUnits().units() ); attemptResize( newSize ); } else if ( size.height() > rect().height() || size.width() > rect().width() ) { //need to resize box QSizeF targetSize = rect().size(); if ( size.height() > targetSize.height() ) targetSize.setHeight( size.height() ); if ( size.width() > targetSize.width() ) targetSize.setWidth( size.width() ); QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( targetSize, sizeWithUnits().units() ); //set new rect, respecting position mode and data defined size/position attemptResize( newSize ); } } QgsLayoutItem::paint( painter, itemStyle, pWidget ); }
void QgsLayoutItem3DMap::draw( QgsLayoutItemRenderContext &context ) { QgsRenderContext &ctx = context.renderContext(); QPainter *painter = ctx.painter(); int w = static_cast<int>( std::ceil( rect().width() * ctx.scaleFactor() ) ); int h = static_cast<int>( std::ceil( rect().height() * ctx.scaleFactor() ) ); QRect r( 0, 0, w, h ); painter->save(); if ( !mSettings ) { painter->drawText( r, Qt::AlignCenter, tr( "Scene not set" ) ); painter->restore(); return; } if ( mSettings->backgroundColor() != backgroundColor() ) { mSettings->setBackgroundColor( backgroundColor() ); mCapturedImage = QImage(); } if ( !mCapturedImage.isNull() ) { painter->drawImage( r, mCapturedImage ); painter->restore(); return; } // we do not have a cached image of the rendered scene - let's request one from the engine if ( mLayout->renderContext().isPreviewRender() ) { painter->drawText( r, Qt::AlignCenter, tr( "Loading" ) ); painter->restore(); } QSizeF sizePixels = mLayout->renderContext().measurementConverter().convert( sizeWithUnits(), QgsUnitTypes::LayoutPixels ).toQSizeF(); QSize sizePixelsInt = QSize( static_cast<int>( std::ceil( sizePixels.width() ) ), static_cast<int>( std::ceil( sizePixels.height() ) ) ); if ( !mEngine ) { mEngine.reset( new QgsOffscreen3DEngine ); connect( mEngine.get(), &QgsAbstract3DEngine::imageCaptured, this, &QgsLayoutItem3DMap::onImageCaptured ); mEngine->setSize( sizePixelsInt ); mScene = new Qgs3DMapScene( *mSettings, mEngine.get() ); connect( mScene, &Qgs3DMapScene::sceneStateChanged, this, &QgsLayoutItem3DMap::onSceneStateChanged ); mEngine->setRootEntity( mScene ); } if ( mEngine->size() != sizePixelsInt ) mEngine->setSize( sizePixelsInt ); mScene->cameraController()->setCameraPose( mCameraPose ); if ( mLayout->renderContext().isPreviewRender() ) { onSceneStateChanged(); } else { // we can't just request a capture and hope it will arrive at some point later. // this is not a preview, we need the rendered scene now! if ( mDrawing ) return; mDrawing = true; Qgs3DUtils::captureSceneImage( *mEngine.get(), mScene ); QImage img = Qgs3DUtils::captureSceneImage( *mEngine.get(), mScene ); painter->drawImage( r, img ); painter->restore(); mDrawing = false; } }