mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
6e29c00f35
Feels natural in a C++ code base. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
163 lines
4 KiB
C++
163 lines
4 KiB
C++
// SPDX-License-Identifier: GPL-2.
|
|
#include "qmlprofile.h"
|
|
#include "profilescene.h"
|
|
#include "mobile-widgets/qmlmanager.h"
|
|
#include "core/divelist.h"
|
|
#include "core/errorhelper.h"
|
|
#include "core/subsurface-float.h"
|
|
#include "core/metrics.h"
|
|
#include "core/subsurface-string.h"
|
|
#include <QTransform>
|
|
#include <QScreen>
|
|
#include <QElapsedTimer>
|
|
|
|
QMLProfile::QMLProfile(QQuickItem *parent) :
|
|
QQuickPaintedItem(parent),
|
|
m_diveId(0),
|
|
m_dc(0),
|
|
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 = divelog.dives.get_by_uniq_id(m_diveId);
|
|
if (!d)
|
|
return;
|
|
m_profileWidget->draw(painter, painterRect, d, m_dc, 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;
|
|
emit numDCChanged();
|
|
}
|
|
|
|
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 (nearly_equal(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 (nearly_equal(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) {
|
|
report_info("dive #%d changed, trigger profile update", d->number);
|
|
triggerUpdate();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void QMLProfile::nextDC()
|
|
{
|
|
rotateDC(1);
|
|
}
|
|
|
|
void QMLProfile::prevDC()
|
|
{
|
|
rotateDC(-1);
|
|
}
|
|
|
|
void QMLProfile::rotateDC(int dir)
|
|
{
|
|
struct dive *d = divelog.dives.get_by_uniq_id(m_diveId);
|
|
if (!d)
|
|
return;
|
|
int numDC = d->number_of_computers();
|
|
if (numDC == 1)
|
|
return;
|
|
m_dc = (m_dc + dir) % numDC;
|
|
if (m_dc < 0)
|
|
m_dc += numDC;
|
|
triggerUpdate();
|
|
}
|
|
|
|
int QMLProfile::numDC() const
|
|
{
|
|
struct dive *d = divelog.dives.get_by_uniq_id(m_diveId);
|
|
return d ? d->number_of_computers() : 0;
|
|
}
|