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/pressure.svg</file>
|
||||
<file>ui/images/sensors/temperature.svg</file>
|
||||
<file>ui/components/MainPageTile.qml</file>
|
||||
<file>ui/images/configure.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -10,4 +10,9 @@ ApplicationWindow {
|
||||
Material.theme: Material.Dark
|
||||
Material.accent: guhAccent
|
||||
Material.primary: Material.background
|
||||
|
||||
function interfaceToColor(name) {
|
||||
return "khaki"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ Page {
|
||||
id: favoritesViewComponent
|
||||
FavoritesView {
|
||||
id: favoritesView
|
||||
objectName: "favorites"
|
||||
width: swipeView.width
|
||||
height: swipeView.height
|
||||
property string title: qsTr("My favorites")
|
||||
@ -201,6 +202,7 @@ Page {
|
||||
id: tabEntryComponent
|
||||
MainPageTabButton {
|
||||
property int pageIndex: 0
|
||||
// height: tabBar.height
|
||||
onClicked: settings.currentMainViewIndex = pageIndex
|
||||
alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ ToolBar {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.mediumFont
|
||||
elide: Text.ElideRight
|
||||
text: root.title.toLowerCase();
|
||||
text: root.title
|
||||
}
|
||||
|
||||
HeaderButton {
|
||||
|
||||
@ -40,7 +40,7 @@ ToolBar {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.mediumFont
|
||||
elide: Text.ElideRight
|
||||
text: root.text.toLowerCase();
|
||||
text: root.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,12 @@ TabButton {
|
||||
property string iconSource
|
||||
property var alignment: Qt.Vertical
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Material.foreground
|
||||
opacity: 0.05
|
||||
}
|
||||
|
||||
contentItem: GridLayout {
|
||||
columns: root.alignment === Qt.Vertical ? 1 : 2
|
||||
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 "../components"
|
||||
|
||||
Item {
|
||||
MainPageTile {
|
||||
id: root
|
||||
Pane {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins / 2
|
||||
Material.elevation: 1
|
||||
text: interfaceToString(model.name).toUpperCase()
|
||||
iconName: interfaceToIcon(model.name)
|
||||
iconColor: app.guhAccent
|
||||
disconnected: devicesSubProxyConnectables.count > 0
|
||||
batteryCritical: devicesSubProxyBattery.count > 0
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -app.iconSize
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
height: app.iconSize * 1.3
|
||||
width: height
|
||||
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
|
||||
}
|
||||
onClicked: {
|
||||
var page;
|
||||
switch (model.name) {
|
||||
case "light":
|
||||
page = "LightsDeviceListPage.qml"
|
||||
break;
|
||||
default:
|
||||
page = "GenericDeviceListPage.qml"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
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]
|
||||
if (model.name === "uncategorized") {
|
||||
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {hiddenInterfaces: app.supportedInterfaces})
|
||||
} else {
|
||||
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {shownInterfaces: [model.name]})
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: quickAlertPane
|
||||
anchors { top: parent.top; right: parent.right; margins: app.margins }
|
||||
DevicesProxy {
|
||||
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: devicesProxy
|
||||
devices: Engine.deviceManager.devices
|
||||
shownInterfaces: [model.name]
|
||||
}
|
||||
|
||||
DevicesProxy {
|
||||
id: devicesSubProxyConnectables
|
||||
devices: devicesProxy
|
||||
filterDisconnected: true
|
||||
}
|
||||
DevicesProxy {
|
||||
id: devicesSubProxyBattery
|
||||
devices: devicesProxy
|
||||
filterBatteryCritical: true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: inlineControlPane
|
||||
anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: app.margins / 2 }
|
||||
height: app.iconSize + app.margins * 2
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
// color: app.guhAccent
|
||||
color: "black"
|
||||
opacity: .05
|
||||
contentItem: Loader {
|
||||
id: inlineControlLoader
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: app.margins / 2
|
||||
rightMargin: app.margins / 2
|
||||
}
|
||||
Loader {
|
||||
id: inlineControlLoader
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: app.margins
|
||||
rightMargin: app.margins
|
||||
topMargin: app.margins / 2
|
||||
bottomMargin: app.margins / 2
|
||||
}
|
||||
sourceComponent: {
|
||||
switch (model.name) {
|
||||
case "sensor":
|
||||
case "weather":
|
||||
return labelComponent;
|
||||
sourceComponent: {
|
||||
switch (model.name) {
|
||||
case "sensor":
|
||||
case "weather":
|
||||
return labelComponent;
|
||||
|
||||
case "light":
|
||||
case "media":
|
||||
case "garagegate":
|
||||
case "blind":
|
||||
case "extendedblind":
|
||||
case "shutter":
|
||||
case "extendedshutter":
|
||||
case "awning":
|
||||
case "extendedawning":
|
||||
return buttonComponent
|
||||
default:
|
||||
console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name)
|
||||
}
|
||||
case "light":
|
||||
case "media":
|
||||
case "garagegate":
|
||||
case "blind":
|
||||
case "extendedblind":
|
||||
case "shutter":
|
||||
case "extendedshutter":
|
||||
case "awning":
|
||||
case "extendedawning":
|
||||
return buttonComponent
|
||||
default:
|
||||
console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: buttonComponent
|
||||
MouseArea {
|
||||
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 {
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
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 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)
|
||||
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)
|
||||
}
|
||||
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)
|
||||
console.warn("DevicesPageDelegate, inlineButtonControl: 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 {
|
||||
id: icon
|
||||
width: app.largeFont
|
||||
width: app.iconSize
|
||||
height: width
|
||||
color: app.guhAccent
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
name: {
|
||||
switch (model.name) {
|
||||
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 {
|
||||
id: labelComponent
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
property var device: devicesProxy.get(0)
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
property var state: deviceClass ? device.states.getState(deviceClass.stateTypes.findByName("temperature").id) : null
|
||||
|
||||
@ -8,6 +8,7 @@ import "../components"
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property bool editMode: false
|
||||
readonly property int count: tagsProxy.count
|
||||
|
||||
TagsProxyModel {
|
||||
@ -22,48 +23,123 @@ Item {
|
||||
readonly property int minTileWidth: 180
|
||||
readonly property int minTileHeight: 240
|
||||
readonly property int tilesPerRow: root.width / minTileWidth
|
||||
|
||||
cellWidth: gridView.width / tilesPerRow
|
||||
cellHeight: cellWidth
|
||||
|
||||
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 {
|
||||
id: dndArea
|
||||
id: dragArea
|
||||
anchors.fill: parent
|
||||
enabled: root.editMode
|
||||
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 to: -1
|
||||
property int index: gridView.indexAt(mouseX, mouseY) // Item underneath cursor
|
||||
property var dndDelegate: null
|
||||
|
||||
property int dx
|
||||
property int dy
|
||||
|
||||
onPressAndHold: {
|
||||
//currentId = icons.get(newIndex = index).gridId
|
||||
preventStealing = true;
|
||||
onEntered: {
|
||||
var index = gridView.indexAt(drag.x + dragArea.dragOffset.x, drag.y + dragArea.dragOffset.y);
|
||||
from = index;
|
||||
print("pressandHold on", 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();
|
||||
to = index;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (dndDelegate) {
|
||||
dndDelegate.x = mouseX - dx
|
||||
dndDelegate.y = mouseY - dy
|
||||
}
|
||||
|
||||
if (dndArea.from >= 0 && to != index && from != index) {
|
||||
var index = gridView.indexAt(drag.x + dragArea.dragOffset.x, drag.y + dragArea.dragOffset.y);
|
||||
if (to !== index && from !== index && index >= 0 && index <= tagsProxy.count) {
|
||||
to = index;
|
||||
print("should move", from, "to", to)
|
||||
for (var i = 0; i < tagsProxy.count; i++) {
|
||||
@ -88,80 +164,248 @@ Item {
|
||||
}
|
||||
from = index;
|
||||
}
|
||||
// tagsProxy.move(newIndex, newIndex = index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Component {
|
||||
id: favoritesDelegateComponent
|
||||
Item {
|
||||
id: delegateRoot
|
||||
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
|
||||
id: lightsComponent
|
||||
RowLayout {
|
||||
property var device: null
|
||||
property var deviceClass: null
|
||||
|
||||
visible: index !== undefined && index !== dndArea.from
|
||||
width: gridView.cellWidth
|
||||
height: gridView.cellHeight
|
||||
|
||||
Pane {
|
||||
id: pane
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins / 2
|
||||
Material.elevation: 1
|
||||
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
|
||||
}
|
||||
ItemDelegate {
|
||||
Layout.preferredWidth: app.iconSize
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.leftMargin: app.margins / 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
padding: 0; topPadding: 0; bottomPadding: 0
|
||||
contentItem: ColorIcon {
|
||||
name: "../images/light-off.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
}
|
||||
|
||||
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: {
|
||||
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
|
||||
cellHeight: cellWidth
|
||||
delegate: Item {
|
||||
id: scenesDelegate
|
||||
|
||||
delegate: MainPageTile {
|
||||
width: interfacesGridView.cellWidth
|
||||
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 iconTag: Engine.tagsManager.tags.findRuleTag(model.id, "icon")
|
||||
|
||||
onClicked: Engine.ruleManager.executeActions(model.id)
|
||||
|
||||
Connections {
|
||||
target: Engine.tagsManager.tags
|
||||
onCountChanged: {
|
||||
@ -39,51 +46,6 @@ Item {
|
||||
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