Merge remote-tracking branch 'origin/tuning' into landing-silo
This commit is contained in:
commit
84dc119675
@ -234,5 +234,7 @@
|
|||||||
<file>ui/images/sensors/moisture.svg</file>
|
<file>ui/images/sensors/moisture.svg</file>
|
||||||
<file>ui/images/sensors/pressure.svg</file>
|
<file>ui/images/sensors/pressure.svg</file>
|
||||||
<file>ui/images/sensors/temperature.svg</file>
|
<file>ui/images/sensors/temperature.svg</file>
|
||||||
|
<file>ui/components/MainPageTile.qml</file>
|
||||||
|
<file>ui/images/configure.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -10,4 +10,9 @@ ApplicationWindow {
|
|||||||
Material.theme: Material.Dark
|
Material.theme: Material.Dark
|
||||||
Material.accent: guhAccent
|
Material.accent: guhAccent
|
||||||
Material.primary: Material.background
|
Material.primary: Material.background
|
||||||
|
|
||||||
|
function interfaceToColor(name) {
|
||||||
|
return "khaki"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,7 @@ Page {
|
|||||||
id: favoritesViewComponent
|
id: favoritesViewComponent
|
||||||
FavoritesView {
|
FavoritesView {
|
||||||
id: favoritesView
|
id: favoritesView
|
||||||
|
objectName: "favorites"
|
||||||
width: swipeView.width
|
width: swipeView.width
|
||||||
height: swipeView.height
|
height: swipeView.height
|
||||||
property string title: qsTr("My favorites")
|
property string title: qsTr("My favorites")
|
||||||
@ -201,6 +202,7 @@ Page {
|
|||||||
id: tabEntryComponent
|
id: tabEntryComponent
|
||||||
MainPageTabButton {
|
MainPageTabButton {
|
||||||
property int pageIndex: 0
|
property int pageIndex: 0
|
||||||
|
// height: tabBar.height
|
||||||
onClicked: settings.currentMainViewIndex = pageIndex
|
onClicked: settings.currentMainViewIndex = pageIndex
|
||||||
alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
|
alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ ToolBar {
|
|||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.pixelSize: app.mediumFont
|
font.pixelSize: app.mediumFont
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: root.title.toLowerCase();
|
text: root.title
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderButton {
|
HeaderButton {
|
||||||
|
|||||||
@ -40,7 +40,7 @@ ToolBar {
|
|||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.pixelSize: app.mediumFont
|
font.pixelSize: app.mediumFont
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: root.text.toLowerCase();
|
text: root.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,12 @@ TabButton {
|
|||||||
property string iconSource
|
property string iconSource
|
||||||
property var alignment: Qt.Vertical
|
property var alignment: Qt.Vertical
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Material.foreground
|
||||||
|
opacity: 0.05
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: GridLayout {
|
contentItem: GridLayout {
|
||||||
columns: root.alignment === Qt.Vertical ? 1 : 2
|
columns: root.alignment === Qt.Vertical ? 1 : 2
|
||||||
ColorIcon {
|
ColorIcon {
|
||||||
|
|||||||
108
nymea-app/ui/components/MainPageTile.qml
Normal file
108
nymea-app/ui/components/MainPageTile.qml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtQuick.Controls.Material 2.2
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias iconName: colorIcon.name
|
||||||
|
property alias fallbackIconName: fallbackIcon.name
|
||||||
|
property alias iconColor: colorIcon.color
|
||||||
|
property string text
|
||||||
|
property bool disconnected: false
|
||||||
|
property bool batteryCritical: false
|
||||||
|
|
||||||
|
property alias contentItem: innerContent.children
|
||||||
|
|
||||||
|
signal clicked();
|
||||||
|
signal pressAndHold();
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: app.margins / 2
|
||||||
|
Material.elevation: 1
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
contentItem: ItemDelegate {
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
onClicked: root.clicked()
|
||||||
|
onPressAndHold: root.pressAndHold()
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.margins: app.margins
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
ColorIcon {
|
||||||
|
id: colorIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: app.iconSize * 1.3
|
||||||
|
width: height
|
||||||
|
ColorIcon {
|
||||||
|
id: fallbackIcon
|
||||||
|
anchors.fill: parent
|
||||||
|
color: root.iconColor
|
||||||
|
visible: parent.status === Image.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: label
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
text: root.text.toUpperCase()
|
||||||
|
font.pixelSize: app.smallFont
|
||||||
|
font.letterSpacing: 1
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
maximumLineCount: 2
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: innerContent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: app.iconSize + app.margins * 2
|
||||||
|
visible: root.contentItem.length > 1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Material.foreground
|
||||||
|
opacity: 0.05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: quickAlertPane
|
||||||
|
anchors { top: parent.top; right: parent.right; margins: app.margins }
|
||||||
|
ColorIcon {
|
||||||
|
height: app.iconSize / 2
|
||||||
|
width: height
|
||||||
|
name: "../images/dialog-warning-symbolic.svg"
|
||||||
|
color: "red"
|
||||||
|
visible: root.disconnected
|
||||||
|
}
|
||||||
|
ColorIcon {
|
||||||
|
height: app.iconSize / 2
|
||||||
|
width: height
|
||||||
|
name: "../images/battery/battery-010.svg"
|
||||||
|
visible: root.batteryCritical
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
70
nymea-app/ui/images/configure.svg
Normal file
70
nymea-app/ui/images/configure.svg
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="svg4874"
|
||||||
|
width="96"
|
||||||
|
height="96"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 96 96"
|
||||||
|
sodipodi:docname="configure.svg"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||||
|
<defs
|
||||||
|
id="defs917" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="2880"
|
||||||
|
inkscape:window-height="1698"
|
||||||
|
id="namedview915"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="4.9460646"
|
||||||
|
inkscape:cx="-36.820629"
|
||||||
|
inkscape:cy="67.664461"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="44"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4874">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid922" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata4879">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:none"
|
||||||
|
height="96"
|
||||||
|
width="96"
|
||||||
|
y="-96"
|
||||||
|
x="-2.7465819e-06"
|
||||||
|
transform="rotate(90)"
|
||||||
|
id="rect4782" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#808080;enable-background:new"
|
||||||
|
d="M 53.224853,20.293258 C 49.111288,24.40688 47.784374,30.257807 49.222134,35.5394 L 18.249429,66.512077 c -3.251992,3.252118 -3.363566,8.376104 -0.250528,11.489002 3.113108,3.11311 8.237157,3.0016 11.489141,-0.25039 L 60.46067,46.777936 c 5.281451,1.438184 11.133255,0.111723 15.246495,-4.002366 4.480632,-4.480533 5.647733,-11.037159 3.544302,-16.659153 l -8.249122,8.249094 -9.367678,-9.367823 8.249114,-8.249101 C 64.262353,14.644874 57.705564,15.812236 53.224699,20.29296 Z M 21.436868,70.171864 a 3.1053,3.0703 45 0 1 4.366879,0.02454 3.1053,3.0703 45 0 1 0.02475,4.367092 3.1053,3.0703 45 0 1 -4.367091,-0.02475 3.1053,3.0703 45 0 1 -0.02454,-4.366879 z"
|
||||||
|
id="path4328" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
@ -5,257 +5,134 @@ import QtQuick.Controls.Material 2.2
|
|||||||
import Nymea 1.0
|
import Nymea 1.0
|
||||||
import "../components"
|
import "../components"
|
||||||
|
|
||||||
Item {
|
MainPageTile {
|
||||||
id: root
|
id: root
|
||||||
Pane {
|
text: interfaceToString(model.name).toUpperCase()
|
||||||
anchors.fill: parent
|
iconName: interfaceToIcon(model.name)
|
||||||
anchors.margins: app.margins / 2
|
iconColor: app.guhAccent
|
||||||
Material.elevation: 1
|
disconnected: devicesSubProxyConnectables.count > 0
|
||||||
|
batteryCritical: devicesSubProxyBattery.count > 0
|
||||||
|
|
||||||
Column {
|
onClicked: {
|
||||||
width: parent.width
|
var page;
|
||||||
anchors.centerIn: parent
|
switch (model.name) {
|
||||||
anchors.verticalCenterOffset: -app.iconSize
|
case "light":
|
||||||
spacing: app.margins
|
page = "LightsDeviceListPage.qml"
|
||||||
ColorIcon {
|
break;
|
||||||
height: app.iconSize * 1.3
|
default:
|
||||||
width: height
|
page = "GenericDeviceListPage.qml"
|
||||||
color: app.guhAccent
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
name: interfaceToIcon(model.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: interfaceToString(model.name).toUpperCase()
|
|
||||||
font.pixelSize: app.extraSmallFont
|
|
||||||
font.bold: true
|
|
||||||
font.letterSpacing: 1
|
|
||||||
width: parent.width
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (model.name === "uncategorized") {
|
||||||
MouseArea {
|
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {hiddenInterfaces: app.supportedInterfaces})
|
||||||
anchors.fill: parent
|
} else {
|
||||||
onClicked: {
|
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {shownInterfaces: [model.name]})
|
||||||
var page;
|
|
||||||
switch (model.name) {
|
|
||||||
case "light":
|
|
||||||
page = "LightsDeviceListPage.qml"
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
page = "GenericDeviceListPage.qml"
|
|
||||||
}
|
|
||||||
if (model.name === "uncategorized") {
|
|
||||||
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {hiddenInterfaces: app.supportedInterfaces})
|
|
||||||
} else {
|
|
||||||
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {shownInterfaces: [model.name]})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DevicesProxy {
|
|
||||||
id: devicesProxy
|
|
||||||
devices: Engine.deviceManager.devices
|
|
||||||
shownInterfaces: [model.name]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
DevicesProxy {
|
||||||
id: quickAlertPane
|
id: devicesProxy
|
||||||
anchors { top: parent.top; right: parent.right; margins: app.margins }
|
devices: Engine.deviceManager.devices
|
||||||
DevicesProxy {
|
shownInterfaces: [model.name]
|
||||||
id: devicesSubProxyConnectables
|
|
||||||
devices: devicesProxy
|
|
||||||
filterDisconnected: true
|
|
||||||
}
|
|
||||||
ColorIcon {
|
|
||||||
height: app.iconSize / 2
|
|
||||||
width: height
|
|
||||||
name: "../images/dialog-warning-symbolic.svg"
|
|
||||||
color: "red"
|
|
||||||
visible: devicesSubProxyConnectables.count > 0
|
|
||||||
}
|
|
||||||
DevicesProxy {
|
|
||||||
id: devicesSubProxyBattery
|
|
||||||
devices: devicesProxy
|
|
||||||
filterBatteryCritical: true
|
|
||||||
}
|
|
||||||
ColorIcon {
|
|
||||||
height: app.iconSize / 2
|
|
||||||
width: height
|
|
||||||
name: "../images/battery/battery-010.svg"
|
|
||||||
visible: devicesSubProxyBattery.count > 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DevicesProxy {
|
||||||
|
id: devicesSubProxyConnectables
|
||||||
|
devices: devicesProxy
|
||||||
|
filterDisconnected: true
|
||||||
|
}
|
||||||
|
DevicesProxy {
|
||||||
|
id: devicesSubProxyBattery
|
||||||
|
devices: devicesProxy
|
||||||
|
filterBatteryCritical: true
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
contentItem: Loader {
|
||||||
id: inlineControlPane
|
id: inlineControlLoader
|
||||||
anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: app.margins / 2 }
|
anchors {
|
||||||
height: app.iconSize + app.margins * 2
|
fill: parent
|
||||||
Rectangle {
|
leftMargin: app.margins / 2
|
||||||
anchors.fill: parent
|
rightMargin: app.margins / 2
|
||||||
// color: app.guhAccent
|
|
||||||
color: "black"
|
|
||||||
opacity: .05
|
|
||||||
}
|
}
|
||||||
Loader {
|
sourceComponent: {
|
||||||
id: inlineControlLoader
|
switch (model.name) {
|
||||||
anchors {
|
case "sensor":
|
||||||
fill: parent
|
case "weather":
|
||||||
leftMargin: app.margins
|
return labelComponent;
|
||||||
rightMargin: app.margins
|
|
||||||
topMargin: app.margins / 2
|
|
||||||
bottomMargin: app.margins / 2
|
|
||||||
}
|
|
||||||
sourceComponent: {
|
|
||||||
switch (model.name) {
|
|
||||||
case "sensor":
|
|
||||||
case "weather":
|
|
||||||
return labelComponent;
|
|
||||||
|
|
||||||
case "light":
|
case "light":
|
||||||
case "media":
|
case "media":
|
||||||
case "garagegate":
|
case "garagegate":
|
||||||
case "blind":
|
case "blind":
|
||||||
case "extendedblind":
|
case "extendedblind":
|
||||||
case "shutter":
|
case "shutter":
|
||||||
case "extendedshutter":
|
case "extendedshutter":
|
||||||
case "awning":
|
case "awning":
|
||||||
case "extendedawning":
|
case "extendedawning":
|
||||||
return buttonComponent
|
return buttonComponent
|
||||||
default:
|
default:
|
||||||
console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name)
|
console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: buttonComponent
|
id: buttonComponent
|
||||||
MouseArea {
|
ColumnLayout {
|
||||||
onClicked: {
|
spacing: 0
|
||||||
switch (model.name) {
|
|
||||||
case "light":
|
Label {
|
||||||
if (devicesProxy.count == 1) {
|
id: label
|
||||||
var device = devicesProxy.get(0);
|
Layout.fillWidth: true
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
text: {
|
||||||
var stateType = deviceClass.stateTypes.findByName("power")
|
switch (model.name) {
|
||||||
var actionType = deviceClass.actionTypes.findByName("power")
|
case "media":
|
||||||
var params = [];
|
return devicesProxy.get(0).name;
|
||||||
var param1 = {};
|
case "light":
|
||||||
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
|
var count = 0;
|
||||||
param1["value"] = !device.states.getState(stateType.id).value;
|
|
||||||
params.push(param1)
|
|
||||||
Engine.deviceManager.executeAction(device.id, actionType.id, params)
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < devicesProxy.count; i++) {
|
for (var i = 0; i < devicesProxy.count; i++) {
|
||||||
var device = devicesProxy.get(i);
|
var device = devicesProxy.get(i);
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
var actionType = deviceClass.actionTypes.findByName("power");
|
var stateType = deviceClass.stateTypes.findByName("power")
|
||||||
|
if (device.states.getState(stateType.id).value === true) {
|
||||||
var params = [];
|
count++;
|
||||||
var param1 = {};
|
}
|
||||||
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
|
|
||||||
param1["value"] = false;
|
|
||||||
params.push(param1)
|
|
||||||
Engine.deviceManager.executeAction(device.id, actionType.id, params)
|
|
||||||
}
|
}
|
||||||
|
return count === 0 ? qsTr("All off") : qsTr("%1 on").arg(count)
|
||||||
|
case "garagegate":
|
||||||
|
var count = 0;
|
||||||
|
for (var i = 0; i < devicesProxy.count; i++) {
|
||||||
|
var device = devicesProxy.get(i);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var stateType = deviceClass.stateTypes.findByName("state");
|
||||||
|
if (device.states.getState(stateType.id).value !== "closed") {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count === 0 ? qsTr("All closed") : qsTr("%1 open").arg(count)
|
||||||
|
case "blind":
|
||||||
|
case "extendedblind":
|
||||||
|
case "awning":
|
||||||
|
case "extendedawning":
|
||||||
|
case "shutter":
|
||||||
|
case "extendedshutter":
|
||||||
|
return qsTr("%1 installed").arg(devicesProxy.count)
|
||||||
}
|
}
|
||||||
break;
|
console.warn("DevicesPageDelegate, inlineButtonControl: Unhandled interface", model.name)
|
||||||
case "media":
|
|
||||||
var device = devicesProxy.get(0)
|
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
|
||||||
var stateType = deviceClass.stateTypes.findByName("playbackStatus");
|
|
||||||
var state = device.states.getState(stateType.id)
|
|
||||||
|
|
||||||
var actionName
|
|
||||||
switch (state.value) {
|
|
||||||
case "Playing":
|
|
||||||
actionName = "pause";
|
|
||||||
break;
|
|
||||||
case "Paused":
|
|
||||||
actionName = "play";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var actionTypeId = deviceClass.actionTypes.findByName(actionName).id;
|
|
||||||
|
|
||||||
print("executing", device, device.id, actionTypeId, actionName, deviceClass.actionTypes)
|
|
||||||
|
|
||||||
Engine.deviceManager.executeAction(device.id, actionTypeId)
|
|
||||||
case "garagegate":
|
|
||||||
case "shutter":
|
|
||||||
case "extendedshutter":
|
|
||||||
case "blind":
|
|
||||||
case "extendedblind":
|
|
||||||
case "awning":
|
|
||||||
case "extendedawning":
|
|
||||||
case "simpleclosable":
|
|
||||||
for (var i = 0; i < devicesProxy.count; i++) {
|
|
||||||
var device = devicesProxy.get(i);
|
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
|
||||||
var actionType = deviceClass.actionTypes.findByName("close");
|
|
||||||
Engine.deviceManager.executeAction(device.id, actionType.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.warn("DevicesPageDelegate, inlineButtonControl clicked: Unhandled interface", model.name)
|
|
||||||
}
|
}
|
||||||
|
font.pixelSize: app.smallFont
|
||||||
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredHeight: app.iconSize
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: label
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: {
|
|
||||||
switch (model.name) {
|
|
||||||
case "media":
|
|
||||||
return devicesProxy.get(0).name;
|
|
||||||
case "light":
|
|
||||||
var count = 0;
|
|
||||||
for (var i = 0; i < devicesProxy.count; i++) {
|
|
||||||
var device = devicesProxy.get(i);
|
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
|
||||||
var stateType = deviceClass.stateTypes.findByName("power")
|
|
||||||
if (device.states.getState(stateType.id).value === true) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count === 0 ? qsTr("All off") : qsTr("%1 on").arg(count)
|
|
||||||
case "garagegate":
|
|
||||||
var count = 0;
|
|
||||||
for (var i = 0; i < devicesProxy.count; i++) {
|
|
||||||
var device = devicesProxy.get(i);
|
|
||||||
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
|
||||||
var stateType = deviceClass.stateTypes.findByName("state");
|
|
||||||
if (device.states.getState(stateType.id).value !== "closed") {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count === 0 ? qsTr("All closed") : qsTr("%1 open").arg(count)
|
|
||||||
case "blind":
|
|
||||||
case "extendedblind":
|
|
||||||
case "awning":
|
|
||||||
case "extendedawning":
|
|
||||||
case "shutter":
|
|
||||||
case "extendedshutter":
|
|
||||||
return qsTr("%1 installed").arg(devicesProxy.count)
|
|
||||||
}
|
|
||||||
console.warn("DevicesPageDelegate, inlineButtonControl: Unhandled interface", model.name)
|
|
||||||
}
|
|
||||||
font.pixelSize: app.smallFont
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
ColorIcon {
|
ColorIcon {
|
||||||
id: icon
|
id: icon
|
||||||
width: app.largeFont
|
width: app.iconSize
|
||||||
height: width
|
height: width
|
||||||
color: app.guhAccent
|
color: app.guhAccent
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
name: {
|
name: {
|
||||||
switch (model.name) {
|
switch (model.name) {
|
||||||
case "media":
|
case "media":
|
||||||
@ -281,13 +158,86 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
switch (model.name) {
|
||||||
|
case "light":
|
||||||
|
if (devicesProxy.count == 1) {
|
||||||
|
var device = devicesProxy.get(0);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var stateType = deviceClass.stateTypes.findByName("power")
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("power")
|
||||||
|
var params = [];
|
||||||
|
var param1 = {};
|
||||||
|
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||||
|
param1["value"] = !device.states.getState(stateType.id).value;
|
||||||
|
params.push(param1)
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id, params)
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < devicesProxy.count; i++) {
|
||||||
|
var device = devicesProxy.get(i);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("power");
|
||||||
|
|
||||||
|
var params = [];
|
||||||
|
var param1 = {};
|
||||||
|
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||||
|
param1["value"] = false;
|
||||||
|
params.push(param1)
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "media":
|
||||||
|
var device = devicesProxy.get(0)
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var stateType = deviceClass.stateTypes.findByName("playbackStatus");
|
||||||
|
var state = device.states.getState(stateType.id)
|
||||||
|
|
||||||
|
var actionName
|
||||||
|
switch (state.value) {
|
||||||
|
case "Playing":
|
||||||
|
actionName = "pause";
|
||||||
|
break;
|
||||||
|
case "Paused":
|
||||||
|
actionName = "play";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var actionTypeId = deviceClass.actionTypes.findByName(actionName).id;
|
||||||
|
|
||||||
|
print("executing", device, device.id, actionTypeId, actionName, deviceClass.actionTypes)
|
||||||
|
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionTypeId)
|
||||||
|
case "garagegate":
|
||||||
|
case "shutter":
|
||||||
|
case "extendedshutter":
|
||||||
|
case "blind":
|
||||||
|
case "extendedblind":
|
||||||
|
case "awning":
|
||||||
|
case "extendedawning":
|
||||||
|
case "simpleclosable":
|
||||||
|
for (var i = 0; i < devicesProxy.count; i++) {
|
||||||
|
var device = devicesProxy.get(i);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("close");
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn("DevicesPageDelegate, inlineButtonControl clicked: Unhandled interface", model.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: labelComponent
|
id: labelComponent
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
property var device: devicesProxy.get(0)
|
property var device: devicesProxy.get(0)
|
||||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||||
property var state: deviceClass ? device.states.getState(deviceClass.stateTypes.findByName("temperature").id) : null
|
property var state: deviceClass ? device.states.getState(deviceClass.stateTypes.findByName("temperature").id) : null
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import "../components"
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool editMode: false
|
||||||
readonly property int count: tagsProxy.count
|
readonly property int count: tagsProxy.count
|
||||||
|
|
||||||
TagsProxyModel {
|
TagsProxyModel {
|
||||||
@ -22,48 +23,123 @@ Item {
|
|||||||
readonly property int minTileWidth: 180
|
readonly property int minTileWidth: 180
|
||||||
readonly property int minTileHeight: 240
|
readonly property int minTileHeight: 240
|
||||||
readonly property int tilesPerRow: root.width / minTileWidth
|
readonly property int tilesPerRow: root.width / minTileWidth
|
||||||
|
|
||||||
cellWidth: gridView.width / tilesPerRow
|
cellWidth: gridView.width / tilesPerRow
|
||||||
cellHeight: cellWidth
|
cellHeight: cellWidth
|
||||||
|
|
||||||
model: tagsProxy
|
model: tagsProxy
|
||||||
delegate: favoritesDelegateComponent
|
delegate: MainPageTile {
|
||||||
|
id: delegateRoot
|
||||||
|
width: gridView.cellWidth
|
||||||
|
height: gridView.cellHeight
|
||||||
|
text: device.name.toUpperCase()
|
||||||
|
iconName: app.interfacesToIcon(deviceClass.interfaces)
|
||||||
|
iconColor: app.guhAccent
|
||||||
|
visible: !fakeDragItem.visible || fakeDragItem.deviceId !== device.id
|
||||||
|
batteryCritical: batteryCriticalState && batteryCriticalState.value === true
|
||||||
|
disconnected: connectedState && connectedState.value === false
|
||||||
|
|
||||||
|
property var modelIndex: index
|
||||||
|
|
||||||
|
property string deviceId: model.deviceId
|
||||||
|
property string ruleId: model.ruleId
|
||||||
|
readonly property var device: Engine.deviceManager.devices.getDevice(deviceId)
|
||||||
|
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||||
|
readonly property var connectedState: deviceClass.interfaces.indexOf("connectable") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("connected").id) : null
|
||||||
|
readonly property var batteryCriticalState: deviceClass.interfaces.indexOf("battery") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("batteryCritical").id) : null
|
||||||
|
|
||||||
|
onClicked: pageStack.push(Qt.resolvedUrl("../devicepages/" + app.interfaceListToDevicePage(deviceClass.interfaces)), {device: device})
|
||||||
|
|
||||||
|
onPressAndHold: root.editMode = true
|
||||||
|
|
||||||
|
contentItem: Loader {
|
||||||
|
id: loader
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: {
|
||||||
|
if (delegateRoot.deviceClass.interfaces.indexOf("closable") >= 0) {
|
||||||
|
return closableComponent;
|
||||||
|
}
|
||||||
|
if (delegateRoot.deviceClass.interfaces.indexOf("light") >= 0) {
|
||||||
|
return lightsComponent;
|
||||||
|
}
|
||||||
|
if (delegateRoot.deviceClass.interfaces.indexOf("sensor") >= 0) {
|
||||||
|
return sensorsComponent;
|
||||||
|
}
|
||||||
|
if (delegateRoot.deviceClass.interfaces.indexOf("weather") >= 0) {
|
||||||
|
return sensorsComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Binding { target: loader.item ? loader.item : null; property: "deviceClass"; value: delegateRoot.deviceClass }
|
||||||
|
Binding { target: loader.item ? loader.item : null; property: "device"; value: delegateRoot.device }
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
loops: Animation.Infinite
|
||||||
|
running: root.editMode
|
||||||
|
alwaysRunToEnd: true
|
||||||
|
NumberAnimation { from: 0; to: 3; target: delegateRoot; duration: 75; property: "rotation" }
|
||||||
|
NumberAnimation { from: 3; to: -3; target: delegateRoot; duration: 150; property: "rotation" }
|
||||||
|
NumberAnimation { from: -3; to: 0; target: delegateRoot; duration: 75; property: "rotation" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: dndArea
|
id: dragArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
enabled: root.editMode
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
|
property var dragOffset: ({})
|
||||||
|
property var draggedItem: null
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
var item = gridView.itemAt(mouseX, mouseY)
|
||||||
|
draggedItem = item;
|
||||||
|
dragOffset = mapToItem(item, mouseX, mouseY)
|
||||||
|
fakeDragItem.x = mouseX - dragOffset.x;
|
||||||
|
fakeDragItem.y = mouseY - dragOffset.y;
|
||||||
|
fakeDragItem.text = item.text
|
||||||
|
fakeDragItem.iconName = item.iconName
|
||||||
|
fakeDragItem.iconColor = item.iconColor;
|
||||||
|
fakeDragItem.deviceId = item.device.id
|
||||||
|
fakeDragItem.batteryCritical = item.batteryCritical
|
||||||
|
fakeDragItem.disconnected = item.disconnected
|
||||||
|
drag.target = fakeDragItem
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
drag.target = null
|
||||||
|
draggedItem = null
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.editMode = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainPageTile {
|
||||||
|
id: fakeDragItem
|
||||||
|
width: gridView.cellWidth
|
||||||
|
height: gridView.cellHeight
|
||||||
|
Drag.active: dragArea.drag.active
|
||||||
|
visible: Drag.active
|
||||||
|
property var deviceId
|
||||||
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
id: dropArea
|
||||||
|
anchors.fill: gridView
|
||||||
|
|
||||||
property int from: -1
|
property int from: -1
|
||||||
property int to: -1
|
property int to: -1
|
||||||
property int index: gridView.indexAt(mouseX, mouseY) // Item underneath cursor
|
|
||||||
property var dndDelegate: null
|
|
||||||
|
|
||||||
property int dx
|
onEntered: {
|
||||||
property int dy
|
var index = gridView.indexAt(drag.x + dragArea.dragOffset.x, drag.y + dragArea.dragOffset.y);
|
||||||
|
|
||||||
onPressAndHold: {
|
|
||||||
//currentId = icons.get(newIndex = index).gridId
|
|
||||||
preventStealing = true;
|
|
||||||
from = index;
|
from = index;
|
||||||
print("pressandHold on", index)
|
to = index;
|
||||||
var tag = tagsProxy.get(index);
|
|
||||||
var originalDelegate = gridView.itemAt(mouseX, mouseY)
|
|
||||||
dndDelegate = favoritesDelegateComponent.createObject(dndArea, {deviceId: tag.deviceId, ruleId: tag.ruleId, x: originalDelegate.x, y: originalDelegate.y})
|
|
||||||
dx = mouseX - originalDelegate.x;
|
|
||||||
dy = mouseY - originalDelegate.y;
|
|
||||||
}
|
|
||||||
onReleased: {
|
|
||||||
preventStealing = false;
|
|
||||||
from = -1;
|
|
||||||
dndDelegate.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
if (dndDelegate) {
|
var index = gridView.indexAt(drag.x + dragArea.dragOffset.x, drag.y + dragArea.dragOffset.y);
|
||||||
dndDelegate.x = mouseX - dx
|
if (to !== index && from !== index && index >= 0 && index <= tagsProxy.count) {
|
||||||
dndDelegate.y = mouseY - dy
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dndArea.from >= 0 && to != index && from != index) {
|
|
||||||
to = index;
|
to = index;
|
||||||
print("should move", from, "to", to)
|
print("should move", from, "to", to)
|
||||||
for (var i = 0; i < tagsProxy.count; i++) {
|
for (var i = 0; i < tagsProxy.count; i++) {
|
||||||
@ -88,80 +164,248 @@ Item {
|
|||||||
}
|
}
|
||||||
from = index;
|
from = index;
|
||||||
}
|
}
|
||||||
// tagsProxy.move(newIndex, newIndex = index, 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: favoritesDelegateComponent
|
id: lightsComponent
|
||||||
Item {
|
RowLayout {
|
||||||
id: delegateRoot
|
property var device: null
|
||||||
property string deviceId: model.deviceId
|
property var deviceClass: null
|
||||||
property string ruleId: model.ruleId
|
|
||||||
readonly property var device: Engine.deviceManager.devices.getDevice(deviceId)
|
|
||||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
|
||||||
|
|
||||||
visible: index !== undefined && index !== dndArea.from
|
ItemDelegate {
|
||||||
width: gridView.cellWidth
|
Layout.preferredWidth: app.iconSize
|
||||||
height: gridView.cellHeight
|
Layout.preferredHeight: app.iconSize
|
||||||
|
Layout.leftMargin: app.margins / 2
|
||||||
Pane {
|
Layout.alignment: Qt.AlignVCenter
|
||||||
id: pane
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
anchors.fill: parent
|
contentItem: ColorIcon {
|
||||||
anchors.margins: app.margins / 2
|
name: "../images/light-off.svg"
|
||||||
Material.elevation: 1
|
color: app.guhAccent
|
||||||
ColumnLayout {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width - app.margins * 2
|
|
||||||
spacing: app.margins
|
|
||||||
|
|
||||||
ColorIcon {
|
|
||||||
Layout.preferredWidth: app.iconSize * 1.3
|
|
||||||
Layout.preferredHeight: width
|
|
||||||
name: app.interfacesToIcon(delegateRoot.deviceClass.interfaces)
|
|
||||||
color: app.guhAccent
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: delegateRoot.device.name.toUpperCase()
|
|
||||||
font.pixelSize: app.extraSmallFont
|
|
||||||
font.bold: true
|
|
||||||
font.letterSpacing: 1
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: quickAlertPane
|
|
||||||
anchors { top: parent.top; right: parent.right; margins: app.margins }
|
|
||||||
ColorIcon {
|
|
||||||
height: app.iconSize / 2
|
|
||||||
width: height
|
|
||||||
name: "../images/dialog-warning-symbolic.svg"
|
|
||||||
color: "red"
|
|
||||||
property var connectedState: delegateRoot.deviceClass.interfaces.indexOf("connectable") >= 0 ? delegateRoot.device.states.getState(delegateRoot.deviceClass.stateTypes.findByName("connected").id) : null
|
|
||||||
visible: connectedState !== null && connectedState.value === false
|
|
||||||
}
|
|
||||||
ColorIcon {
|
|
||||||
height: app.iconSize / 2
|
|
||||||
width: height
|
|
||||||
name: "../images/battery/battery-010.svg"
|
|
||||||
property var batteryCriticalState: delegateRoot.deviceClass.interfaces.indexOf("battery") >= 0 ? delegateRoot.device.states.getState(delegateRoot.deviceClass.stateTypes.findByName("batteryCritical").id) : null
|
|
||||||
visible: batteryCriticalState !== null && batteryCriticalState.value === true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("../devicepages/" + app.interfaceListToDevicePage(delegateRoot.deviceClass.interfaces)), {device: delegateRoot.device})
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("power");
|
||||||
|
var params = [];
|
||||||
|
var powerParam = {}
|
||||||
|
powerParam["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||||
|
powerParam["value"] = false;
|
||||||
|
params.push(powerParam)
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThrottledSlider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
visible: deviceClass.interfaces.indexOf("dimmablelight") >= 0
|
||||||
|
readonly property var brightnessStateType: deviceClass.stateTypes.findByName("brightness");
|
||||||
|
readonly property var brightnessState: device.states.getState(brightnessStateType.id)
|
||||||
|
from: 0
|
||||||
|
to: 100
|
||||||
|
value: brightnessState.value
|
||||||
|
onMoved: {
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("brightness");
|
||||||
|
var params = [];
|
||||||
|
var powerParam = {}
|
||||||
|
powerParam["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||||
|
powerParam["value"] = value;
|
||||||
|
params.push(powerParam)
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.rightMargin: app.margins / 2
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
name: "../images/light-on.svg"
|
||||||
|
color: app.guhAccent
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("power");
|
||||||
|
var params = [];
|
||||||
|
var powerParam = {}
|
||||||
|
powerParam["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||||
|
powerParam["value"] = true;
|
||||||
|
params.push(powerParam)
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: sensorsComponent
|
||||||
|
RowLayout {
|
||||||
|
id: sensorsRoot
|
||||||
|
property var device: null
|
||||||
|
property var deviceClass: null
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
property var shownInterfaces: []
|
||||||
|
property int currentStateIndex: -1
|
||||||
|
property var currentStateType: deviceClass ? deviceClass.stateTypes.findByName(shownInterfaces[currentStateIndex].state) : null
|
||||||
|
property var currentState: currentStateType ? device.states.getState(currentStateType.id) : null
|
||||||
|
|
||||||
|
onDeviceClassChanged: {
|
||||||
|
if (deviceClass == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = []
|
||||||
|
if (deviceClass.interfaces.indexOf("temperaturesensor") >= 0) {
|
||||||
|
tmp.push({iface: "temperaturesensor", state: "temperature"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("humiditysensor") >= 0) {
|
||||||
|
tmp.push({iface: "humiditysensor", state: "humidity"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("moisturesensor") >= 0) {
|
||||||
|
tmp.push({iface: "moisturesensor", state: "moisture"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("pressuresensor") >= 0) {
|
||||||
|
tmp.push({iface: "pressuresensor", state: "pressure"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("lightsensor") >= 0) {
|
||||||
|
tmp.push({iface: "lightsensor", state: "lightIntensity"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("conductivitysensor") >= 0) {
|
||||||
|
tmp.push({iface: "conductivitysensor", state: "conductivity"});
|
||||||
|
}
|
||||||
|
if (deviceClass.interfaces.indexOf("weather") >= 0) {
|
||||||
|
tmp.push({iface: "temperaturesensor", state: "temperature"});
|
||||||
|
tmp.push({iface: "humiditysensor", state: "humidity"});
|
||||||
|
tmp.push({iface: "pressuresensor", state: "pressure"});
|
||||||
|
}
|
||||||
|
|
||||||
|
shownInterfaces = tmp
|
||||||
|
currentStateIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.leftMargin: app.margins / 2
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
visible: sensorsRoot.shownInterfaces.length > 1
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
name: "../images/back.svg"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var newIndex = sensorsRoot.currentStateIndex - 1;
|
||||||
|
if (newIndex < 0) newIndex = sensorsRoot.shownInterfaces.length - 1
|
||||||
|
sensorsRoot.currentStateIndex = newIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorIcon {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
color: app.interfaceToColor(sensorsRoot.shownInterfaces[sensorsRoot.currentStateIndex].iface)
|
||||||
|
name: app.interfaceToIcon(sensorsRoot.shownInterfaces[sensorsRoot.currentStateIndex].iface)
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
text: sensorsRoot.currentStateType.unitString
|
||||||
|
font.pixelSize: app.smallFont
|
||||||
|
color: app.guhAccent
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
text: sensorsRoot.currentState.value// + " " + sensorsRoot.currentStateType.unitString
|
||||||
|
color: app.guhAccent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.rightMargin: app.margins / 2
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
visible: sensorsRoot.shownInterfaces.length > 1
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
name: "../images/next.svg"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var newIndex = sensorsRoot.currentStateIndex + 1;
|
||||||
|
if (newIndex >= sensorsRoot.shownInterfaces.length) newIndex = 0;
|
||||||
|
sensorsRoot.currentStateIndex = newIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: closableComponent
|
||||||
|
RowLayout {
|
||||||
|
property var device: null
|
||||||
|
property var deviceClass: null
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.leftMargin: app.margins / 2
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
name: "../images/up.svg"
|
||||||
|
color: app.guhAccent
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("open");
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: closableSlider
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
visible: deviceClass.interfaces.indexOf("extendedclosable") >= 0
|
||||||
|
readonly property var percentageStateType: deviceClass.stateTypes.findByName("percentage");
|
||||||
|
readonly property var percentateState: device.states.getState(percentageStateType.id)
|
||||||
|
from: 0
|
||||||
|
to: 100
|
||||||
|
value: percentateState.value
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
visible: !closableSlider.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Layout.rightMargin: app.margins / 2
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
padding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
contentItem: ColorIcon {
|
||||||
|
name: "../images/down.svg"
|
||||||
|
color: app.guhAccent
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var actionType = deviceClass.actionTypes.findByName("close");
|
||||||
|
Engine.deviceManager.executeAction(device.id, actionType.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,20 @@ Item {
|
|||||||
}
|
}
|
||||||
cellWidth: width / tilesPerRow
|
cellWidth: width / tilesPerRow
|
||||||
cellHeight: cellWidth
|
cellHeight: cellWidth
|
||||||
delegate: Item {
|
|
||||||
id: scenesDelegate
|
delegate: MainPageTile {
|
||||||
width: interfacesGridView.cellWidth
|
width: interfacesGridView.cellWidth
|
||||||
height: interfacesGridView.cellHeight
|
height: interfacesGridView.cellHeight
|
||||||
|
iconName: iconTag ? "../images/" + iconTag.value + ".svg" : "../images/slideshow.svg";
|
||||||
|
fallbackIconName: "../images/slideshow.svg"
|
||||||
|
iconColor: colorTag ? colorTag.value : app.guhAccent;
|
||||||
|
text: model.name.toUpperCase()
|
||||||
|
|
||||||
property var colorTag: Engine.tagsManager.tags.findRuleTag(model.id, "color")
|
property var colorTag: Engine.tagsManager.tags.findRuleTag(model.id, "color")
|
||||||
property var iconTag: Engine.tagsManager.tags.findRuleTag(model.id, "icon")
|
property var iconTag: Engine.tagsManager.tags.findRuleTag(model.id, "icon")
|
||||||
|
|
||||||
|
onClicked: Engine.ruleManager.executeActions(model.id)
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Engine.tagsManager.tags
|
target: Engine.tagsManager.tags
|
||||||
onCountChanged: {
|
onCountChanged: {
|
||||||
@ -39,51 +46,6 @@ Item {
|
|||||||
iconTag = Engine.tagsManager.tags.findRuleTag(model.id, "icon")
|
iconTag = Engine.tagsManager.tags.findRuleTag(model.id, "icon")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pane {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: app.margins / 2
|
|
||||||
Material.elevation: 1
|
|
||||||
padding: 0
|
|
||||||
ItemDelegate {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
Engine.ruleManager.executeActions(model.id)
|
|
||||||
}
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: app.margins
|
|
||||||
|
|
||||||
ColorIcon {
|
|
||||||
Layout.preferredHeight: app.iconSize * 1.3
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
name: scenesDelegate.iconTag ? "../images/" + scenesDelegate.iconTag.value + ".svg" : "../images/slideshow.svg";
|
|
||||||
color: scenesDelegate.colorTag ? scenesDelegate.colorTag.value : app.guhAccent;
|
|
||||||
|
|
||||||
ColorIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
name: "../images/slideshow.svg"
|
|
||||||
color: app.guhAccent
|
|
||||||
visible: parent.status === Image.Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: model.name.toUpperCase()
|
|
||||||
font.pixelSize: app.extraSmallFont
|
|
||||||
font.bold: true
|
|
||||||
font.letterSpacing: 1
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
maximumLineCount: 2
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user