Skip to content

Commit

Permalink
Initial QML implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jturcotte committed Oct 7, 2015
0 parents commit f71816f
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

.qmake.stash

*.o
moc_*.cpp
qrc_*.cpp
qrcode-animation
Makefile*
43 changes: 43 additions & 0 deletions QRCode.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import main 1.0
import QtQuick 2.4

Item {
property string text
property real revealProgress: 1
property QtObject helper: QRCodeHelper { }
Rectangle {
id: qrCode2
property var qrCodeData: helper.getQRCodeData(text)
// Keep space for an empty dot length at the edges
width: qrCodeData.width + 2
height: width

// This item is using a coordinate system where one QR code dot is 1 unit
// Apply a scale to fill the parent in which 1 unit is 1 pixel
scale: parent.width / width
transformOrigin: Item.TopLeft

color: "white"
Repeater {
model: qrCode2.qrCodeData.dots
delegate: Rectangle {
property real dotProgress: {
function smoothstep(edge0, edge1, x) {
var t = Math.min(1.0, Math.max(0.0, (x - edge0) / (edge1 - edge0)));
return t * t * (3.0 - 2.0 * t);
}
var start = 1.0 - smoothstep(0.0, 30, modelData.surroundCount)
var end = 1.0 - smoothstep(0.0, 30, modelData.surroundCount + 5.0)
return smoothstep(start, end, revealProgress)
}
color: "black"
opacity: 1 - dotProgress
// + 1 dot offset for the empty edge
x: modelData.x + 1
y: modelData.y + 1 + 25 * 0.5 * dotProgress * dotProgress
width: 1
height: 1
}
}
}
}
21 changes: 21 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "qrcode.h"
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQuickView>

int main(int argc, char **argv)
{
qmlRegisterType<QRCodeHelper>("main", 1, 0, "QRCodeHelper");
QGuiApplication app{argc, argv};

QQuickView view;
QSurfaceFormat surfaceFormat = view.requestedFormat();
surfaceFormat.setSamples(4);
view.setFormat(surfaceFormat);
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl{"qrc:///main.qml"});
view.setColor(Qt::black);
view.show();

return app.exec();
}
48 changes: 48 additions & 0 deletions main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import QtQuick.Controls 1.0
import QtQuick 2.0
import main 1.0

Item {
height: 600
width: 600

Grid {
id: grid
columns: 1
rows: columns
anchors.fill: parent

Repeater {
model: grid.columns * grid.rows
delegate: QRCode {
width: grid.width / grid.columns
height: grid.height / grid.rows
text: "http://woboq.com/software-services.html"
revealProgress: slider.value
}
}
}

Slider {
id: slider
property QtObject animation: SequentialAnimation {
loops: Animation.Infinite
NumberAnimation { to: 0; target: slider; property: "value"; duration: 2000 }
NumberAnimation { to: 1; target: slider; property: "value"; duration: 2000 }
}
anchors { left: parent.left; top: parent.top; right: parent.right }
value: 1
}

focus: true
Keys.onPressed: {
if (event.key == Qt.Key_Left)
grid.columns = Math.max(1, grid.columns * 0.5)
else if (event.key == Qt.Key_Right)
grid.columns *= 2
else if (event.key == Qt.Key_Space)
slider.animation.running = !slider.animation.running

print("Showing " + grid.columns * grid.columns + " items.")
}
}
18 changes: 18 additions & 0 deletions qrcode-animation.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
TEMPLATE = app

QT += quick
CONFIG += c++11
CONFIG -= app_bundle

CONFIG += link_pkgconfig
PKGCONFIG += libqrencode

# Input
SOURCES += \
main.cpp \
qrcode.cpp

HEADERS += \
qrcode.h

RESOURCES += qrcode-animation.qrc
6 changes: 6 additions & 0 deletions qrcode-animation.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>QRCode.qml</file>
</qresource>
</RCC>
41 changes: 41 additions & 0 deletions qrcode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "qrcode.h"

#include <qrencode.h>

QVariant QRCodeHelper::getQRCodeData(const QString &text)
{
QRcode *qrencodeCode = QRcode_encodeString(
text.toUtf8().constData(), 1, QR_ECLEVEL_L, QR_MODE_8, true);
Code code;
code.width = qrencodeCode ? qrencodeCode->width : 0;

for (int y = 0; y < code.width; ++y) {
for (int x = 0; x < code.width; ++x) {
auto src = qrencodeCode->data + y * code.width + x;
// First bit: 1=black/0=white
if (*src & 0x1) {
// Count the number of dots 2 columns/rows around
int surroundCount = 0;
for (int i = x - 2; i <= x + 2; ++i) {
if (i < 0 || i >= code.width)
continue;
for (int j = y - 2; j <= y + 2; ++j) {
if (j < 0 || j >= code.width)
continue;
auto src = qrencodeCode->data + j * code.width + i;
if (*src & 0x1)
++surroundCount;
}
}

code.dots.append(QVariant::fromValue(
CodeDot{x, y, surroundCount}
));
}
}
}
QRcode_free(qrencodeCode);

return QVariant::fromValue(code);
}

34 changes: 34 additions & 0 deletions qrcode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef QRCODE_H
#define QRCODE_H

#include <QObject>
#include <QVariant>

struct CodeDot {
int x, y;
int surroundCount;

Q_PROPERTY(int x MEMBER x)
Q_PROPERTY(int y MEMBER y)
Q_PROPERTY(int surroundCount MEMBER surroundCount)
Q_GADGET
};

struct Code {
int width;
QVariantList dots;

Q_PROPERTY(int width MEMBER width)
Q_PROPERTY(QVariantList dots MEMBER dots)
Q_GADGET
};


class QRCodeHelper : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE static QVariant getQRCodeData(const QString &text);
};

#endif // QRCODE_H

0 comments on commit f71816f

Please sign in to comment.