Files
harbour-aira/qml/cover/CoverPage.qml
T
Carlo 2136122398 0.6.9: azione sulla copertina (P8) — il boost senza aprire l'app
Sulla copertina compare l'icona del boost (CoverAction). Una sola azione: la
documentazione Silica ammette piu' di una azione ma dice che lo stile delle app
di sistema ne mostra una. CoverBackground eredita da Cover, quindi l'elenco
dichiarato li' si attacca; l'icona e' iconSource (non icon.source del Button:
sbagliarlo non da' errore, l'icona semplicemente non compare). La riga in fondo
si ancora a Cover.coverActionArea, cosi' l'icona non la copre.

Nuovo controllo statico tests/cover_action_check.py: elenco figlio diretto del
Cover, una sola azione, icona che esiste, id del comando presente nella tabella
del bridge. Il componente e' nominato nella guida Silica dell'SDK di Carlo.
2026-10-11 11:35:49 +02:00

180 lines
6.6 KiB
QML

import QtQuick 2.0
import Sailfish.Silica 1.0
// Copertina: legge api.summary (context property C++), quindi non dipende
// dallo scope delle property della pagina principale.
//
// Due righe con l'etichetta davanti — "Casa" e "Acqua calda" — ognuna con il
// valore attuale e l'obiettivo. L'etichetta dell'acqua e' lunga e la cover e'
// stretta: percio' il valore attuale sta piu' grande e l'obiettivo piu' piccolo
// e attaccato ("51,5/55,0 °C"), invece di due numeri della stessa taglia che
// costringerebbero a tagliare. Prima erano frasi lunghe ("ACS 53,4 °C ·
// obiettivo 55 °C") e il numero vero spariva a meta' riga.
CoverBackground {
id: cover
function t(key) {
var v = api.summary[key]
return api.formatValue(v)
}
// "/19,0 °C": l'obiettivo attaccato al valore attuale. Niente spazio dopo la
// barra: con l'etichetta lunga e' quello che tiene la riga dentro la cover.
function obiettivo(key) {
return "/" + cover.t(key) + " °C"
}
// Colore del pallino: gli stessi criteri della Home (vedi MainPage.qml).
// Un dato vecchio e' ambra come un modo attivo: un dato vecchio non e' un
// dato buono, e la copertina e' il posto dove si guarda di sfuggita.
// Rosso solo per un allarme che ferma la macchina (livello 3): un avviso
// (livello 2) e' ambra.
function statusColor() {
if (!api.hasData || api.stale)
return "orange"
var livello = api.statusLevel()
if (livello === 3)
return Theme.errorColor
if (livello === 2)
return "#ffb300"
if (livello === 1)
return Theme.highlightColor
return "#4caf50"
}
Row {
id: intestazione
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Theme.paddingLarge
spacing: Theme.paddingSmall
Rectangle {
anchors.verticalCenter: parent.verticalCenter
width: Theme.paddingSmall
height: width
radius: width / 2
color: cover.statusColor()
}
Label {
text: "Aira"
color: Theme.primaryColor
font.pixelSize: Theme.fontSizeLarge
}
}
Column {
anchors.centerIn: parent
width: parent.width - 2 * Theme.paddingMedium
spacing: Theme.paddingMedium
// ---- casa ---------------------------------------------------------- //
Row {
id: rigaCasa
width: parent.width
spacing: Theme.paddingSmall
Label {
text: qsTr("House")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
width: rigaCasa.width * 0.42
anchors.verticalCenter: parent.verticalCenter
}
Row {
width: rigaCasa.width * 0.58 - rigaCasa.spacing
spacing: 0
anchors.verticalCenter: parent.verticalCenter
Label {
id: casaOra
// Spento quando i numeri sono vecchi: non deve sembrare fresco.
text: cover.t("zone1_temperature")
color: api.stale ? Theme.secondaryColor : Theme.primaryColor
font.pixelSize: Theme.fontSizeSmall
font.bold: true
}
Label {
text: cover.obiettivo("zone1_setpoint")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
width: parent.width - casaOra.width
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
}
}
// ---- acqua calda --------------------------------------------------- //
Row {
id: rigaAcqua
width: parent.width
spacing: Theme.paddingSmall
Label {
text: qsTr("Hot water")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
width: rigaAcqua.width * 0.42
anchors.verticalCenter: parent.verticalCenter
}
Row {
width: rigaAcqua.width * 0.58 - rigaAcqua.spacing
spacing: 0
anchors.verticalCenter: parent.verticalCenter
Label {
id: acquaOra
text: cover.t("dhw_current")
color: api.stale ? Theme.secondaryColor : Theme.primaryColor
font.pixelSize: Theme.fontSizeSmall
font.bold: true
}
Label {
text: cover.obiettivo("dhw_target")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
width: parent.width - acquaOra.width
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
// Sopra l'area delle azioni: quando l'azione c'e', Silica disegna li'
// l'icona del boost, che non deve coprire questa riga. Se l'area non
// c'e' la riga resta attaccata al fondo, come prima.
anchors.bottom: cover.coverActionArea ? cover.coverActionArea.top : parent.bottom
anchors.bottomMargin: Theme.paddingMedium
// Qui c'e' posto per dire che i numeri non sono freschi.
text: api.stale
? qsTr("Not updated · last %1").arg(api.lastUpdate)
: qsTr("outside %1 °C").arg(cover.t("outdoor_temperature"))
color: api.stale ? "orange" : Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
truncationMode: TruncationMode.Fade
width: parent.width - 2 * Theme.paddingMedium
}
// ---- azione sulla copertina (P8) --------------------------------------- //
// Agire senza aprire l'app: il boost dell'acqua calda. Una sola, perche' la
// documentazione Silica dice che due azioni si possono avere ma che lo stile
// delle app di sistema ne mostra una. CoverBackground eredita da Cover,
// quindi l'elenco si attacca: e' il posto documentato dove dichiararlo.
// Il componente e' in Sailfish.Silica 1.0 (verificato nella guida dell'SDK).
CoverActionList {
CoverAction {
iconSource: "../icons/quick-boost.png"
onTriggered: api.sendCommand("hot_water_boost_on")
}
}
}