C
Qt Quick Ultralite Watch Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QtQuick 2.15
import QtQuickUltralite.Extras 2.0
import Watch 1.0
Item {
id: root
height: Theme.appHeight
width: Theme.appWidth
property bool onScreen: false
property bool offScreen: false
readonly property real startOp: 0.0
readonly property real startForecastMargin: 40
readonly property real startDescriptionMargin: 10
readonly property real startTopMargin: height / 2 - currentWeather.height / 2
readonly property int introDuration: 150
readonly property int introDurationLong: 250
SequentialAnimation {
id: intro
ParallelAnimation {
NumberAnimation { target: currentWeather; property: "margin"; to: 30; easing.type: Easing.InOutCubic; duration: introDurationLong }
NumberAnimation { target: weatherCity; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDurationLong }
}
NumberAnimation { target: bottomMask; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDurationLong }
ParallelAnimation {
NumberAnimation { target: weatherForecast; property: "tueOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration }
NumberAnimation { target: weatherForecast; property: "tueMargin"; to: 20; easing.type: Easing.OutCubic; duration: introDuration }
}
ParallelAnimation {
NumberAnimation { target: weatherForecast; property: "wedOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration }
NumberAnimation { target: weatherForecast; property: "wedMargin"; to: 20; easing.type: Easing.OutCubic; duration: introDuration }
}
ParallelAnimation {
NumberAnimation { target: weatherForecast; property: "thuOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration }
NumberAnimation { target: weatherForecast; property: "thuMargin"; to: 20; easing.type: Easing.OutCubic; duration: introDuration }
}
NumberAnimation { target: weatherForecast; property: "sepOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration }
ParallelAnimation {
NumberAnimation { target: weatherDescription; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDurationLong }
NumberAnimation { target: weatherDescription; property: "bottomMar"; to: 30; easing.type: Easing.OutCubic; duration: introDurationLong }
}
}
/*
* Current weather
*/
Column {
id: currentWeather
anchors.right: parent.right
anchors.rightMargin: parent.width / 2 - width
anchors.top: parent.top
anchors.topMargin: margin
property int margin: startTopMargin
Text {
text: "18°"
font.pixelSize: 61
font.family: Theme.fontFamily
font.weight: Font.Medium
color: Theme.whiteColor
}
Text {
id: weatherCity
opacity: 0.0
text: "BERLIN"
font.pixelSize: 20
font.family: Theme.fontFamily
color: Theme.whiteColor
}
}
/*
* Weather big icon
*/
Image {
id: weatherIcon
anchors.verticalCenter: currentWeather.verticalCenter
anchors.right: currentWeather.left
anchors.rightMargin: 10
source: "images/weather/big-sun.png"
}
/*
* Weather description
*/
Row {
id: weatherDescription
anchors.bottom: bottomMask.top
anchors.bottomMargin: bottomMar
anchors.horizontalCenter: parent.horizontalCenter
spacing: 15
opacity: startOp
property real bottomMar: startDescriptionMargin
Image {
source: "images/weather/ion-ios-rainy-outline.png"
}
StaticText {
text: "Rain in 4 hours (17:00)"
font.pixelSize: 25
font.family: Theme.fontFamily
color: Theme.whiteColor
}
}
Image {
id: bottomMask
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
source: "images/weather/w-bottom-mask.png"
opacity: startOp
}
/*
* Bottom weather forecast
*/
Row {
id: weatherForecast
anchors.top: bottomMask.top
anchors.horizontalCenter: parent.horizontalCenter
property real tueOpacity: startOp
property real wedOpacity: startOp
property real thuOpacity: startOp
property real sepOpacity: startOp
property real tueMargin: startForecastMargin
property real wedMargin: startForecastMargin
property real thuMargin: startForecastMargin
Repeater {
model: ListModel {
ListElement { day: "TUE"; weatherImg: "images/weather/ion-ios-partlysunny-outline.png"; temperature: "21°C" }
ListElement { day: "WED"; weatherImg: "images/weather/ion-ios-rainy-outline.png"; temperature: "19°C" }
ListElement { day: "THU"; weatherImg: "images/weather/ion-ios-sunny-outline.png"; temperature: "23°C" }
}
delegate: Item {
width: 90
opacity: getOpacity(index)
Text {
id: dayLabel
anchors.left: temperatureLabel.left
anchors.top: parent.top
anchors.topMargin: getMargin(index)
text: model.day
font.pixelSize: 14
font.family: Theme.fontFamily
color: Theme.whiteColor
}
Text {
id: temperatureLabel
anchors.top: dayLabel.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: model.temperature
font.pixelSize: 30
font.family: Theme.fontFamily
color: Theme.whiteColor
}
Image {
anchors.topMargin: 30 - height / 2
anchors.top: temperatureLabel.bottom
anchors.horizontalCenter: temperatureLabel.horizontalCenter
source: model.weatherImg
}
Image {
anchors.top: parent.top
anchors.right: parent.right
visible: index < 2
source: "images/weather/w-vertical.png"
opacity: weatherForecast.sepOpacity
}
}
}
}
onOnScreenChanged: {
if (onScreen) {
intro.running = true
}
}
onOffScreenChanged: {
if (offScreen) {
resetIntro()
}
}
function resetIntro() {
intro.running = false
currentWeather.margin = startTopMargin
weatherCity.opacity = startOp
bottomMask.opacity = startOp
weatherForecast.tueOpacity = startOp
weatherForecast.wedOpacity = startOp
weatherForecast.thuOpacity = startOp
weatherForecast.sepOpacity = startOp
weatherDescription.opacity = startOp
weatherForecast.tueMargin = startForecastMargin
weatherForecast.wedMargin = startForecastMargin
weatherForecast.thuMargin = startForecastMargin
weatherDescription.bottomMar = startDescriptionMargin
}
function getOpacity(index : int) : real {
switch(index) {
case 0:
return weatherForecast.tueOpacity
case 1:
return weatherForecast.wedOpacity
case 2:
return weatherForecast.thuOpacity
}
}
function getMargin(index : int) : real {
switch(index) {
case 0:
return weatherForecast.tueMargin
case 1:
return weatherForecast.wedMargin
case 2:
return weatherForecast.thuMargin
}
}
}