qskinny/src/common/QskFunctions.cpp

221 lines
5.0 KiB
C++
Raw Normal View History

2017-07-21 16:21:34 +00:00
#include "QskFunctions.h"
2018-07-19 12:10:48 +00:00
#include <qguiapplication.h>
#include <qmath.h>
2018-08-03 06:15:28 +00:00
#include <qscreen.h>
2020-03-13 12:32:22 +00:00
#include <qfont.h>
#include <qfontmetrics.h>
2017-07-21 16:21:34 +00:00
QSK_QT_PRIVATE_BEGIN
#include <private/qguiapplication_p.h>
2021-04-21 06:26:15 +00:00
#if QT_VERSION < QT_VERSION_CHECK( 5, 8, 0 )
#ifndef foreach
// qhighdpiscaling_p.h needs it
#define foreach Q_FOREACH
#endif
#endif
#include <private/qhighdpiscaling_p.h>
QSK_QT_PRIVATE_END
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h>
2021-05-26 11:06:50 +00:00
#include <cmath>
2017-07-21 16:21:34 +00:00
template< class Rect, class Value >
static inline Rect qskAlignedRect( const Rect& outerRect,
Value width, Value height, Qt::Alignment alignment )
{
Value x = outerRect.x();
Value y = outerRect.y();
2017-07-21 16:21:34 +00:00
2018-08-03 06:15:28 +00:00
switch ( alignment & Qt::AlignHorizontal_Mask )
2017-07-21 16:21:34 +00:00
{
case Qt::AlignHCenter:
x += ( outerRect.width() - width ) / 2;
2017-07-21 16:21:34 +00:00
break;
2017-07-21 16:21:34 +00:00
case Qt::AlignRight:
x += outerRect.width() - width;
2017-07-21 16:21:34 +00:00
break;
2017-07-21 16:21:34 +00:00
default:
break;
2017-07-21 16:21:34 +00:00
}
2018-08-03 06:15:28 +00:00
switch ( alignment & Qt::AlignVertical_Mask )
2017-07-21 16:21:34 +00:00
{
case Qt::AlignVCenter:
y += ( outerRect.height() - height ) / 2;
2017-07-21 16:21:34 +00:00
break;
2017-07-21 16:21:34 +00:00
case Qt::AlignBottom:
y += outerRect.height() - height;
2017-07-21 16:21:34 +00:00
break;
2017-07-21 16:21:34 +00:00
default:
break;
2017-07-21 16:21:34 +00:00
}
return Rect( x, y, width, height );
2017-07-21 16:21:34 +00:00
}
QRect qskAlignedRect( const QRect& outerRect,
int width, int height, Qt::Alignment alignment )
{
return qskAlignedRect< QRect, int >( outerRect, width, height, alignment );
}
QRectF qskAlignedRectF( const QRectF& outerRect,
qreal width, qreal height, Qt::Alignment alignment )
{
return qskAlignedRect< QRectF, qreal >( outerRect, width, height, alignment );
}
QRect qskInnerRect( const QRectF& rect )
{
const int left = qCeil( rect.left() );
const int top = qCeil( rect.top() );
const int right = qFloor( rect.right() );
const int bottom = qFloor( rect.bottom() );
return QRect( left, top, right - left, bottom - top );
}
2019-04-10 17:37:59 +00:00
QRectF qskInnerRectF( const QRectF& rect )
{
const qreal left = qCeil( rect.left() );
const qreal top = qCeil( rect.top() );
const qreal right = qFloor( rect.right() );
const qreal bottom = qFloor( rect.bottom() );
return QRectF( left, top, right - left, bottom - top );
}
QRectF qskValidOrEmptyInnerRect( const QRectF& rect, const QMarginsF& margins )
{
qreal x, y, h, w;
2019-04-24 06:39:13 +00:00
if ( rect.width() > 0.0 )
{
2019-04-24 06:39:13 +00:00
const qreal marginsWidth = margins.left() + margins.right();
if ( marginsWidth > rect.width() )
{
x = rect.x() + rect.width() * ( margins.left() / marginsWidth );
w = 0.0;
}
else
{
x = rect.x() + margins.left();
w = rect.width() - marginsWidth;
}
2018-08-03 06:15:28 +00:00
}
else
{
2019-04-24 06:39:13 +00:00
x = rect.x();
w = 0.0;
2018-08-03 06:15:28 +00:00
}
2019-04-24 06:39:13 +00:00
if ( rect.height() > 0.0 )
{
2019-04-24 06:39:13 +00:00
const qreal marginsHeight = margins.top() + margins.bottom();
if ( marginsHeight > rect.height() )
{
y = rect.y() + rect.height() * ( margins.top() / marginsHeight );
h = 0.0;
}
else
{
y = rect.y() + margins.top();
h = rect.height() - marginsHeight;
}
2018-08-03 06:15:28 +00:00
}
else
{
2019-04-24 06:39:13 +00:00
y = rect.y();
h = 0.0;
2018-08-03 06:15:28 +00:00
}
return QRectF( x, y, w, h );
2018-08-03 06:15:28 +00:00
}
2017-07-21 16:21:34 +00:00
qreal qskDpiScaled( qreal value )
{
static qreal factor = 0.0;
if ( factor <= 0.0 )
{
if ( const QScreen* screen = QGuiApplication::primaryScreen() )
factor = screen->logicalDotsPerInchX();
else
factor = 100.0;
factor /= 96.0;
}
return value * factor;
}
2020-03-13 12:32:22 +00:00
qreal qskHorizontalAdvance( const QFont& font, const QString& text )
{
return qskHorizontalAdvance( QFontMetricsF( font ), text );
}
qreal qskHorizontalAdvance( const QFontMetricsF& fontMetrics, const QString& text )
{
#if QT_VERSION >= QT_VERSION_CHECK( 5, 11, 0 )
return fontMetrics.horizontalAdvance( text );
#else
return fontMetrics.width( text );
#endif
}
2021-04-21 06:26:15 +00:00
qreal qskGlobalScaleFactor()
{
// The value of QT_SCALE_FACTOR
const QScreen* noScreen = nullptr;
return QHighDpiScaling::factor( noScreen );
}
bool qskHasPlatformWindowManagement()
{
if ( auto platform = QGuiApplicationPrivate::platformIntegration() )
return platform->hasCapability( QPlatformIntegration::WindowManagement );
return false;
}
QRect qskPlatformScreenGeometry( const QScreen* screen )
{
if ( screen == nullptr )
return QRect();
return screen->handle()->geometry();
}
2021-05-26 11:06:50 +00:00
/*
Due to the nature of floating point arithmetic
we might floor a value, that is already "aligned"
F.e static_cast< int >( 0.29 / 0.01 ) -> 28
*/
qreal qskFuzzyFloor( qreal value, qreal stepSize )
{
qreal v = std::floor( value / stepSize ) * stepSize;
if ( qFuzzyCompare( value - v, stepSize ) )
v = value;
return v;
}
qreal qskFuzzyCeil( qreal value, qreal stepSize )
{
qreal v = std::ceil( value / stepSize ) * stepSize;
if ( qFuzzyCompare( v - value, stepSize ) )
v = value;
return v;
}