diff --git a/.gitignore b/.gitignore index fab7372..46de04f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ Makefile* *.prl *.app moc_*.cpp +moc_*.h ui_*.h qrc_*.cpp Thumbs.db @@ -70,4 +71,5 @@ Thumbs.db # -------- *.dll *.exe - +bin/ +obj/ diff --git a/Main.qml b/Main.qml new file mode 100644 index 0000000..0416183 --- /dev/null +++ b/Main.qml @@ -0,0 +1,161 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.0 +import QtQuick.Window 2.11 +import QtQuick.Layouts 1.3 + +Window { + id: canvas + width: screenGeometry.width + height: screenGeometry.height + visible: true + + Rectangle { + id:body + anchors.fill: parent + function redraw() { + canvas.visible = true + body.update() + } + + Timer{ + id: redraw_timer + interval: 300 + repeat: false + + onTriggered: redraw() + } + Item { + id:header + height: 80 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + Text{ + text: "draft launcher" + anchors.centerIn: parent + + font.family:"Noto Serif" + font.pixelSize:30 + font.bold: true + } + Rectangle{ + anchors.left:parent.left + anchors.right:parent.right + anchors.bottom:parent.bottom + anchors.margins: 10 + height: 5 + color: "black" + } + } + Item { + id:footer + height:40 + + anchors{ + bottom: parent.bottom + left:parent.left + right:parent.right + } + + Rectangle{ + anchors.left:parent.left + anchors.right:parent.right + anchors.top:parent.top + anchors.leftMargin: 10 + anchors.rightMargin: 10 + height: 5 + color: "black" + } + + Text{ + text: controller.getVersion() + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins:10 + + font.family:"Noto Serif" + font.pixelSize:15 + font.bold: true + } + } + + + Item { + + anchors.top: header.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: 15 + + ListView { + id:optionsArea + spacing: 15 + anchors.fill:parent + interactive: false + model: controller.getOptions(); + delegate: Rectangle{ + id:menu_item + height:150 + border.color: "black" + border.width: 2 + + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 10 + states: [ + State { + name:"normal" + PropertyChanges { + target: menu_item + color: "white" + } + }, + State { + name:"clicked" + PropertyChanges { + target: menu_item + color: "gray" + } + }] + + Text{ + font.pixelSize: 70 + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 10 + text:model.modelData.name + } + + Text { + id:tdesc + anchors.bottom:parent.bottom + anchors.left:parent.left + anchors.right:parent.right + anchors.leftMargin:20 + anchors.bottomMargin:10 + text:model.modelData.desc + font.family:"Noto Serif" + font.pixelSize:30 + font.italic: true + } + MouseArea { + anchors.fill: parent + onPressed: menu_item.state = "clicked" + onReleased: menu_item.state = "normal" + onClicked: { + optionsArea.currentIndex = index + canvas.visible = false + //Qt.connect() + //blocking call + model.modelData.execute() + //redraw_timer.start() + Qt.callLater(body.redraw) + } + } + } + } + } + } +} diff --git a/README.md b/README.md index 6e311be..b16f34c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# draft-reMarkable +# fork of draft-reMarkable A launcher for the reMarkable tablet, which wraps around the standard interface. [Draft v0.2 video](https://www.youtube.com/watch?v=VEngMK54SV4) @@ -9,21 +9,18 @@ A launcher for the reMarkable tablet, which wraps around the standard interface. (nb. You fiddle with the internal system of your reMarkable at your own risk! Here be dragons.) ### 1. Deploy draft -This should simply be a case of opening up qtcreator, loading up the project with the normal reMarkable target, and hitting "run". - -As well as deploying the program, this will also populate `/etc/draft` with some sample commands and add a `/lib/systemd/system/draft.service` systemd file. - - -### 1.i (optional) Deploy button-capture - -[This small program](https://github.com/dixonary/button-capture-reMarkable) allows you to close the current application and return to the draft launcher. There is no native way to close `xochitl` so this is a very useful thing to have if you want to switch between applications. - - -### 1.ii (optional) Deploy fingerterm - -[This terminal](https://github.com/dixonary/fingerterm-reMarkable) runs on the reMarkable and lets you change some config things without needing to SSH in! It's one of the default config options but you can remove that if you are't wanting to use it. +```bash +source thetoolchain +qmake +make +scp bin/draft rm: +``` +or +``` +./dep.sh +``` -### 2. Enable at startup +### 2.a Enable at startup You need to replace the normal xochitl startup with draft. This is done with the following two lines via SSH: ```bash @@ -31,13 +28,14 @@ systemctl disable xochitl systemctl enable draft ``` -### 3. Restart your reMarkable +### 2.b Use touchgestures +TODO + -On restart you should find that `xochitl`, `fingerterm` and `shutdown` are your available choices and the draft launcher is running. ### 4. Configure draft -Draft is configured through the files in the `/etc/draft` directory. They consist of a few simple lines. All of them are needed otherwise the option will not show up in the launcher. +Draft is configured through the files in the `~/.config/draft` directory. They consist of a few simple lines. All of them are needed otherwise the option will not show up in the launcher. `title`: Big word, left hand side of the screen. @@ -45,6 +43,7 @@ Draft is configured through the files in the `/etc/draft` directory. They consis `call`: The shell command to run when the option is pressed. +not implemented yet: `term`: The shell command to run while the option is running, to close it. (or it can do whatever you want really!) This won't do anything without `button-capture` installed. `imgFile`: An icon to use. It will look for a PNG image with that name in the `/etc/draft/icons` directory. diff --git a/dep.sh b/dep.sh new file mode 100755 index 0000000..2b4b300 --- /dev/null +++ b/dep.sh @@ -0,0 +1,5 @@ +make clean && \ +qmake && \ +make -j12 && \ +arm-oe-linux-gnueabi-strip bin/draft && \ +scp bin/draft root@remarkable: diff --git a/draft.pro b/draft.pro index bd993d3..69bfa14 100644 --- a/draft.pro +++ b/draft.pro @@ -1,9 +1,22 @@ +system(./makeversion.sh) QMAKE_EXTRA_TARGETS += version.h +PRE_TARGETDEPS += version.h QT += quick +QT -= GLES CONFIG += c++11 -LIBS += -lqsgepaper +CONFIG += optimize_full -TARGET = draft +linux-oe-g++ { + message("rm") + LIBS += -lqsgepaper + DEFINES += RM +} +TARGET = draft +DESTDIR = bin +OBJECTS_DIR = obj +DEPLOYMENT_PATH=/home/root +INSTALLS += target +target.path = /home/root # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the @@ -16,48 +29,18 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 HEADERS += \ - mainview.h \ + option_item.h \ options.h \ - handler.h + version.h SOURCES += main.cpp \ - mainview.cpp \ - options.cpp \ - handler.cpp - -DEPLOYMENT_PATH = /usr/share/$$TARGET -DEFINES += DEPLOYMENT_PATH=\\\"$$DEPLOYMENT_PATH\\\" -DEFINES += QML_FOLDER=\\\"qml\\\" - -js.files = js/Main.js -js.path == $$DEPLOYMENT_PATH/js -INSTALLS += js - -qml.files = qml/Main.qml -qml.files+= qml/MenuItem.qml -qml.path == $$DEPLOYMENT_PATH/qml -INSTALLS += qml - - -# Installs /etc/draft and /lib/systemd/system/draft.service. -configFiles.files = extra-files/draft -configFiles.path = /etc/ -INSTALLS += configFiles - -service.files = extra-files/draft.service -service.path=/lib/systemd/system/ -INSTALLS += service + option_item.cpp \ + options.cpp # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = - - -target.path = /usr/bin -INSTALLS += target - -DISTFILES += \ - js/Main.js \ - qml/MenuItem.qml +RESOURCES += \ + qml.qrc diff --git a/handler.cpp b/handler.cpp deleted file mode 100644 index d7b3391..0000000 --- a/handler.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "handler.h" -#include "mainview.h" -#include -#include -#include -#include -#include -#include -#include - -time_t lastReturn; -int qSize = 1404; - -Handler::Handler(std::string lT, std::string term, QGuiApplication* app, MainView* mainView, QObject* obj) - : link(lT), term(term), ef(obj), app(app), mainView(mainView){ - - time(&lastReturn); - -} - -bool Handler::eventFilter(QObject* obj, QEvent* event) -{ - if (event->type() == QEvent::MouseButtonPress) { - obj->parent()->setProperty("color", QVariant("#22000000")); - return true; - } - - else if (event->type() == QEvent::MouseButtonRelease) { - obj->parent()->setProperty("color", QVariant("white")); - time_t tim; - time(&tim); - // 1 second cooldown before opening again! - if(difftime(tim, lastReturn) > 1) { - handleEvent(); - } - return true; - } - else - return false; -} - -void Handler::handleEvent() { - - std::cout << "Setting termfile /etc/draft/.terminate" << std::endl; - std::ofstream termfile; - termfile.open("/etc/draft/.terminate"); - termfile << term << std::endl; - - std::cout << "Running command " << link << "..." << std::endl; - system((link).c_str()); - - // Don't exit any more - just head back to the launcher! - std::cout << "Running again" << std::endl; - - // Yes, this is an exceptionally hacky way of repainting the screen - qSize = 1-(qSize-1403)+1403; - - usleep(500000); - - mainView->rootObject()->setProperty("width",QVariant(qSize)); - - // Cooldown - time(&lastReturn); - -} - -Handler::~Handler() { - ef->removeEventFilter(this); -} diff --git a/handler.h b/handler.h deleted file mode 100644 index 6bde1fb..0000000 --- a/handler.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "mainview.h" -#include - -extern time_t lastReturn; - -class Handler : public QObject -{ - Q_OBJECT -public: - Handler(std::string lT, std::string term, QGuiApplication* app, MainView* mainView, QObject* obj); - ~Handler(); - bool eventFilter(QObject* obj, QEvent* event); - void handleEvent(); - -private: - std::string link; - std::string term; - QObject* ef; - QGuiApplication* app; - MainView* mainView; -}; diff --git a/js/Main.js b/js/Main.js deleted file mode 100644 index 423407c..0000000 --- a/js/Main.js +++ /dev/null @@ -1,10 +0,0 @@ -// Main.js - -function displayDateAsHHMMSS() { - var d = new Date(); - var s = d.getSeconds (); - var sep = s % 2 == 0 ? " " : ":"; - return (("0" + d.getHours()).slice(-2) + ":" + - ("0" + d.getMinutes()).slice(-2) + sep + - ("0" + s).slice(-2)); -} diff --git a/main.cpp b/main.cpp index c5517dc..063a7d1 100644 --- a/main.cpp +++ b/main.cpp @@ -1,31 +1,29 @@ #include -//#include -//#include -#include "mainview.h" #include "options.h" -#include "handler.h" - +#ifdef RM +#include Q_IMPORT_PLUGIN(QsgEpaperPlugin) +#endif int main(int argc, char *argv[]) { +#ifdef RM qputenv("QMLSCENE_DEVICE", "epaper"); qputenv("QT_QPA_PLATFORM", "epaper:enable_fonts"); qputenv("QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS", "rotate=180"); - - system("/usr/bin/button-capture &"); + qputenv("QT_QPA_GENERIC_PLUGINS", "evdevtablet"); +#endif QGuiApplication app(argc, argv); - MainView view; - - srand(time(NULL)); + QQmlApplicationEngine view; + Options controller; + qmlRegisterType(); + qmlRegisterType(); view.rootContext()->setContextProperty("screenGeometry", app.primaryScreen()->geometry()); - view.engine()->addImportPath(QStringLiteral(DEPLOYMENT_PATH)); - view.setSource(QDir(DEPLOYMENT_PATH).filePath("qml/Main.qml")); - view.show(); + view.rootContext()->setContextProperty("controller", &controller); - Options options(&view, &app); + view.load(QUrl("qrc:/Main.qml")); return app.exec(); } diff --git a/mainview.cpp b/mainview.cpp deleted file mode 100644 index 7f7763f..0000000 --- a/mainview.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "mainview.h" - -MainView::MainView() -{ - -} - -void MainView::keyPressEvent(QKeyEvent* ke) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << "mw" << ke->key() << "down"; - QQuickView::keyPressEvent(ke); // base class implementation -} - -void MainView::mouseMoveEvent(QMouseEvent* me) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << me->pos(); - QQuickView::mouseMoveEvent(me); -} - -void MainView::mousePressEvent(QMouseEvent* me) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << me->pos(); - QQuickView::mousePressEvent(me); -} - -void MainView::mouseReleaseEvent(QMouseEvent* me) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << me->pos(); - QQuickView::mouseReleaseEvent(me); -} - -void MainView::tabletEvent(QTabletEvent* te) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << te; -} - -void MainView::touchEvent(QTouchEvent* te) -{ - qDebug() << Q_FUNC_INFO; - qDebug() << te; -} diff --git a/mainview.h b/mainview.h deleted file mode 100644 index d6fb80f..0000000 --- a/mainview.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include -#include - -class MainView : public QQuickView -{ -public: - MainView(); -public slots: - void keyPressEvent(QKeyEvent*); - void mouseMoveEvent(QMouseEvent* me); - void mousePressEvent(QMouseEvent* me); - void mouseReleaseEvent(QMouseEvent* me); - void tabletEvent(QTabletEvent* te); - void touchEvent(QTouchEvent* te); -}; diff --git a/makeversion.sh b/makeversion.sh new file mode 100755 index 0000000..4fc60b3 --- /dev/null +++ b/makeversion.sh @@ -0,0 +1 @@ +echo "#define VERSION \"$(git describe --tags --long)\"" > version.h diff --git a/option_item.cpp b/option_item.cpp new file mode 100644 index 0000000..af1e638 --- /dev/null +++ b/option_item.cpp @@ -0,0 +1,10 @@ +#include "option_item.h" + +bool OptionItem::ok() { + return ! (_name.isEmpty() && _call.isEmpty()); +} + +void OptionItem::execute() +{ + system(_call.toUtf8()); +} diff --git a/option_item.h b/option_item.h new file mode 100644 index 0000000..60c45f2 --- /dev/null +++ b/option_item.h @@ -0,0 +1,30 @@ +#ifndef OPTION_ITEM_H +#define OPTION_ITEM_H +#include + +class OptionItem : public QObject { + Q_OBJECT +public: + + Q_PROPERTY(QString name MEMBER _name NOTIFY nameChanged) + Q_PROPERTY(QString desc MEMBER _desc NOTIFY descChanged) + Q_PROPERTY(QString call MEMBER _call NOTIFY callChanged) + Q_PROPERTY(QString term MEMBER _term NOTIFY termChanged) + + bool ok(); + + Q_INVOKABLE void execute(); +signals: + void nameChanged(); + void descChanged(); + void callChanged(); + void termChanged(); + +private: + QString _name; + QString _desc; + QString _call; + QString _term; +}; + +#endif // OPTION_ITEM_H diff --git a/options.cpp b/options.cpp index 924a060..a0dc1bd 100644 --- a/options.cpp +++ b/options.cpp @@ -1,120 +1,68 @@ #include "options.h" -#include "handler.h" -#include -#include -#include -#include -#include -#include - -const std::string configDir = "/etc/draft"; - -// Create options and add them to the screen. -Options::Options(MainView* mainView, QGuiApplication* app) : - mainView(mainView), - optionsView(mainView->rootObject()->findChild("optionsArea")), - app(app) -{ - - std::vector filenames; - +#include +#include +#include +#include +#include +#include +#include +#include "version.h" + +QList Options::getOptions(){ + + QString configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); + QList result; // If the config directory doesn't exist, // then print an error and stop. - if(!Options::read_directory(configDir, filenames)) { - Options::error("Failed to read directory - it does not exist."); - return; + QDir directory(configDir); + if (!directory.exists() || configDir.isEmpty()) + { + qCritical() << "Failed to read directory - it does not exist.> " << configDir; + return result; } - std::sort(filenames.begin(), filenames.end()); - for(std::string f : filenames) { + directory.setFilter( QDir::Files | QDir::NoSymLinks | QDir::NoDot | QDir::NoDotDot); + + auto images = directory.entryInfoList(QDir::NoFilter,QDir::SortFlag::Name); + foreach(QFileInfo fi, images) { + auto f = fi.absoluteFilePath(); + + qDebug() << "parsing file " << f; - std::cout << "parsing file " << f << std::endl; - QFile file((configDir + "/" + f).c_str()); + QFile file(fi.absoluteFilePath()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - Options::error("Couldn't find the file " + f + "."); - break; + qCritical() << "Couldn't find the file " << f; + continue; } QTextStream in(&file); - OptionItem opt; + OptionItem *opt= new OptionItem(); while (!in.atEnd()) { - std::string line = in.readLine().toStdString(); - if(line.length() > 0) { - size_t sep = line.find("="); - if(sep != line.npos) { - std::string lhs = line.substr(0,sep); - std::string rhs = line.substr(sep+1); - - if (lhs == "name") opt.name = rhs; - else if(lhs == "desc") opt.desc = rhs; - else if(lhs == "imgFile") opt.imgFile = rhs; - else if(lhs == "call") opt.call = rhs; - else if(lhs == "term") opt.term = rhs; - else std::cout << "ignoring unknown parameter \"" << line - << "\" in file \"" << f << "\"" << std::endl; - } + QString line = in.readLine(); + QStringList parts = line.split("="); + if(parts.length() != 2){ + qWarning() << "wrong format on " << line; + continue; } - else { - std::cout << "ignoring malformed line \"" << line - << "\" in file \"" << f << "\"" << std::endl; + QString lhs= parts.at(0); + QString rhs= parts.at(1); + QSet known = {"name","desc","call"}; + if (known.contains(lhs)){ + opt->setProperty(lhs.toUtf8(), rhs); } } - - if(opt.call == "" || opt.term == "") continue; - createOption(opt, optionList.size()); - optionList.push_back(opt); - + if(opt->ok()) + result.append(opt); } - -} - -void Options::createOption(OptionItem &option, size_t index) { - - QQuickView* opt = new QQuickView(); - opt->setSource(QDir(DEPLOYMENT_PATH).filePath("qml/MenuItem.qml")); - opt->show(); - - QQuickItem* root = opt->rootObject(); - root->setProperty("itemNumber", QVariant(index)); - root->setParentItem(optionsView); - - root->setProperty("t_name",QVariant(option.name.c_str())); - root->setProperty("t_desc",QVariant(option.desc.c_str())); - root->setProperty("t_imgFile",QVariant(("file://"+configDir+"/icons/"+option.imgFile+".png").c_str())); - - QObject* mouseArea = root->children().at(0); - Handler* handler = new Handler(option.call, option.term, app, mainView, mouseArea); - root->children().at(0)->installEventFilter(handler); - - option.object = opt; - option.handler = handler; -} - -void Options::error(std::string text) { - std::cout << "!! Error: " << text << std::endl; + return result; } - -// Stolen shamelessly from Martin Broadhurst -bool Options::read_directory(const std::string name, - std::vector& filenames) +QString Options::getVersion() { - DIR* dirp = opendir(name.c_str()); - if(dirp == nullptr) { - return false; - } - - struct dirent * dp; - while ((dp = readdir(dirp)) != NULL) { - std::string dn = dp->d_name; + return VERSION; +} - if(dn == "." || dn == ".."|| dn == "icons") continue; - filenames.push_back(dn); - } - closedir(dirp); - return true; -} diff --git a/options.h b/options.h index 2e21372..46236e1 100644 --- a/options.h +++ b/options.h @@ -1,32 +1,13 @@ #pragma once #include -#include -#include -#include -#include "mainview.h" +#include "option_item.h" -struct OptionItem { - std::string name; - std::string desc; - std::string call; - std::string term; - std::string imgFile; - QObject* object; - QObject* handler; -}; - -class Options +class Options : public QObject { -public: - Options(MainView* mainView, QGuiApplication* app); - bool read_directory(const std::string name, std::vector& files); -private: - void error(std::string text); - void createOption(OptionItem &option, size_t index); + Q_OBJECT - MainView* mainView; - QQuickItem* optionsView; - std::vector optionList; - QGuiApplication* app; +public: + Q_INVOKABLE QList getOptions(); + Q_INVOKABLE QString getVersion(); }; diff --git a/qml/Main.qml b/qml/Main.qml deleted file mode 100644 index 32e6864..0000000 --- a/qml/Main.qml +++ /dev/null @@ -1,86 +0,0 @@ -import QtQuick 2.0 -import "../js/Main.js" as MainJS - -Rectangle { - id: canvas - width: 1404 - height: 1872 - - Behavior on y { - NumberAnimation { - property:"y" - to:0 - duration:1000 - } - } - - Text { - id: heading - anchors.left:parent.left - anchors.right:parent.right - text: " draft launcher" - textFormat: Text.RichText - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 80 - font.family:"Noto Serif" - font.italic:true - } - - Text { - id: credit - anchors.right:parent.right - anchors.bottom:parent.bottom - anchors.margins: {bottom:10} - text: qsTr("draft v0.2 created by @dixonary_") - font.pixelSize: 30 - font.family:"Noto Serif" - font.italic:true - } - - Text { - id: optionsHeading - anchors.left:parent.left - anchors.right:parent.right - anchors.margins:50 - horizontalAlignment:Text.AlignLeft - font.pixelSize: 40 - font.family:"Noto Serif" - font.italic:true - text: "Available Options" - y: heading.y + heading.height + 50 - } - Rectangle { - id:optionsArea - objectName: "optionsArea" - y:optionsHeading.y + optionsHeading.height + 10 - anchors.left:parent.left - anchors.right:parent.right - height:credit.y - y - 5 - - Rectangle { - id:topBar - color: "black" - anchors.left:parent.left - anchors.right:parent.right - anchors.margins: 50 - anchors.topMargin: 0 - height:5 - } - Rectangle { - id:bottomBar - color: "black" - anchors.left:parent.left - anchors.right:parent.right - anchors.bottom:parent.bottom - anchors.margins: 50 - anchors.bottomMargin:0 - height:5 - } - - MouseArea { - anchors.fill:parent - } - - } - -} diff --git a/qml/MenuItem.qml b/qml/MenuItem.qml deleted file mode 100644 index c3f0d7b..0000000 --- a/qml/MenuItem.qml +++ /dev/null @@ -1,58 +0,0 @@ -import QtQuick 2.0 -import "../js/Main.js" as MainJS - -Rectangle { - property int itemNumber: 0 - - property alias t_name : tname.text - property alias t_desc : tdesc.text - property alias t_imgFile: timg.source - //property alias t_imgFile: imgLoader.src - - - y: itemNumber * 200 + 30 - anchors.left:parent.left - anchors.right:parent.right - height:180 - anchors.margins:70 - border.color:"#cccccc" - border.width: 3 - - MouseArea { - id:ma - anchors.fill:parent - } - - Text { - id:tname - anchors.top:parent.top - anchors.left:parent.left - anchors.right:parent.right - anchors.topMargin:10 - anchors.leftMargin:20 - font.family:"Noto Serif" - font.pixelSize:80 - font.italic: true - } - Text { - id:tdesc - anchors.bottom:parent.bottom - anchors.left:parent.left - anchors.right:parent.right - anchors.leftMargin:20 - anchors.bottomMargin:10 - font.family:"Noto Serif" - font.pixelSize:40 - font.italic: true - } - Image { - id:timg - fillMode: Image.PreserveAspectFit - width: height - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom:parent.bottom - anchors.margins:15 - } - -} diff --git a/version.h b/version.h new file mode 100644 index 0000000..4f4c0e8 --- /dev/null +++ b/version.h @@ -0,0 +1 @@ +#define VERSION "0.0.2-1-ge8c6b71"