Commit 246f5e25 authored by Alberto Mardegan's avatar Alberto Mardegan
Browse files

VncOutput: handle scaling and panning

This is still not used in the UI.
parent a5ab9cb8
......@@ -28,6 +28,8 @@ Project {
prefix: "src/"
files: [
"main.cpp",
"scaler.cpp",
"scaler.h",
"types.cpp",
"types.h",
"vnc_client.cpp",
......
......@@ -19,6 +19,7 @@
#include "vnc_output.h"
#include "scaler.h"
#include "vnc_client.h"
#include <QDebug>
......@@ -38,14 +39,19 @@ public:
VncOutputPrivate(VncOutput *q);
~VncOutputPrivate();
void setScale(qreal scale);
void setCenter(const QPointF &center);
void updateMapping();
private:
VncClient *m_client;
QSize m_vncSize;
QRect m_paintedRect;
QRect m_vncVisibleRect;
QRectF m_paintedRect;
QTransform m_itemToVnc;
QTransform m_vncToItem;
qreal m_scale;
QPointF m_center;
VncOutput *q_ptr;
};
......@@ -53,6 +59,7 @@ private:
VncOutputPrivate::VncOutputPrivate(VncOutput *q):
m_client(nullptr),
m_scale(0.0),
q_ptr(q)
{
}
......@@ -61,31 +68,58 @@ VncOutputPrivate::~VncOutputPrivate()
{
}
void VncOutputPrivate::setScale(qreal scale)
{
m_scale = scale;
updateMapping();
}
void VncOutputPrivate::setCenter(const QPointF &center)
{
m_center = center;
updateMapping();
}
void VncOutputPrivate::updateMapping()
{
Q_Q(VncOutput);
QTransform itemToVnc;
QRect paintedRect;
QTransform vncToItem;
QRectF paintedRect;
QRect vncVisibleRect;
int w = q->width();
int h = q->height();
qreal w = q->width();
qreal h = q->height();
const QSize vncSize = m_client ? m_client->image().size() : QSize();
if (vncSize.isValid() && w > 0 && h > 0) {
QSize scaledSize = vncSize.scaled(w, h, Qt::KeepAspectRatio);
int x = (w - scaledSize.width()) / 2;
int y = (h - scaledSize.height()) / 2;
qreal scale = qreal(vncSize.width()) / qreal(scaledSize.width());
paintedRect = QRect(x, y, scaledSize.width(), scaledSize.height());
itemToVnc.scale(scale, scale);
itemToVnc.translate(-x, -y);
Scaler::InputData in {
vncSize,
QSizeF(w, h),
m_scale,
m_center,
};
Scaler::OutputData out;
bool ok = Scaler::updateMapping(in, &out);
if (Q_LIKELY(ok)) {
m_vncVisibleRect = out.sourceVisibleRect.toRect();
m_paintedRect = out.itemPaintedRect;
m_scale = out.scale;
m_center = out.center;
m_itemToVnc = out.itemToSource;
} else {
m_vncVisibleRect = QRect();
m_paintedRect = QRectF();
m_scale = 0.0;
m_center = QPointF();
m_itemToVnc = QTransform();
}
m_vncSize = vncSize;
m_paintedRect = paintedRect;
m_itemToVnc = itemToVnc;
m_vncToItem = itemToVnc.inverted();
m_vncToItem = m_itemToVnc.inverted();
Q_EMIT q->scaleChanged();
Q_EMIT q->centerChanged();
}
VncOutput::VncOutput(QQuickItem *parent):
......@@ -123,6 +157,32 @@ VncClient *VncOutput::client() const
return d->m_client;
}
void VncOutput::setScale(qreal scale)
{
Q_D(VncOutput);
d->setScale(scale);
update();
}
qreal VncOutput::scale() const
{
Q_D(const VncOutput);
return d->m_scale;
}
void VncOutput::setCenter(const QPointF &center)
{
Q_D(VncOutput);
d->setCenter(center);
update();
}
QPointF VncOutput::center() const
{
Q_D(const VncOutput);
return d->m_center;
}
void VncOutput::paint(QPainter *painter)
{
Q_D(VncOutput);
......@@ -131,7 +191,7 @@ void VncOutput::paint(QPainter *painter)
if (image.size() != d->m_vncSize) {
d->updateMapping();
}
painter->drawImage(d->m_paintedRect, image);
painter->drawImage(d->m_paintedRect, image, d->m_vncVisibleRect);
}
void VncOutput::geometryChanged(const QRectF &newGeometry,
......
......@@ -32,6 +32,8 @@ class VncOutput: public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(VncClient *client READ client WRITE setClient NOTIFY clientChanged)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
Q_PROPERTY(QPointF center READ center WRITE setCenter NOTIFY centerChanged)
public:
VncOutput(QQuickItem *parent = nullptr);
......@@ -40,10 +42,18 @@ public:
void setClient(VncClient *client);
VncClient *client() const;
void setScale(qreal scale);
qreal scale() const;
void setCenter(const QPointF &center);
QPointF center() const;
void paint(QPainter *painter) override;
Q_SIGNALS:
void clientChanged();
void scaleChanged();
void centerChanged();
protected:
void geometryChanged(const QRectF &newGeometry,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment