add Qt6 version of some examples (see below); revisions
'9999', 'advanced-qml-auto-reload', 'planets', 'sokoban'
69
examples/Qt6/9999/qml/main.qml
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
2
examples/Qt6/advanced-qml-auto-reload/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
|
|
@ -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)
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/.ext/Page1.qml
Normal 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
|
||||
}
|
||||
}
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/.ext/Page2.qml
Normal 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
|
||||
}
|
||||
}
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/.ext/Page3.qml
Normal 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
|
||||
}
|
||||
}
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/.ext/Repl.qml
Normal 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
|
||||
}
|
||||
}
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/.template.qml
Normal 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
|
||||
}
|
||||
}
|
||||
15
examples/Qt6/advanced-qml-auto-reload/qml/ext/Page1.qml
Normal 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>"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
examples/Qt6/advanced-qml-auto-reload/qml/ext/Page2.qml
Normal 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>"
|
||||
}
|
||||
}
|
||||
}
|
||||
18
examples/Qt6/advanced-qml-auto-reload/qml/ext/Page3.qml
Normal 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>"
|
||||
}
|
||||
}
|
||||
}
|
||||
160
examples/Qt6/advanced-qml-auto-reload/qml/ext/Repl.qml
Normal 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 }}
|
||||
]
|
||||
}
|
||||
49
examples/Qt6/advanced-qml-auto-reload/qml/main.qml
Normal 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
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
2
examples/Qt6/planets/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
193
examples/Qt6/planets/qml/main.qml
Normal 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
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||
16
examples/Qt6/sokoban/qml/ext/ArrowButton.qml
Normal 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")
|
||||
}
|
||||
13
examples/Qt6/sokoban/qml/ext/Button.qml
Normal 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")
|
||||
}
|
||||
21
examples/Qt6/sokoban/qml/ext/Dynamic.qml
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
6
examples/Qt6/sokoban/qml/ext/NumberAnimation.qml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick
|
||||
|
||||
NumberAnimation {
|
||||
onRunningChanged: Lisp.call("qsoko:animation-change", running)
|
||||
}
|
||||
|
||||
6
examples/Qt6/sokoban/qml/ext/RotationAnimation.qml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick
|
||||
|
||||
RotationAnimation {
|
||||
onRunningChanged: Lisp.call("qsoko:animation-change", running)
|
||||
}
|
||||
|
||||
5
examples/Qt6/sokoban/qml/ext/ScaleAnimator.qml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick
|
||||
|
||||
ScaleAnimator {
|
||||
onRunningChanged: Lisp.call("qsoko:animation-change", running)
|
||||
}
|
||||
6
examples/Qt6/sokoban/qml/ext/SequentialAnimation.qml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick
|
||||
|
||||
SequentialAnimation {
|
||||
onRunningChanged: Lisp.call("qsoko:animation-change", running)
|
||||
}
|
||||
|
||||
18
examples/Qt6/sokoban/qml/ext/dynamic/Box.qml
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
48
examples/Qt6/sokoban/qml/ext/dynamic/Box2.qml
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
4
examples/Qt6/sokoban/qml/ext/dynamic/Fixed.qml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import QtQuick
|
||||
|
||||
Image {
|
||||
}
|
||||
30
examples/Qt6/sokoban/qml/ext/dynamic/Player.qml
Normal 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
|
||||
}
|
||||
}
|
||||
157
examples/Qt6/sokoban/qml/main.qml
Normal 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"
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ win32: PRE_TARGETDEPS = tmp/app.lib
|
|||
QT += quick qml quickcontrols2
|
||||
TEMPLATE = app
|
||||
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
|
||||
ECL_VERSION = $$lower($$system(ecl -v))
|
||||
ECL_VERSION = $$replace(ECL_VERSION, " ", "-")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
*This example is outdated and not really useful anymore, sorry.*
|
||||
|
||||
|
||||
Try it
|
||||
------
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 19 KiB |
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@
|
|||
<h2>Simple Standalone Device</h2>
|
||||
<img src="img/chatter.jpg" width=280>
|
||||
<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>
|
||||
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
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
||||