add Qt6 version of some examples (see below); revisions

'9999', 'advanced-qml-auto-reload', 'planets', 'sokoban'
This commit is contained in:
pls.153 2024-10-22 13:27:56 +02:00
parent ca79dec909
commit dc29ac9084
87 changed files with 963 additions and 74 deletions

View file

@ -0,0 +1,69 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Window
Rectangle {
id: main
width: 200
height: 300 + input.height
color: "lavender"
TextField {
id: input
objectName: "input"
width: parent.width
horizontalAlignment: Qt.AlignHCenter
text: "0000"
inputMask: "9999"
inputMethodHints: Qt.ImhDigitsOnly
focus: true
onTextChanged: Lisp.call("app:draw-number", Number(text))
}
Canvas {
id: canvas
objectName: "canvas"
y: input.height
width: parent.width
height: {
var h = Qt.inputMethod.keyboardRectangle.y
var f = (Qt.platform.os === "android") ? Screen.devicePixelRatio : 1
h = (h === 0) ? main.height : h / f
return (h - input.height)
}
property var ctx
// functions to be called from Lisp
function begin(color, width) {
ctx.beginPath()
ctx.strokeStyle = color
ctx.lineWidth = width
ctx.lineCap = "round"
}
function end() {
ctx.stroke()
}
function drawLine(x1, y1, x2, y2) {
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
}
onPaint: {
ctx = getContext("2d")
ctx.reset()
ctx.translate(canvas.width / 2, canvas.height / 2)
var s = height / 340
ctx.scale(s, s)
Lisp.call("app:paint")
ctx.stroke()
}
}
}

View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -0,0 +1,22 @@
(in-package :cl-user)
(defparameter *dir* *load-truename*)
(defvar *template* (with-open-file (s (merge-pathnames ".template.qml" *dir*))
(let ((str (make-string (file-length s))))
(read-sequence str s)
str)))
(defun create-qml-loaders ()
(dolist (file (directory (merge-pathnames "ext/**/*.qml" *dir*)))
(let* ((name (namestring file))
(p (1+ (search "/ext/" name)))
(loader (concatenate 'string (subseq name 0 p) "." (subseq name p))))
(unless (probe-file loader)
(ensure-directories-exist loader)
(with-open-file (s loader :direction :output)
(let ((new (subseq name p)))
(format t "~&creating .~A~%" new)
(format s *template* (subseq name p))))))))
(create-qml-loaders)

View file

@ -0,0 +1,15 @@
import QtQuick
Loader {
objectName: "ext/Page1.qml"
source: objectName
Component.onCompleted: if (width === 0) { anchors.fill = parent }
function reload() {
var src = source
source = ""
Engine.clearCache()
source = src
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
Loader {
objectName: "ext/Page2.qml"
source: objectName
Component.onCompleted: if (width === 0) { anchors.fill = parent }
function reload() {
var src = source
source = ""
Engine.clearCache()
source = src
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
Loader {
objectName: "ext/Page3.qml"
source: objectName
Component.onCompleted: if (width === 0) { anchors.fill = parent }
function reload() {
var src = source
source = ""
Engine.clearCache()
source = src
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
Loader {
objectName: "ext/Repl.qml"
source: objectName
Component.onCompleted: if (width === 0) { anchors.fill = parent }
function reload() {
var src = source
source = ""
Engine.clearCache()
source = src
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
Loader {
objectName: "~A"
source: objectName
Component.onCompleted: if (width === 0) { anchors.fill = parent }
function reload() {
var src = source
source = ""
Engine.clearCache()
source = src
}
}

View file

@ -0,0 +1,15 @@
import QtQuick
Item {
Rectangle {
anchors.fill: parent
color: Qt.lighter("red", 1.5)
border.width: 10
border.color: "red"
Text {
anchors.centerIn: parent
text: "<h2>page 1</h2>"
}
}
}

View file

@ -0,0 +1,16 @@
import QtQuick
Item {
Rectangle {
anchors.fill: parent
radius: 100
color: Qt.lighter("green", 3.0)
border.width: 10
border.color: "green"
Text {
anchors.centerIn: parent
text: "<h2>page 2</h2>"
}
}
}

View file

@ -0,0 +1,18 @@
import QtQuick
Item {
Rectangle {
anchors.centerIn: parent
width: Math.min(parent.width, parent.height)
height: width
radius: width
color: Qt.lighter("blue", 1.7)
border.width: 10
border.color: "blue"
Text {
anchors.centerIn: parent
text: "<h2>page 3</h2>"
}
}
}

View file

@ -0,0 +1,160 @@
import QtQuick
import QtQuick.Controls
Item {
id: repl
z: 1
anchors.fill: parent
Row {
anchors.right: parent.right
z: 1
Text {
text: "REPL"
anchors.verticalCenter: show.verticalCenter
visible: !show.checked
}
Switch {
id: show
onCheckedChanged: container.enabled = checked
}
}
Column {
id: container
opacity: 0
Rectangle {
width: repl.parent.width
height: repl.parent.height / 4
color: "#101010"
ListView {
id: replOutput
objectName: "repl_output"
anchors.fill: parent
contentWidth: parent.width * 4
clip: true
model: replModel
flickableDirection: Flickable.HorizontalAndVerticalFlick
delegate: Column {
Rectangle {
width: replOutput.contentWidth
height: 1
color: "#707070"
visible: mLine
}
Text {
x: 2
padding: 2
textFormat: Text.PlainText
font.family: fontHack.name
font.bold: mBold
text: mText
color: mColor
}
}
}
ListModel {
id: replModel
objectName: "repl_model"
function appendText(data) {
append(data)
replOutput.contentX = 0
replOutput.positionViewAtEnd()
}
}
}
Row {
width: repl.parent.width
TextField {
id: input
objectName: "repl_input"
width: repl.parent.width - 2 * back.width
font.family: fontHack.name
font.bold: true
color: "#c0c0c0"
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
focus: show.checked
palette {
highlight: "#e0e0e0"
highlightedText: "#101010"
}
background: Rectangle {
color: "#101010"
border.width: 2
border.color: "gray"
}
onAccepted: Lisp.call("eval:eval-in-thread", text)
}
Button {
id: back
objectName: "history_back"
width: 40
height: input.height
focusPolicy: Qt.NoFocus
font.family: fontIcons.name
font.pixelSize: 26
text: "\uf100"
onClicked: Lisp.call("eval:history-move", "back")
}
Rectangle {
width: 1
height: input.height
color: "#101010"
}
Button {
id: forward
objectName: "history_forward"
width: back.width
height: input.height
focusPolicy: Qt.NoFocus
font.family: fontIcons.name
font.pixelSize: 26
text: "\uf101"
onClicked: Lisp.call("eval:history-move", "forward")
}
}
Rectangle {
width: repl.parent.width
height: 1
color: "#101010"
}
}
ProgressBar {
objectName: "progress"
anchors.top: container.bottom
width: repl.width
z: 1
indeterminate: true
enabled: visible
visible: false
}
states: [
State { when: show.checked; PropertyChanges { target: container; opacity: 0.9; y: 0 }},
State { when: !show.checked; PropertyChanges { target: container; opacity: 0.0; y: -height }}
]
transitions: [
Transition { NumberAnimation { properties: "opacity,y"; duration: 250; easing.type: Easing.InCubic }}
]
}

View file

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import ".ext/" as Ext // for single file auto reload (development)
//import "ext/" as Ext // release version
Rectangle {
id: main
width: 300
height: 500
objectName: "main"
color: "black"
SwipeView {
id: view
objectName: "view"
anchors.fill: parent
Rectangle {
color: "white"
Ext.Repl {}
Text {
anchors.centerIn: parent
text: "swipe for next page"
}
}
// N.B. don't use Loader inside a Repeater here, won't work with single
// file auto reload (which already uses a Loader)
Ext.Page1 {}
Ext.Page2 {}
Ext.Page3 {}
}
PageIndicator {
anchors.bottom: view.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
count: view.count
currentIndex: view.currentIndex
}
FontLoader { id: fontIcons; source: "fonts/fontawesome-webfont.ttf" }
FontLoader { id: fontHack; source: "fonts/Hack-Regular.ttf" }
FontLoader { id: fontHackBold; source: "fonts/Hack-Bold.ttf" }
}

2
examples/Qt6/meshtastic/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

2
examples/Qt6/planets/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -0,0 +1,193 @@
import QtQuick
Item {
id: main
objectName: "main"
width: 300
height: 500
Rectangle {
anchors.fill: parent
color: "#101010"
}
ListView {
id: view
objectName: "view"
anchors.fill: parent
delegate: planetInfo
model: planets
}
ListModel {
id: planets
objectName: "planets"
// example of inline item
//ListElement { name: "Earth"; shape: "img/earth.png"; map: "img/earth-map.jpg"; info: "..." }
function addPlanet(planet) { append(planet) }
}
property int itemHeight: 44
Component {
id: planetInfo
Item {
id: wrapper
width: view.width
height: itemHeight
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: itemHeight
color: "#303060"
border.color: Qt.lighter(color, 1.2)
Text {
x: 15
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 4
font.pixelSize: parent.height - 22
color: "#f0f0f0"
text: model.name // see Lisp keyword name
}
}
Rectangle {
id: image
width: itemHeight - 4
height: width
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 2
anchors.topMargin: 2
color: "#101010"
Column {
id: imageColumn
anchors.fill: parent
Image {
id: shapeImage
height: parent.height - mapImage.height
width: parent.width
fillMode: Image.PreserveAspectFit
source: model.shape // see Lisp keyword name
}
Image {
id: mapImage
width: parent.width
height: 0
fillMode: Image.PreserveAspectFit
source: model.map // see Lisp keyword name
}
}
}
MouseArea {
anchors.fill: parent
onClicked: parent.state = "expanded"
}
Item {
id: infoView
anchors.top: image.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
opacity: 0
Rectangle {
anchors.fill: parent
color: "#303060"
border.color: "#101010"
border.width: 1
Flickable {
id: flick
anchors.fill: parent
anchors.margins: 4
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
clip: true
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x + r.width)
contentX = r.x + r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y + r.height)
contentY = r.y + r.height-height;
}
TextEdit {
id: edit
width: flick.width
color: "#f0f0f0"
font.pixelSize: 16
readOnly: true
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
text: model.info // see Lisp keyword name
}
}
}
}
Rectangle {
id: closeButton
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 2
anchors.topMargin: 2
width: itemHeight - 4
height: width
color: "transparent"
border.color: "#f0f0f0"
opacity: 0
Text {
anchors.centerIn: parent
color: "#f0f0f0"
font.bold: true
text: "X"
}
MouseArea {
anchors.fill: parent
onClicked: wrapper.state = ""
}
}
states: [
State {
name: "expanded"
PropertyChanges { target: wrapper; height: view.height }
PropertyChanges { target: image; width: view.width; height: view.height * 2/3; anchors.rightMargin: 0; anchors.topMargin: itemHeight }
PropertyChanges { target: mapImage; height: view.height * 1/3 }
PropertyChanges { target: infoView; opacity: 1 }
PropertyChanges { target: closeButton; opacity: 1 }
PropertyChanges { target: wrapper.ListView.view; contentY: wrapper.y; interactive: false }
}
]
transitions: [
Transition {
NumberAnimation {
duration: 250
properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY"
}
}
]
}
}
}

2
examples/Qt6/sokoban/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -0,0 +1,16 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
Button {
width: main.small ? 37 : 50
height: width
flat: true
focusPolicy: Qt.NoFocus
font.family: fontAwesome.name
font.pixelSize: 1.2 * width
opacity: 0.2
scale: 1.2
onPressed: Lisp.call(this, "qsoko:button-pressed")
}

View file

@ -0,0 +1,13 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
Button {
width: main.small ? 32 : 50
height: width
font.family: fontAwesome.name
font.pixelSize: width - 6
opacity: 0.8
onPressed: Lisp.call(this, "qsoko:button-pressed")
}

View file

@ -0,0 +1,21 @@
import QtQuick
Item {
objectName: "dynamic"
property Component box: Qt.createComponent("dynamic/Box.qml")
property Component box2: Qt.createComponent("dynamic/Box2.qml")
property Component player: Qt.createComponent("dynamic/Player.qml")
property Component fixed: Qt.createComponent("dynamic/Fixed.qml")
function createItem(name) {
switch (name) {
case "object": return box.createObject()
case "object2": return box2.createObject()
case "player":
case "player2": return player.createObject()
case "wall":
case "goal": return fixed.createObject()
}
}
}

View file

@ -0,0 +1,6 @@
import QtQuick
NumberAnimation {
onRunningChanged: Lisp.call("qsoko:animation-change", running)
}

View file

@ -0,0 +1,6 @@
import QtQuick
RotationAnimation {
onRunningChanged: Lisp.call("qsoko:animation-change", running)
}

View file

@ -0,0 +1,5 @@
import QtQuick
ScaleAnimator {
onRunningChanged: Lisp.call("qsoko:animation-change", running)
}

View file

@ -0,0 +1,6 @@
import QtQuick
SequentialAnimation {
onRunningChanged: Lisp.call("qsoko:animation-change", running)
}

View file

@ -0,0 +1,18 @@
import QtQuick
import "../" as Ext
Image {
Behavior on x {
Ext.NumberAnimation {
duration: 150
easing.type: Easing.InQuart
}
}
Behavior on y {
Ext.NumberAnimation {
duration: 150
easing.type: Easing.InQuart
}
}
}

View file

@ -0,0 +1,48 @@
import QtQuick
import "../" as Ext
Image {
id: box2
Behavior on x {
Ext.NumberAnimation {
duration: 150
easing.type: Easing.InQuart
}
}
Behavior on y {
Ext.NumberAnimation {
duration: 150
easing.type: Easing.InQuart
}
}
// final animation
Ext.SequentialAnimation {
objectName: "wiggle_box"
loops: 3
RotationAnimation {
target: box2
property: "rotation"
from: 0; to: 30
duration: 150
}
RotationAnimation {
target: box2
property: "rotation"
from: 30; to: -30
duration: 300
}
RotationAnimation {
target: box2
property: "rotation"
from: -30; to: 0
duration: 150
}
}
}

View file

@ -0,0 +1,4 @@
import QtQuick
Image {
}

View file

@ -0,0 +1,30 @@
import QtQuick
import "../" as Ext
Image {
id: player
Behavior on x {
Ext.NumberAnimation {
duration: 120
easing.type: Easing.InOutSine
}
}
Behavior on y {
Ext.NumberAnimation {
duration: 120
easing.type: Easing.InOutSine
}
}
// final animation
Ext.RotationAnimation {
objectName: "rotate_player"
target: player
property: "rotation"
from: 0; to: 360
duration: 600
}
}

View file

@ -0,0 +1,157 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Window
import "ext/" as Ext
Rectangle {
id: main
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
color: Qt.darker("lightsteelblue", 1.25)
property bool small: (Math.max(width, height) < 1000)
function isLandscape() { return (Screen.primaryOrientation === Qt.LandscapeOrientation) }
Ext.Dynamic {}
Row {
anchors.centerIn: parent
// adapt 'level' and 'board' scale to screen size
scale: isLandscape()
? ((Screen.desktopAvailableHeight - 10) / board.height)
: ((Screen.desktopAvailableWidth - 10) / (board.width + 2 * level.width))
Slider {
id: level
objectName: "level"
height: board.height
orientation: Qt.Vertical
stepSize: 1.0
onValueChanged: Lisp.call("qsoko:set-maze")
}
Rectangle {
id: board
objectName: "board"
width: 512; height: 512
color: "lightsteelblue"
}
// dummy to have it exactly centered
Item {
width: level.width
height: level.height
}
}
Row {
id: buttons1
objectName: "buttons1"
spacing: main.small ? 10 : 15
padding: 10
anchors.bottom: parent.bottom
Ext.Button {
objectName: "previous"
text: "\uf100"
}
Ext.Button {
objectName: "next"
text: "\uf101"
}
}
Row {
id: buttons2
objectName: "buttons2"
spacing: main.small ? 10 : 15
padding: 10
anchors.right: parent.right
anchors.bottom: parent.bottom
Ext.Button {
objectName: "undo"
text: "\uf112"
}
Ext.Button {
objectName: "restart"
text: "\uf0e2"
}
Ext.Button {
objectName: "solve"
text: "\uf17b"
}
}
// container for arrow buttons
Item {
id: arrows
y: buttons1.y - height - (main.small ? 25 : 50)
width: up.width * 3
height: up.height * 3
anchors.margins: 10
anchors.horizontalCenter: buttons2.horizontalCenter
Ext.ArrowButton {
id: up
objectName: "up"
text: "\uf139"
anchors.horizontalCenter: parent.horizontalCenter
}
Ext.ArrowButton {
objectName: "left"
text: "\uf137"
anchors.verticalCenter: parent.verticalCenter
}
Ext.ArrowButton {
objectName: "right"
text: "\uf138"
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
}
Ext.ArrowButton {
objectName: "down"
text: "\uf13a"
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
}
}
// level change animations
Ext.ScaleAnimator {
objectName: "zoom_board_out"
target: board
from: 1.0
to: 0.0
duration: 250
}
Ext.ScaleAnimator {
objectName: "zoom_board_in"
target: board
from: 0.0
to: 1.0
duration: 250
}
// etc
Keys.onPressed: {
if (event.key === Qt.Key_Back) {
event.accepted = true
Lisp.call("qml:qquit")
}
}
FontLoader {
id: fontAwesome
source: "fonts/fontawesome-webfont.ttf"
}
}

View file

@ -30,7 +30,7 @@ win32: PRE_TARGETDEPS = tmp/app.lib
QT += quick qml quickcontrols2 QT += quick qml quickcontrols2
TEMPLATE = app TEMPLATE = app
CONFIG += c++17 no_keywords release CONFIG += c++17 no_keywords release
DEFINES += DESKTOP_APP INI_LISP INI_ASDF INI_ECL_CONTRIB QT_EXTENSION DEFINES += DESKTOP_APP INI_LISP INI_ASDF INI_ECL_CONTRIB QT_EXTENSION # NO_USB
INCLUDEPATH = /usr/local/include INCLUDEPATH = /usr/local/include
ECL_VERSION = $$lower($$system(ecl -v)) ECL_VERSION = $$lower($$system(ecl -v))
ECL_VERSION = $$replace(ECL_VERSION, " ", "-") ECL_VERSION = $$replace(ECL_VERSION, " ", "-")

View file

@ -1,3 +1,5 @@
*This example is outdated and not really useful anymore, sorry.*
Try it Try it
------ ------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -1,10 +0,0 @@
{
"UrlTemplate": "https://tile.openstreetmap.org/%z/%x/%y.png",
"ImageFormat": "png",
"QImageFormat": "Indexed8",
"ID": "cl-meshtastic",
"MaximumZoomLevel": 19,
"MapCopyRight": "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
"DataCopyRight": ""
}

View file

@ -105,7 +105,7 @@
<h2>Simple Standalone Device</h2> <h2>Simple Standalone Device</h2>
<img src="img/chatter.jpg" width=280> <img src="img/chatter.jpg" width=280>
<p> <p>
Support for Meshtastic is increasing continuously. These are <i>CircuitMess Chatter 2.0</i> devices (they come in pairs). Currently only available on ebay. Support for Meshtastic is increasing continuously. These are <i>CircuitMess Chatter 2.0</i> devices (they come in pairs). I found them on US amazon, also available on ebay.
</p> </p>
<p> <p>
They have some limitations: they only support <i>MediumSlow</i> instead of <i>LongFast</i>, and have a lousy antenna, but work great if those limitations are acceptable for one's use case. They have some limitations: they only support <i>MediumSlow</i> instead of <i>LongFast</i>, and have a lousy antenna, but work great if those limitations are acceptable for one's use case.

2
examples/palindrome/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -38,8 +38,8 @@ LQML is **BSD** 0 clause.
Tested Tested
------ ------
The examples are only tested with **Qt5.15**. The binding also works with The examples are tested with both **Qt5.15** and **Qt6**. For differences
**Qt6**, but would need some adaption of QML in most examples. It's recommended in Qt6 (mostly in QML) see [examples/Qt6/](examples/Qt6/). It's recommended
to use the new Qt online installer (see [readme-qt](readme-qt.md)), where to use the new Qt online installer (see [readme-qt](readme-qt.md)), where
you can choose to install different Qt versions side by side, sharing the same you can choose to install different Qt versions side by side, sharing the same
Qt Creator. Qt Creator.