subsurface/profile-widget/qmlprofile.cpp
Dirk Hohndel c2a7382b10 mobile: better scaling of profile items
With all the recent changes, some of the previous assumptions about the scale
of items seem to be no longer appropriate. Now that we are showing the icons in
the profile again on device it's quite obvious that they were way too big -
clearly we don't need the special scaling anymore.

Also implement a suggestion from Berthold to get slightly smaller fonts and
finer structures in the profile on mobile devices. This scaling of the DPR
seems to work well in my tests.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-13 15:06:13 -07:00

128 lines
3.4 KiB
C++

// SPDX-License-Identifier: GPL-2.
#include "qmlprofile.h"
#include "profilescene.h"
#include "mobile-widgets/qmlmanager.h"
#include "core/errorhelper.h"
#include "core/subsurface-string.h"
#include "core/metrics.h"
#include <QTransform>
#include <QScreen>
#include <QElapsedTimer>
QMLProfile::QMLProfile(QQuickItem *parent) :
QQuickPaintedItem(parent),
m_devicePixelRatio(1.0),
m_margin(0),
m_xOffset(0.0),
m_yOffset(0.0)
{
createProfileView();
setAntialiasing(true);
setFlags(QQuickItem::ItemClipsChildrenToShape | QQuickItem::ItemHasContents );
connect(QMLManager::instance(), &QMLManager::sendScreenChanged, this, &QMLProfile::screenChanged);
connect(this, &QMLProfile::scaleChanged, this, &QMLProfile::triggerUpdate);
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &QMLProfile::divesChanged);
setDevicePixelRatio(QMLManager::instance()->lastDevicePixelRatio());
}
QMLProfile::~QMLProfile()
{
}
void QMLProfile::createProfileView()
{
m_profileWidget.reset(new ProfileScene(m_devicePixelRatio * 0.8, false, false));
}
// we need this so we can connect update() to the scaleChanged() signal - which the connect above cannot do
// directly as it chokes on the default parameter for update().
// If the scale changes we may need to change our offsets to ensure that we still only show a subset of
// the profile and not empty space around it, which the paint() method below will take care of, which will
// eventually get called after we call update()
void QMLProfile::triggerUpdate()
{
update();
}
void QMLProfile::paint(QPainter *painter)
{
QElapsedTimer timer;
if (verbose)
timer.start();
// let's look at the intended size of the content and scale our scene accordingly
// for some odd reason the painter transformation is set up to scale by the dpr - which results
// in applying that dpr scaling twice. So we hard-code it here to be the identity matrix
QRect painterRect = painter->viewport();
painter->resetTransform();
if (m_diveId < 0)
return;
struct dive *d = get_dive_by_uniq_id(m_diveId);
if (!d)
return;
m_profileWidget->draw(painter, painterRect, d, dc_number, nullptr, false);
}
void QMLProfile::setMargin(int margin)
{
m_margin = margin;
}
int QMLProfile::diveId() const
{
return m_diveId;
}
void QMLProfile::setDiveId(int diveId)
{
m_diveId = diveId;
}
qreal QMLProfile::devicePixelRatio() const
{
return m_devicePixelRatio;
}
void QMLProfile::setDevicePixelRatio(qreal dpr)
{
if (dpr != m_devicePixelRatio) {
m_devicePixelRatio = dpr;
// Recreate the view to redraw the text items with the new scale.
createProfileView();
emit devicePixelRatioChanged();
}
}
// 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();
}
void QMLProfile::screenChanged(QScreen *screen)
{
setDevicePixelRatio(screen->devicePixelRatio());
}
void QMLProfile::divesChanged(const QVector<dive *> &dives, DiveField)
{
for (struct dive *d: dives) {
if (d->id == m_diveId) {
qDebug() << "dive #" << d->number << "changed, trigger profile update";
triggerUpdate();
return;
}
}
}