2017-04-27 18:30:36 +00:00
// SPDX-License-Identifier: GPL-2.0
2015-07-17 16:09:42 +00:00
# include "qmlprofile.h"
2018-06-08 10:56:23 +00:00
# include "mobile-widgets/qmlmanager.h"
2019-08-05 17:41:15 +00:00
# include "core/errorhelper.h"
2018-05-11 15:25:41 +00:00
# include "core/subsurface-string.h"
2016-04-05 05:02:03 +00:00
# include "core/metrics.h"
2015-07-25 16:10:51 +00:00
# include <QTransform>
2016-03-09 03:33:19 +00:00
# include <QScreen>
2020-02-17 18:45:28 +00:00
# include <QElapsedTimer>
2015-07-17 16:09:42 +00:00
QMLProfile : : QMLProfile ( QQuickItem * parent ) :
2015-12-29 17:50:47 +00:00
QQuickPaintedItem ( parent ) ,
2016-01-28 15:02:20 +00:00
m_devicePixelRatio ( 1.0 ) ,
2018-05-25 21:30:10 +00:00
m_margin ( 0 ) ,
2020-02-17 18:46:31 +00:00
m_profileWidget ( new ProfileWidget2 ) ,
m_xOffset ( 0.0 ) ,
m_yOffset ( 0.0 )
2015-07-17 16:09:42 +00:00
{
2015-12-29 17:51:34 +00:00
setAntialiasing ( true ) ;
2020-02-17 18:46:31 +00:00
setFlags ( QQuickItem : : ItemClipsChildrenToShape | QQuickItem : : ItemHasContents ) ;
2015-11-12 00:43:13 +00:00
m_profileWidget - > setProfileState ( ) ;
2018-05-22 08:49:29 +00:00
m_profileWidget - > setPrintMode ( true ) ;
2015-12-29 15:15:52 +00:00
m_profileWidget - > setFontPrintScale ( 0.8 ) ;
2016-03-09 03:33:19 +00:00
connect ( QMLManager : : instance ( ) , & QMLManager : : sendScreenChanged , this , & QMLProfile : : screenChanged ) ;
setDevicePixelRatio ( QMLManager : : instance ( ) - > lastDevicePixelRatio ( ) ) ;
2015-11-12 00:43:13 +00:00
}
2015-07-17 16:09:42 +00:00
void QMLProfile : : paint ( QPainter * painter )
{
2020-02-17 18:45:28 +00:00
QElapsedTimer timer ;
if ( verbose )
timer . start ( ) ;
2016-01-18 20:32:47 +00:00
// let's look at the intended size of the content and scale our scene accordingly
2016-03-09 03:38:03 +00:00
QRect painterRect = painter - > viewport ( ) ;
QRect profileRect = m_profileWidget - > viewport ( ) - > rect ( ) ;
2016-03-11 02:02:36 +00:00
// qDebug() << "profile viewport and painter viewport" << profileRect << painterRect;
2016-01-18 20:32:47 +00:00
qreal sceneSize = 104 ; // that should give us 2% margin all around (100x100 scene)
2016-03-09 03:38:03 +00:00
qreal dprComp = devicePixelRatio ( ) * painterRect . width ( ) / profileRect . width ( ) ;
qreal sx = painterRect . width ( ) / sceneSize / dprComp ;
qreal sy = painterRect . height ( ) / sceneSize / dprComp ;
// next figure out the weird magic by which we need to shift the painter so the profile is shown
2017-04-03 19:49:14 +00:00
double dpr = devicePixelRatio ( ) ;
double magicValues [ ] = { 0.0 , 0.1 , 0.25 , 0.33 , 0.375 , 0.40 , 0.42 } ;
qreal magicShiftFactor = 0.0 ;
2017-04-16 15:26:40 +00:00
if ( dpr < 1.3 ) {
2017-04-03 19:49:14 +00:00
magicShiftFactor = magicValues [ 0 ] ;
} else if ( dpr > 6.0 ) {
magicShiftFactor = magicValues [ 6 ] ;
} else if ( IS_FP_SAME ( dpr , rint ( dpr ) ) ) {
magicShiftFactor = magicValues [ lrint ( dpr ) ] ;
} else {
int lower = ( int ) dpr ;
magicShiftFactor = ( magicValues [ lower ] * ( lower + 1 - dpr ) + magicValues [ lower + 1 ] * ( dpr - lower ) ) ;
2017-04-16 15:26:40 +00:00
if ( dpr < 1.45 )
magicShiftFactor - = 0.03 ;
2017-04-03 19:49:14 +00:00
}
2016-03-09 03:38:03 +00:00
// now set up the transformations scale the profile and
// shift the painter (taking its existing transformation into account)
QTransform profileTransform = QTransform ( ) ;
2016-01-15 21:55:42 +00:00
profileTransform . scale ( sx , sy ) ;
2016-03-09 03:38:03 +00:00
QTransform painterTransform = painter - > transform ( ) ;
2020-02-17 18:46:31 +00:00
painterTransform . translate ( dpr * m_xOffset - painterRect . width ( ) * magicShiftFactor , dpr * m_yOffset - painterRect . height ( ) * magicShiftFactor ) ;
2016-03-09 03:38:03 +00:00
2017-06-06 06:22:19 +00:00
# if defined(PROFILE_SCALING_DEBUG)
2016-03-09 03:38:03 +00:00
// some debugging messages to help adjust this in case the magic above is insufficient
2017-06-06 06:22:19 +00:00
qDebug ( ) < < QString ( " dpr %1 profile viewport %2 %3 painter viewport %4 %5 " ) . arg ( dpr ) . arg ( profileRect . width ( ) ) . arg ( profileRect . height ( ) )
. arg ( painterRect . width ( ) ) . arg ( painterRect . height ( ) ) ;
qDebug ( ) < < QString ( " profile matrix %1 %2 %3 %4 %5 %6 %7 %8 %9 " ) . arg ( profileTransform . m11 ( ) ) . arg ( profileTransform . m12 ( ) ) . arg ( profileTransform . m13 ( ) )
. arg ( profileTransform . m21 ( ) ) . arg ( profileTransform . m22 ( ) ) . arg ( profileTransform . m23 ( ) )
. arg ( profileTransform . m31 ( ) ) . arg ( profileTransform . m32 ( ) ) . arg ( profileTransform . m33 ( ) ) ) ;
qDebug ( ) < < QString ( " painter matrix %1 %2 %3 %4 %5 %6 %7 %8 %9 " ) . arg ( painterTransform . m11 ( ) ) . arg ( painterTransform . m12 ( ) ) . arg ( painterTransform . m13 ( ) )
. arg ( painterTransform . m21 ( ) ) . arg ( painterTransform . m22 ( ) ) . arg ( painterTransform . m23 ( ) )
. arg ( painterTransform . m31 ( ) ) . arg ( painterTransform . m32 ( ) ) . arg ( painterTransform . m33 ( ) ) ) ;
2016-03-24 04:22:55 +00:00
qDebug ( ) < < " exist profile transform " < < m_profileWidget - > transform ( ) < < " painter transform " < < painter - > transform ( ) ;
# endif
2016-03-09 03:38:03 +00:00
// apply the transformation
painter - > setTransform ( painterTransform ) ;
2016-01-15 21:55:42 +00:00
m_profileWidget - > setTransform ( profileTransform ) ;
2016-03-09 03:38:03 +00:00
// finally, render the profile
2015-11-12 00:43:13 +00:00
m_profileWidget - > render ( painter ) ;
2020-02-17 18:45:28 +00:00
if ( verbose )
2020-02-17 18:46:31 +00:00
qDebug ( ) < < " finished rendering profile with offset " < < QString : : number ( m_xOffset , ' f ' , 1 ) < < " / " < < QString : : number ( m_yOffset , ' f ' , 1 ) < < " in " < < timer . elapsed ( ) < < " ms " ;
2015-07-17 16:09:42 +00:00
}
2015-12-29 17:50:47 +00:00
void QMLProfile : : setMargin ( int margin )
{
m_margin = margin ;
}
2019-12-23 19:52:41 +00:00
int QMLProfile : : diveId ( ) const
2015-07-17 16:09:42 +00:00
{
return m_diveId ;
}
2020-02-17 18:42:56 +00:00
void QMLProfile : : updateProfile ( )
2015-07-17 16:09:42 +00:00
{
2020-02-17 18:42:56 +00:00
struct dive * d = get_dive_by_uniq_id ( m_diveId ) ;
2015-12-01 23:22:38 +00:00
if ( ! d )
return ;
2017-03-18 22:49:56 +00:00
if ( verbose )
2020-02-17 18:46:31 +00:00
qDebug ( ) < < " update profile for dive # " < < d - > number < < " offeset " < < QString : : number ( m_xOffset , ' f ' , 1 ) < < " / " < < QString : : number ( m_yOffset , ' f ' , 1 ) ;
2016-02-28 14:49:21 +00:00
m_profileWidget - > plotDive ( d , true ) ;
2016-01-13 02:05:06 +00:00
}
2020-02-17 18:42:56 +00:00
void QMLProfile : : setDiveId ( int diveId )
{
m_diveId = diveId ;
if ( m_diveId < 0 )
return ;
updateProfile ( ) ;
}
2016-01-13 02:05:06 +00:00
qreal QMLProfile : : devicePixelRatio ( ) const
{
return m_devicePixelRatio ;
}
void QMLProfile : : setDevicePixelRatio ( qreal dpr )
{
if ( dpr ! = m_devicePixelRatio ) {
m_devicePixelRatio = dpr ;
2016-03-09 03:33:19 +00:00
m_profileWidget - > setFontPrintScale ( 0.8 * dpr ) ;
2016-03-28 21:43:40 +00:00
updateDevicePixelRatio ( dpr ) ;
2016-01-13 02:05:06 +00:00
emit devicePixelRatioChanged ( ) ;
}
2015-07-17 16:09:42 +00:00
}
2016-03-09 03:33:19 +00:00
2020-02-17 18:46:31 +00:00
// don't update the profile here, have the user update x and y and then manually trigger an update
void QMLProfile : : setXOffset ( qreal value )
{
if ( IS_FP_SAME ( value , m_xOffset ) )
return ;
m_xOffset = value ;
emit xOffsetChanged ( ) ;
}
// don't update the profile here, have the user update x and y and then manually trigger an update
void QMLProfile : : setYOffset ( qreal value )
{
if ( IS_FP_SAME ( value , m_yOffset ) )
return ;
m_yOffset = value ;
emit yOffsetChanged ( ) ;
}
2016-03-09 03:33:19 +00:00
void QMLProfile : : screenChanged ( QScreen * screen )
{
setDevicePixelRatio ( screen - > devicePixelRatio ( ) ) ;
}