WIP Add more examples content
63
Content/wallpaper_html/index.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="">
|
||||
<style>
|
||||
/* Set the font to the default system font */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
|
||||
/* Add a gradient from a deep blue to a sky blue as the body background */
|
||||
background: linear-gradient(to top, #0D47A1, #87ceeb);
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
/* Create a container and center items vertically and horizontally */
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Center the h1 element */
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Define the initial state of the div */
|
||||
.color-change {
|
||||
text-align: center;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
background-color:#D84315;
|
||||
transition: background-color 0.5s ease; /* Smooth transition */
|
||||
}
|
||||
|
||||
/* Define the hover state of the div */
|
||||
.color-change:hover {
|
||||
background-color: #FF5722 ;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>This is my HTML Wallpaper 🚀</h1>
|
||||
<div class="color-change">
|
||||
Hover over me!
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
Content/wallpaper_html/preview.png
Normal file
After Width: | Height: | Size: 38 KiB |
10
Content/wallpaper_html/project.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"createdBy": "",
|
||||
"file": "index.html",
|
||||
"preview": "preview.png",
|
||||
"license": "Creative Commons - Attribution-ShareAlike 4.0",
|
||||
"tags": [
|
||||
],
|
||||
"title": "test",
|
||||
"type": "HTMLWallpaper"
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
@ -8,9 +9,20 @@ Rectangle {
|
||||
id: root
|
||||
color: "#333333"
|
||||
anchors.fill: parent
|
||||
|
||||
Button {
|
||||
property int counter: 0
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
color: "white"
|
||||
font.pointSize: 14
|
||||
text: "🎉 Qml Button clicked: " + root.counter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
Button {
|
||||
text: "Click me!"
|
||||
Layout.fillWidth: true
|
||||
onClicked: root.counter++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 36 KiB |
@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Particles
|
||||
@ -43,33 +42,22 @@ Item {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
Component.onCompleted: {
|
||||
attractor.pointX = parent.width * .5;
|
||||
attractor.pointY = 0;
|
||||
attractor.pointX = parent.width * .5
|
||||
attractor.pointY = 0
|
||||
}
|
||||
|
||||
onPressed:
|
||||
//attractor.enabled = true
|
||||
{
|
||||
onPressed: {
|
||||
attractor.enabled = true
|
||||
}
|
||||
onPositionChanged: {
|
||||
attractor.pointX = mouseX;
|
||||
attractor.pointY = mouseY;
|
||||
rct.x = mouseX;
|
||||
rct.y = mouseY;
|
||||
attractor.pointX = mouseX
|
||||
attractor.pointY = mouseY
|
||||
}
|
||||
onReleased:
|
||||
//attractor.enabled = false
|
||||
{
|
||||
onReleased: {
|
||||
attractor.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rct
|
||||
color: "orange"
|
||||
width: 40
|
||||
height: 40
|
||||
}
|
||||
|
||||
Attractor {
|
||||
id: attractor
|
||||
system: particleSystem
|
||||
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 765 B After Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 518 B After Width: | Height: | Size: 518 B |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 528 B |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
@ -8,31 +8,32 @@ Item {
|
||||
implicitHeight: 100
|
||||
|
||||
function timeChanged() {
|
||||
var date = new Date;
|
||||
var hours = "";
|
||||
var minutes = "";
|
||||
var seconds = "";
|
||||
var date = new Date
|
||||
var hours = ""
|
||||
var minutes = ""
|
||||
var seconds = ""
|
||||
if (date.getHours() < 10) {
|
||||
hours = "0" + date.getHours().toString();
|
||||
hours = "0" + date.getHours().toString()
|
||||
} else {
|
||||
hours = date.getHours().toString();
|
||||
hours = date.getHours().toString()
|
||||
}
|
||||
if (date.getMinutes() < 10) {
|
||||
minutes = "0" + date.getMinutes().toString();
|
||||
minutes = "0" + date.getMinutes().toString()
|
||||
} else {
|
||||
minutes = date.getMinutes().toString();
|
||||
minutes = date.getMinutes().toString()
|
||||
}
|
||||
if (date.getSeconds() < 10) {
|
||||
seconds = "0" + date.getSeconds().toString();
|
||||
seconds = "0" + date.getSeconds().toString()
|
||||
} else {
|
||||
seconds = date.getSeconds().toString();
|
||||
seconds = date.getSeconds().toString()
|
||||
}
|
||||
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
var day = days[date.getDay()];
|
||||
var month = months[date.getMonth()];
|
||||
txtClock.text = hours + ":" + minutes + ":" + seconds;
|
||||
txtDate.text = day + ", " + date.getDay() + " " + month + ", " + date.getFullYear();
|
||||
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
||||
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
var day = days[date.getDay()]
|
||||
var month = months[date.getMonth()]
|
||||
txtClock.text = hours + ":" + minutes + ":" + seconds
|
||||
txtDate.text = day + ", " + date.getDay(
|
||||
) + " " + month + ", " + date.getFullYear()
|
||||
}
|
||||
|
||||
Timer {
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
@ -1,47 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitHeight: 100
|
||||
implicitWidth: 300
|
||||
|
||||
property string published
|
||||
property string rights
|
||||
property string updated
|
||||
property string category
|
||||
property string title
|
||||
property string link
|
||||
property string summary
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: 14
|
||||
wrapMode: Text.Wrap
|
||||
text: model.title
|
||||
height: 20
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.Wrap
|
||||
text: model.summary
|
||||
font.pointSize: 10
|
||||
height: 20
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
print(model.link);
|
||||
Qt.openUrlExternally(model.link);
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 111 KiB |
57
Content/widget_rss_guardian_news/PostDelegate.qml
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitHeight: 80
|
||||
implicitWidth: 300
|
||||
|
||||
property string published
|
||||
property string rights
|
||||
property string updated
|
||||
property string category
|
||||
property string title
|
||||
property string link
|
||||
property string mediaContent
|
||||
onMediaContentChanged: {
|
||||
print("src")
|
||||
const src = parseItem(model.mediaContent, 'url="', '"')
|
||||
print("src", src)
|
||||
//img.source = src;
|
||||
}
|
||||
|
||||
function parseItem(raw, startTag, endTag) {
|
||||
var startIdx = raw.indexOf(startTag) + startTag.length
|
||||
var endIdx = raw.indexOf(endTag, startIdx)
|
||||
return raw.substring(startIdx, endIdx)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Image {
|
||||
id: img
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Text {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: 12
|
||||
wrapMode: Text.Wrap
|
||||
text: model.title
|
||||
height: 20
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
print(model.category)
|
||||
print(model.mediaContent)
|
||||
//Qt.openUrlExternally(model.link);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
@ -14,36 +14,14 @@ Item {
|
||||
|
||||
XmlListModel {
|
||||
id: feedModel
|
||||
source: "https://rss.dw.com/atom/rss-en-all"
|
||||
query: "/feed/entry"
|
||||
onCountChanged: {
|
||||
console.log("count ", count);
|
||||
}
|
||||
source: "https://www.theguardian.com/world/rss"
|
||||
query: "/rss/channel/item"
|
||||
onStatusChanged: {
|
||||
print("status ", status);
|
||||
console.log("count ", count);
|
||||
if (status === XmlListModel.Error) {
|
||||
console.log("Error: " + errorString);
|
||||
console.log("Error: " + errorString)
|
||||
}
|
||||
}
|
||||
|
||||
XmlListModelRole {
|
||||
name: "published"
|
||||
elementName: "published"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "rights"
|
||||
elementName: "rights"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "updated"
|
||||
elementName: "updated"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "category"
|
||||
elementName: "category"
|
||||
attributeName: "term"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "title"
|
||||
elementName: "title"
|
||||
@ -51,11 +29,36 @@ Item {
|
||||
XmlListModelRole {
|
||||
name: "link"
|
||||
elementName: "link"
|
||||
attributeName: "href"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "summary"
|
||||
elementName: "summary"
|
||||
name: "description"
|
||||
elementName: "description"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "category"
|
||||
elementName: "category"
|
||||
attributeName: "domain"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "pubDate"
|
||||
elementName: "pubDate"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "guid"
|
||||
elementName: "guid"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "creator"
|
||||
elementName: "dc:creator"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "date"
|
||||
elementName: "dc:date"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "mediaContent"
|
||||
elementName: "media:content"
|
||||
attributeName: "url"
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ Item {
|
||||
spacing: 10
|
||||
model: feedModel
|
||||
delegate: PostDelegate {
|
||||
width: parent.width
|
||||
width: root.width
|
||||
}
|
||||
}
|
||||
}
|
BIN
Content/widget_rss_guardian_news/preview.png
Normal file
After Width: | Height: | Size: 136 KiB |
94
Content/widget_rss_hackernews/PostDelegate.qml
Normal file
@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayAssets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
height: wrapper.childrenRect.height
|
||||
|
||||
property string points
|
||||
property string commentCount
|
||||
property string pubDate
|
||||
property string pubDateFormatted
|
||||
onPubDateChanged: {
|
||||
var date = new Date(pubDate)
|
||||
root.pubDateFormatted = date.toLocaleDateString(
|
||||
Qt.locale(),
|
||||
"ddd, dd MMM yyyy") + ' ' + date.toLocaleTimeString(
|
||||
Qt.locale(), "HH:mm:ss")
|
||||
}
|
||||
property string description
|
||||
onDescriptionChanged: {
|
||||
print("description")
|
||||
// See https://hnrss.org/frontpage <description> content
|
||||
// We need to manually parse it here to get the points and comments
|
||||
points = parsePoints(description)
|
||||
commentCount = parseCommentCount(description)
|
||||
print(points, commentCount)
|
||||
}
|
||||
|
||||
function parseCommentCount(raw) {
|
||||
var commentPrefix = "<p># Comments: "
|
||||
var commentSuffix = "</p>"
|
||||
var startIdx = raw.indexOf(commentPrefix)
|
||||
if (startIdx === -1)
|
||||
return "N/A" // return "N/A" if comment count is not found in the description
|
||||
startIdx += commentPrefix.length
|
||||
var endIdx = raw.indexOf(commentSuffix, startIdx)
|
||||
return raw.substring(startIdx, endIdx)
|
||||
}
|
||||
function parsePoints(raw) {
|
||||
var pointsPrefix = "<p>Points: "
|
||||
var pointsSuffix = "</p>"
|
||||
var startIdx = raw.indexOf(pointsPrefix)
|
||||
if (startIdx === -1)
|
||||
return "N/A" // return "N/A" if points are not found in the description
|
||||
startIdx += pointsPrefix.length
|
||||
var endIdx = raw.indexOf(pointsSuffix, startIdx)
|
||||
return raw.substring(startIdx, endIdx)
|
||||
}
|
||||
RowLayout {
|
||||
id: wrapper
|
||||
width: root.width
|
||||
spacing: 5
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Text {
|
||||
id: titleText
|
||||
text: model.title
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
color: "white"
|
||||
Layout.maximumWidth: wrapper.width * .9
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(model.link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: descriptionText
|
||||
text: root.points + " Points • " + root.commentCount
|
||||
+ " Comments 🔗 " + "• Published: " + root.pubDateFormatted
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 10
|
||||
opacity: .7
|
||||
color: "white"
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(model.commentsLink)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
Content/widget_rss_hackernews/Readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
Widget that shows the latest dw feed
|
||||
|
||||
https://corporate.dw.com/en/rss/s-31500
|
117
Content/widget_rss_hackernews/main.qml
Normal file
@ -0,0 +1,117 @@
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQml.XmlListModel
|
||||
import ScreenPlayAssets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 480
|
||||
implicitHeight: 480
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
id: combo
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
Layout.preferredHeight: 50
|
||||
valueRole: "rssurl"
|
||||
textRole: "text"
|
||||
Material.foreground: "white"
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
text: "Best"
|
||||
rssurl: "https://hnrss.org/best"
|
||||
}
|
||||
ListElement {
|
||||
text: "Front Page"
|
||||
rssurl: "https://hnrss.org/frontpage"
|
||||
}
|
||||
ListElement {
|
||||
text: "Jobs"
|
||||
rssurl: "https://hnrss.org/jobs"
|
||||
}
|
||||
ListElement {
|
||||
text: "Newest > 100 pts"
|
||||
rssurl: "https://hnrss.org/newest?points=100"
|
||||
}
|
||||
}
|
||||
onActivated: {
|
||||
rssModel.source = combo.currentValue
|
||||
}
|
||||
}
|
||||
ToolButton {
|
||||
text: "Reload"
|
||||
Material.foreground: "white"
|
||||
onPressed: rssModel.load()
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 10
|
||||
clip: true
|
||||
model: rssModel
|
||||
delegate: PostDelegate {
|
||||
width: root.width
|
||||
description: model.description
|
||||
pubDate: model.pubDate
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
interval: 15 * 60 * 1000 // 15 minutes
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: rssModel.load()
|
||||
}
|
||||
XmlListModel {
|
||||
id: rssModel
|
||||
source: combo.currentValue
|
||||
query: "/rss/channel/item"
|
||||
function load() {
|
||||
print(":load")
|
||||
var tempSource = rssModel.source
|
||||
rssModel.source = ""
|
||||
rssModel.source = tempSource
|
||||
}
|
||||
|
||||
XmlListModelRole {
|
||||
name: "title"
|
||||
elementName: "title"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "link"
|
||||
elementName: "link"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "creator"
|
||||
elementName: "dc:creator"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "commentsLink"
|
||||
elementName: "comments"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "guid"
|
||||
elementName: "guid"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "description"
|
||||
elementName: "description"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "pubDate"
|
||||
elementName: "pubDate"
|
||||
}
|
||||
}
|
||||
}
|
BIN
Content/widget_rss_hackernews/preview.png
Normal file
After Width: | Height: | Size: 73 KiB |
12
Content/widget_rss_hackernews/project.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"description": "Widget that shows the latest hackernews feed",
|
||||
"file": "main.qml",
|
||||
"preview": "preview.png",
|
||||
"tags": [
|
||||
"hackernews",
|
||||
"rss",
|
||||
"feed"
|
||||
],
|
||||
"title": "hackernews",
|
||||
"type": "qmlWidget"
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitHeight: 300
|
||||
implicitWidth: 300
|
||||
|
||||
property string contentRaw: model.content
|
||||
property url href
|
||||
onContentRawChanged: {
|
||||
// Define the regular expression to match the image URL
|
||||
var regex = /<a\s+href="((?:https?:\/\/)?i\.redd\.it\/[^"]+\.jpg)">\[link\]<\/a>/i;
|
||||
|
||||
// Parse the image URL from the HTML content
|
||||
var match = regex.exec(contentRaw);
|
||||
if (match != null) {
|
||||
var imageUrl = match[1];
|
||||
var href = match[2];
|
||||
img.source = "" + imageUrl;
|
||||
root.href = "" + href;
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: img
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: img
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#00333333"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#ff333333"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
wrapMode: Text.Wrap
|
||||
width: parent.width
|
||||
text: model.title
|
||||
height: 20
|
||||
color: "white"
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
print(model.link);
|
||||
Qt.openUrlExternally(model.link);
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
Widget that shows the latest reddit feed
|
@ -1,60 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Particles
|
||||
import QtQml.XmlListModel
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 480
|
||||
implicitHeight: 480
|
||||
|
||||
property string subreddit: "funny"
|
||||
|
||||
XmlListModel {
|
||||
id: feedModel
|
||||
onStatusChanged: {
|
||||
print("status ", status);
|
||||
if (status === XmlListModel.Error) {
|
||||
console.log("Error: " + errorString);
|
||||
}
|
||||
}
|
||||
|
||||
source: "https://www.reddit.com/r/" + root.subreddit + "/.rss"
|
||||
query: "/feed/entry"
|
||||
|
||||
XmlListModelRole {
|
||||
name: "updated"
|
||||
elementName: "updated"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "subtitle"
|
||||
elementName: "subtitle"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "content"
|
||||
elementName: "content"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "link"
|
||||
elementName: "link"
|
||||
attributeName: "href"
|
||||
}
|
||||
XmlListModelRole {
|
||||
name: "title"
|
||||
elementName: "title"
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
anchors.fill: parent
|
||||
model: feedModel
|
||||
delegate: PostDelegate {
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 184 KiB |
@ -1,16 +0,0 @@
|
||||
{
|
||||
"description": "Widget that shows the latest reddit feed",
|
||||
"file": "main.qml",
|
||||
"preview": "preview.png",
|
||||
"tags": [
|
||||
"reddit"
|
||||
],
|
||||
"title": "reddit",
|
||||
"type": "qmlWidget",
|
||||
"properties": {
|
||||
"subreddit": {
|
||||
"type": "string",
|
||||
"value": "funny"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
@ -28,11 +28,11 @@ Item {
|
||||
}
|
||||
|
||||
function stringListToString(list) {
|
||||
let out = "";
|
||||
let out = ""
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
out += "\n" + list[i];
|
||||
out += "\n" + list[i]
|
||||
}
|
||||
return out;
|
||||
return out
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@ -57,7 +57,8 @@ Item {
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: root.stringListToString(ipAddress.privateIpV4AddressList)
|
||||
text: root.stringListToString(
|
||||
ipAddress.privateIpV4AddressList)
|
||||
color: root.accentColor
|
||||
font {
|
||||
pointSize: 16
|
||||
@ -65,7 +66,8 @@ Item {
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: root.stringListToString(ipAddress.privateIpV6AddressList)
|
||||
text: root.stringListToString(
|
||||
ipAddress.privateIpV6AddressList)
|
||||
color: root.accentColor
|
||||
font {
|
||||
pointSize: 16
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
@ -20,56 +20,56 @@ Item {
|
||||
id: weather
|
||||
city: "Friedrichshafen"
|
||||
onReady: {
|
||||
rp.model = weather.days;
|
||||
rp.model = weather.days
|
||||
// Qt bug https://bugreports.qt.io/browse/QTBUG-105137
|
||||
test();
|
||||
test()
|
||||
}
|
||||
}
|
||||
function test() {
|
||||
}
|
||||
function test() {}
|
||||
|
||||
function mapWeatherCode(code) {
|
||||
const weather_time = ""; // or "-day", "-night"
|
||||
const weather_prefix = "wi" + weather_time + "-";
|
||||
const weather_time = ""
|
||||
// or "-day", "-night"
|
||||
const weather_prefix = "wi" + weather_time + "-"
|
||||
// https://open-meteo.com/en/docs
|
||||
// WMO Weather interpretation codes (WW)
|
||||
// to https://erikflowers.github.io/weather-icons/
|
||||
switch (code) {
|
||||
case 0:
|
||||
return weather_prefix + "day-sunny";
|
||||
return weather_prefix + "day-sunny"
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
return weather_prefix + "cloud";
|
||||
return weather_prefix + "cloud"
|
||||
case 45:
|
||||
case 48:
|
||||
return weather_prefix + "day-sunny";
|
||||
return weather_prefix + "day-sunny"
|
||||
case 51:
|
||||
case 53:
|
||||
case 55:
|
||||
return weather_prefix + "rain-mix";
|
||||
return weather_prefix + "rain-mix"
|
||||
case 61:
|
||||
case 63:
|
||||
case 65:
|
||||
return weather_prefix + "rain-mix";
|
||||
return weather_prefix + "rain-mix"
|
||||
case 71:
|
||||
case 73:
|
||||
case 75:
|
||||
return weather_prefix + "snow";
|
||||
return weather_prefix + "snow"
|
||||
case 77:
|
||||
return weather_prefix + "snow";
|
||||
return weather_prefix + "snow"
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
return weather_prefix + "snow";
|
||||
return weather_prefix + "snow"
|
||||
case 85:
|
||||
case 86:
|
||||
return weather_prefix + "snow";
|
||||
return weather_prefix + "snow"
|
||||
case 95:
|
||||
return weather_prefix + "thunderstorm";
|
||||
return weather_prefix + "thunderstorm"
|
||||
case 96:
|
||||
case 99:
|
||||
return weather_prefix + "storm-showers";
|
||||
return weather_prefix + "storm-showers"
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,9 @@ Item {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Material.primaryTextColor
|
||||
text: "longtitude: " + weather.longtitude + " - latitude: " + weather.latitude + " - elevation: " + weather.elevation + "m - population: " + weather.population
|
||||
text: "longtitude: " + weather.longtitude + " - latitude: "
|
||||
+ weather.latitude + " - elevation: " + weather.elevation
|
||||
+ "m - population: " + weather.population
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@ -127,7 +129,8 @@ Item {
|
||||
}
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
horizontalAlignment: Image.AlignHCenter
|
||||
source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(weatherCode) + ".svg"
|
||||
source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(
|
||||
weatherCode) + ".svg"
|
||||
}
|
||||
TextItem {
|
||||
text: "Weather Code"
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
@ -8,45 +8,84 @@ import QtQuick.Particles
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 360
|
||||
implicitHeight: 360
|
||||
state: "normal"
|
||||
implicitWidth: defaultWidth
|
||||
implicitHeight: defaultHeight
|
||||
property int defaultWidth: 200
|
||||
property int defaultHeight: 200
|
||||
|
||||
Image {
|
||||
id: img
|
||||
anchors.fill: parent
|
||||
onStatusChanged: {
|
||||
if (img.status !== Image.Ready)
|
||||
return;
|
||||
if (img.sourceSize.width === 0 || img.sourceSize.height === 0)
|
||||
return;
|
||||
root.implicitHeight = img.sourceSize.height;
|
||||
root.implicitWidth = img.sourceSize.width;
|
||||
function request(url, callback) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.onreadystatechange = (function (myxhr) {
|
||||
return function () {
|
||||
if (myxhr.readyState === 4)
|
||||
callback(myxhr)
|
||||
}
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
})(xhr)
|
||||
xhr.open('GET', url)
|
||||
xhr.send('')
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
request("http://xkcd.com/info.0.json", function (o) {
|
||||
if (o.status === 200) {
|
||||
var d = eval('new Object(' + o.responseText + ')');
|
||||
console.log(o.responseText);
|
||||
img.source = d.img;
|
||||
var d = eval('new Object(' + o.responseText + ')')
|
||||
console.log(o.responseText)
|
||||
img.source = d.img
|
||||
} else {
|
||||
console.log("Some error has occurred");
|
||||
console.log("Some error has occurred")
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function request(url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = (function (myxhr) {
|
||||
return function () {
|
||||
if (myxhr.readyState === 4)
|
||||
callback(myxhr);
|
||||
};
|
||||
})(xhr);
|
||||
xhr.open('GET', url);
|
||||
xhr.send('');
|
||||
Image {
|
||||
id: img
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
property size imgSize: Qt.size(root.defaultWidth, defaultHeight)
|
||||
onStatusChanged: {
|
||||
if (img.status !== Image.Ready)
|
||||
return
|
||||
if (img.sourceSize.width === 0 || img.sourceSize.height === 0)
|
||||
return
|
||||
root.implicitWidth = img.sourceSize.width
|
||||
root.implicitHeight = img.sourceSize.height
|
||||
print(img.status, img.sourceSize.width, img.sourceSize.height)
|
||||
img.imgSize = Qt.size(img.sourceSize.width, img.sourceSize.height)
|
||||
print("img.size", img.imgSize)
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.state = root.state === "expanded" ? "normal" : "expanded"
|
||||
print(root.state, root.implicitHeight, root.implicitWidth)
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
PropertyChanges {
|
||||
name: "normal"
|
||||
root {
|
||||
width: root.defaultWidth
|
||||
height: root.defaultHeight
|
||||
implicitWidth: root.defaultWidth
|
||||
implicitHeight: root.defaultHeight
|
||||
}
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "expanded"
|
||||
PropertyChanges {
|
||||
root {
|
||||
width: img.imgSize.width
|
||||
height: img.imgSize.height
|
||||
implicitWidth: img.imgSize.width
|
||||
implicitHeight: img.imgSize.height
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -11,9 +11,17 @@ Item {
|
||||
implicitWidth: 240
|
||||
implicitHeight: 120
|
||||
property int totalHours: 24
|
||||
property int remainingHours: Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000))
|
||||
property int totalDays: new Date(new Date().getFullYear() + 1, 0, 1) - new Date() / (24 * 60 * 60 * 1000)
|
||||
property int remainingDays: Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000)))
|
||||
property int remainingHours: Math.max(0, Math.floor(
|
||||
(new Date().setHours(
|
||||
24, 0, 0,
|
||||
0) - new Date()) / 3600000))
|
||||
property int totalDays: new Date(new Date().getFullYear() + 1, 0,
|
||||
1) - new Date() / (24 * 60 * 60 * 1000)
|
||||
property int remainingDays: Math.max(
|
||||
0, Math.floor(
|
||||
(new Date(new Date().getFullYear() + 1,
|
||||
0,
|
||||
1) - new Date()) / (24 * 60 * 60 * 1000)))
|
||||
|
||||
Material.theme: Material.Dark
|
||||
Material.accent: Material.DeepOrange
|
||||
@ -42,7 +50,11 @@ Item {
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
remainingHours = Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000));
|
||||
remainingHours = Math.max(
|
||||
0,
|
||||
Math.floor((new Date().setHours(
|
||||
24, 0, 0,
|
||||
0) - new Date()) / 3600000))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -69,7 +81,11 @@ Item {
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
remainingDays = Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000)));
|
||||
remainingDays = Math.max(0,
|
||||
Math.floor((new Date(new Date().getFullYear(
|
||||
) + 1,
|
||||
0, 1)
|
||||
- new Date()) / (24 * 60 * 60 * 1000)))
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |