Initial commit using eql5-sfos template

This commit is contained in:
Renaud Casenave-Péré 2021-12-09 12:47:26 +01:00
commit 87b498c404
20 changed files with 486 additions and 0 deletions

97
README.org Normal file
View file

@ -0,0 +1,97 @@
This package is here to help bootstrap application development for Sailfish OS
using ecl and eql5.
* Dependencies
Youll need ecl and eql5 installed in the build engine that comes with sfos sdk.
These are available through my repository on openrepos.net. You can activate it
and install the packages with the following command:
#+BEGIN_SRC sh
rpm --import https://sailfish.openrepos.net/openrepos.key
zypper ar -f https://sailfish.openrepos.net/razcampagne/personal-main.repo
zypper in eql5
#+END_SRC
* Build and deploy
You can use the build button in qtcreator or do this manually in the sdk engine:
#+BEGIN_SRC sh
qmake harbour-sextant.pro
make
#+END_SRC
But the way I recommend to do it is by using the command-line tool sfdk that
comes with the sdk. Use the following command for a comprehensive manual:
#+BEGIN_SRC sh
sfdk --help-building
#+END_SRC
The TL;DR would be one of the following:
#+BEGIN_SRC sh
sfdk build
#+END_SRC
Or,
#+BEGIN_SRC sh
sfdk qmake
sfdk make
sfdk make-install
sfdk package
#+END_SRC
You also have the option to build against ecl and eql5 statically to distribute
your application without the need to depend on development packages. You can do
this by configuring qmake like so:
#+BEGIN_SRC sh
sfdk qmake -- 'CONFIG += standalone'
#+END_SRC
Once the target and device options have been set, you just have to issue the command:
#+BEGIN_SRC sh
sfdk deploy
#+END_SRC
This will compile and build the package and send it to your phone as a rpm.
* Attach a REPL
Upon initialization of the application, a slynk server is created with the
port 4005. You just have to fire up emacs and connect to it using sly-connect.
Only sly-fancy contribs are supported for now so youll have to disable the
others you may have configured for it to work with this application.
If you wish to disable this feature, you can configure qmake like so:
#+BEGIN_SRC sh
sfdk qmake -- 'CONFIG += norepl'
#+END_SRC
Note that statically linking ecl and eql5 will also disable the repl.
* Reload QML files
You can find a file `webserver.sh` in the repository which will launch a simple
http server. You can then edit the qml files on your host machine and issue the
following command in the application REPL:
#+BEGIN_SRC common-lisp
(reload-qml "http://host-ip-address:8000")
#+END_SRC
This will reload all qml files but not the ones packaged on the device, the ones
on your host system, served by the http server.
You can even do that directly in emacs with the following code:
#+BEGIN_SRC emacs-lisp
(let ((httpd-port 8000)) ; default 8080 port is already used by the sdk build engine
(call-interactively httpd-serve-directory))
#+END_SRC
* Customize
The code included in this repository is voluntarily barebone. Fill free to use
it to bootstrap your application development and rename or replace files,
packages to better suit your needs. You can even replace slynk with swank if you
prefer.

12
harbour-sextant.desktop Normal file
View file

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
Icon=harbour-sextant
Exec=harbour-sextant
Name=harbour-sextant
# translation example:
# your app name in German locale (de)
#
# Remember to comment out the following line, if you do not want to use
# a different app name in German locale (de).
Name[de]=harbour-sextant

62
harbour-sextant.pro Normal file
View file

@ -0,0 +1,62 @@
# NOTICE:
#
# Application name defined in TARGET has a corresponding QML filename.
# If name defined in TARGET is changed, the following needs to be done
# to match new name:
# - corresponding QML filename must be changed
# - desktop icon filename must be changed
# - desktop filename must be changed
# - icon definition filename in desktop file must be changed
# - translation filenames have to be changed
LISP_FILES = make.lisp \
lisp/dependencies.lisp \
lisp/app.lisp \
lisp/app.asd
lisp.output = libapp.a
lisp.commands = eql5 -platform minimal $$PWD/make.lisp
lisp.input = LISP_FILES
lisp.CONFIG = combine target_predeps
QMAKE_EXTRA_COMPILERS += lisp
# The name of your application
TARGET = harbour-sextant
CONFIG += sailfishapp
LIBS += -L. -lapp -lecl -leql5
norepl|standalone:lisp.commands = eql5 -platform minimal $$PWD/make.lisp norepl
standalone {
CONFIG += link_prl
QT += widgets qml multimedia network quick sql
LIBS -= -lecl -leql5
LIBS += -l:libecl.a -l:libeclatomic.a -l:libeclgc.a -l:libeclgmp.a -l:libeclffi.a -l:libeql5.a
}
SOURCES += src/harbour-sextant.cc
DISTFILES += qml/harbour-sextant.qml \
qml/cover/CoverPage.qml \
qml/pages/FirstPage.qml \
qml/pages/SecondPage.qml \
rpm/harbour-sextant.changes.in \
rpm/harbour-sextant.changes.run.in \
rpm/harbour-sextant.spec \
rpm/harbour-sextant.yaml \
# translations/*.ts \
harbour-sextant.desktop
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
# to disable building translations every time, comment out the
# following CONFIG line
# CONFIG += sailfishapp_i18n
# German translation is enabled as an example. If you aren't
# planning to localize your app, remember to comment out the
# following TRANSLATIONS line. And also do not forget to
# modify the localized app name in the the .desktop file.
# TRANSLATIONS += translations/harbour-sextant-de.ts

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

9
lisp/app.asd Normal file
View file

@ -0,0 +1,9 @@
(defsystem app
:serial t
:defsystem-depends-on (:asdf-package-system)
:class :package-inferred-system
:around-compile (lambda (thunk)
(proclaim '(optimize (debug 3) (safety 3) (speed 0)))
(funcall thunk))
:depends-on ("alexandria")
:components ((:file "app")))

49
lisp/app.lisp Normal file
View file

@ -0,0 +1,49 @@
(defpackage :app
(:use :cl :eql)
(:export #:start-slynk
#:stop-slynk
#:start
#:reload-qml))
(in-package :app)
(qrequire :quick)
(defun sym (symbol package)
(intern (symbol-name symbol) package))
#+app-repl
(defun start-slynk ()
(unless (find-package :slynk)
(require :ecl-quicklisp)
(funcall (sym 'quickload :ql) :slynk))
(funcall (sym 'create-server :slynk)
:interface "0.0.0.0" :port 4005 :dont-close t :style :spawn))
#+app-repl
(defun stop-slynk ()
(when (find-package :slynk)
(funcall (sym 'stop-server :slynk) 4005)))
(defun start ()
#+app-repl
(start-slynk)
(qconnect qml:*quick-view* "statusChanged(QQuickView::Status)"
(lambda (status)
(case status
(#.|QQuickView.Ready|
(qml-reloaded))))))
(defun reload-qml (&optional (url "http://localhost:8000/"))
"Reload QML file from an url, directly on the device."
(qrun*
(let ((src (|toString| (|source| qml:*quick-view*))))
(if (x:starts-with qml:*root* src)
(|setSource| qml:*quick-view* (qnew "QUrl(QString)" (x:string-substitute url qml:*root* src)))
(qml:reload))
(|toString| (|source| qml:*quick-view*)))))
(defun qml-reloaded ()
;; re-ini
)
(qlater #'start)

2
lisp/dependencies.lisp Normal file
View file

@ -0,0 +1,2 @@
(require :ecl-quicklisp)
(ql:quickload :alexandria)

24
make.lisp Normal file
View file

@ -0,0 +1,24 @@
#-eql5
(error "Please use the EQL5 executable")
(require :cmp)
(unless (member "norepl" (ext:command-args) :test #'string=)
(push :app-repl *features*))
(load "lisp/dependencies")
(push "lisp/" asdf:*central-registry*)
(asdf:make-build "app"
:monolithic t
:type :static-library
:move-here "./"
:init-name "init_app")
(let ((lib-name "libapp.a"))
(when (probe-file lib-name)
(delete-file lib-name))
(rename-file (x:cc "app--all-systems" ".a") lib-name))
(eql:qquit)

22
qml/cover/CoverPage.qml Normal file
View file

@ -0,0 +1,22 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
CoverBackground {
Label {
id: label
anchors.centerIn: parent
text: qsTr("My Cover")
}
CoverActionList {
id: coverAction
CoverAction {
iconSource: "image://theme/icon-cover-next"
}
CoverAction {
iconSource: "image://theme/icon-cover-pause"
}
}
}

10
qml/harbour-sextant.qml Normal file
View file

@ -0,0 +1,10 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages/" as Pages
ApplicationWindow
{
initialPage: Component { Pages.FirstPage { } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: defaultAllowedOrientations
}

43
qml/pages/FirstPage.qml Normal file
View file

@ -0,0 +1,43 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
// To enable PullDownMenu, place our content in a SilicaFlickable
SilicaFlickable {
anchors.fill: parent
// PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
PullDownMenu {
MenuItem {
text: qsTr("Show Page 2")
onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
}
}
// Tell SilicaFlickable the height of its content.
contentHeight: column.height
// Place our content in a Column. The PageHeader is always placed at the top
// of the page, followed by our content.
Column {
id: column
width: page.width
spacing: Theme.paddingLarge
PageHeader {
title: qsTr("UI Template")
}
Label {
x: Theme.horizontalPageMargin
text: qsTr("Hello Sailors")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
}
}
}
}

30
qml/pages/SecondPage.qml Normal file
View file

@ -0,0 +1,30 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
SilicaListView {
id: listView
model: 20
anchors.fill: parent
header: PageHeader {
title: qsTr("Nested Page")
}
delegate: BackgroundItem {
id: delegate
Label {
x: Theme.horizontalPageMargin
text: qsTr("Item") + " " + index
anchors.verticalCenter: parent.verticalCenter
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
}
onClicked: console.log("Clicked " + index)
}
VerticalScrollDecorator {}
}
}

View file

@ -0,0 +1,18 @@
# Rename this file as harbour-sextant.changes to include changelog
# entries in your RPM file.
#
# Add new changelog entries following the format below.
# Add newest entries to the top of the list.
# Separate entries from eachother with a blank line.
#
# Alternatively, if your changelog is automatically generated (e.g. with
# the git-change-log command provided with Sailfish OS SDK), create a
# harbour-sextant.changes.run script to let mb2 run the required commands for you.
# * date Author's Name <author's email> version-release
# - Summary of changes
* Sun Apr 13 2014 Jack Tar <jack.tar@example.com> 0.0.1-1
- Scrubbed the deck
- Hoisted the sails

View file

@ -0,0 +1,25 @@
#!/bin/bash
#
# Rename this file as harbour-sextant.changes.run to let mb2 automatically
# generate changelog from well formatted Git commit messages and tag
# annotations.
git-change-log
# Here are some basic examples how to change from the default behavior. Run
# git-change-log --help inside the Sailfish OS SDK chroot or build engine to
# learn all the options git-change-log accepts.
# Use a subset of tags
#git-change-log --tags refs/tags/my-prefix/*
# Group entries by minor revision, suppress headlines for patch-level revisions
#git-change-log --dense '/[0-9]+.[0-9+$'
# Trim very old changes
#git-change-log --since 2014-04-01
#echo '[ Some changelog entries trimmed for brevity ]'
# Use the subjects (first lines) of tag annotations when no entry would be
# included for a revision otherwise
#git-change-log --auto-add-annotations

44
rpm/harbour-sextant.yaml Normal file
View file

@ -0,0 +1,44 @@
Name: harbour-sextant
Summary: Org-Mode for Sailfish
Version: 0.1
Release: 1
# The contents of the Group field should be one of the groups listed here:
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
Group: Qt/Qt
URL: http://example.org/
License: LICENSE
# This must be generated before uploading a package to a remote build service.
# Usually this line does not need to be modified.
Sources:
- '%{name}-%{version}.tar.bz2'
Description: |
Short description of my Sailfish OS Application
Configure: none
Builder: qmake5
# This section specifies build dependencies that are resolved using pkgconfig.
# This is the preferred way of specifying build dependencies for your package.
PkgConfigBR:
- sailfishapp >= 1.0.2
- Qt5Core
- Qt5Qml
- Qt5Quick
# Build dependencies without a pkgconfig setup can be listed here
PkgBR:
- ecl
- eql5
# Runtime dependencies which are not automatically detected
Requires:
- sailfishsilica-qt5 >= 0.10.9
# All installed files
Files:
- '%{_bindir}'
- '%{_datadir}/%{name}'
- '%{_datadir}/applications/%{name}.desktop'
- '%{_datadir}/icons/hicolor/*/apps/%{name}.png'
# For more information about yaml and what's supported in Sailfish OS
# build system, please see https://wiki.merproject.org/wiki/Spectacle

38
src/harbour-sextant.cc Normal file
View file

@ -0,0 +1,38 @@
#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif
#include <ecl/ecl.h>
#include <eql5/eql.h>
#include <eql5/eql_fun.h>
#include <sailfishapp.h>
#include <QGuiApplication>
#include <QQuickView>
#include <QTextCodec>
extern "C" void init_app (cl_object);
int main(int argc, char *argv[])
{
// SailfishApp::main() will display "qml/harbour-sextant.qml", if you need more
// control over initialization, you can use:
//
// - SailfishApp::application(int, char *[]) to get the QGuiApplication *
// - SailfishApp::createView() to get a new QQuickView * instance
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
//
// To display the view, call "show()" (will show fullscreen on device).
QScopedPointer<QGuiApplication> app (SailfishApp::application (argc, argv));
QScopedPointer<QQuickView> view (SailfishApp::createView ());
QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(utf8);
EQL eql;
eql.exec (init_app);
eql_fun ("qml:ini-sailfish", Q_ARG (QUrl, SailfishApp::pathToMainQml ()),
Q_ARG (QUrl, SailfishApp::pathTo ("")),
Q_ARG (QQuickView*, view.data ()), Q_ARG(bool, true));
}

1
webserver.sh Executable file
View file

@ -0,0 +1 @@
python3 -m http.server 8000