improve groups view
This commit is contained in:
parent
37397e2c65
commit
14c7a3de1e
@ -137,6 +137,7 @@ void Engine::onConnectedChanged()
|
||||
qDebug() << "Engine: connected changed:" << m_jsonRpcClient->connected();
|
||||
m_deviceManager->clear();
|
||||
m_ruleManager->clear();
|
||||
m_tagsManager->clear();
|
||||
if (m_jsonRpcClient->connected()) {
|
||||
qDebug() << "Engine: inital setup required:" << m_jsonRpcClient->initialSetupRequired() << "auth required:" << m_jsonRpcClient->authenticationRequired();
|
||||
if (!m_jsonRpcClient->initialSetupRequired() && !m_jsonRpcClient->authenticationRequired()) {
|
||||
|
||||
@ -23,6 +23,11 @@ void TagsManager::init()
|
||||
m_jsonClient->sendCommand("Tags.GetTags", this, "getTagsReply");
|
||||
}
|
||||
|
||||
void TagsManager::clear()
|
||||
{
|
||||
m_tags->clear();
|
||||
}
|
||||
|
||||
bool TagsManager::busy() const
|
||||
{
|
||||
return m_busy;
|
||||
@ -123,7 +128,6 @@ void TagsManager::getTagsReply(const QVariantMap ¶ms)
|
||||
{
|
||||
QList<Tag*> tags;
|
||||
foreach (const QVariant &tagVariant, params.value("params").toMap().value("tags").toList()) {
|
||||
qDebug() << "aDDING TAG";
|
||||
Tag *tag = unpackTag(tagVariant.toMap());
|
||||
if (tag) {
|
||||
tags.append(tag);
|
||||
|
||||
@ -17,6 +17,7 @@ public:
|
||||
QString nameSpace() const override;
|
||||
|
||||
void init();
|
||||
void clear();
|
||||
bool busy() const;
|
||||
|
||||
Tags* tags() const;
|
||||
|
||||
@ -120,6 +120,13 @@ Interfaces::Interfaces(QObject *parent) : QAbstractListModel(parent)
|
||||
tr("Playback status"),
|
||||
tr("Playback status changed"),
|
||||
tr("Set playback status"));
|
||||
|
||||
addInterface("mediacontroller", tr("Media controllers"));
|
||||
addActionType("mediacontroller", "play", tr("Start playback"), new ParamTypes());
|
||||
addActionType("mediacontroller", "stop", tr("Stop playback"), new ParamTypes());
|
||||
addActionType("mediacontroller", "pause", tr("Pause playback"), new ParamTypes());
|
||||
addActionType("mediacontroller", "skipBack", tr("Skip back"), new ParamTypes());
|
||||
addActionType("mediacontroller", "skipNext", tr("Skip next"), new ParamTypes());
|
||||
}
|
||||
|
||||
int Interfaces::rowCount(const QModelIndex &parent) const
|
||||
@ -149,6 +156,9 @@ QHash<int, QByteArray> Interfaces::roleNames() const
|
||||
|
||||
Interface *Interfaces::get(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_list.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_list.at(index);
|
||||
}
|
||||
|
||||
|
||||
@ -199,5 +199,6 @@
|
||||
<file>ui/magic/NewScenePage.qml</file>
|
||||
<file>ui/mainviews/GroupsView.qml</file>
|
||||
<file>ui/grouping/GroupPage.qml</file>
|
||||
<file>ui/delegates/ThingTile.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -299,7 +299,7 @@ Page {
|
||||
|
||||
GroupsView {
|
||||
id: groupsView
|
||||
property string title: qsTr("My groups" + count);
|
||||
property string title: qsTr("My groups");
|
||||
width: swipeView.width
|
||||
height: swipeView.height
|
||||
}
|
||||
|
||||
376
nymea-app/ui/delegates/ThingTile.qml
Normal file
376
nymea-app/ui/delegates/ThingTile.qml
Normal file
@ -0,0 +1,376 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
|
||||
MainPageTile {
|
||||
id: root
|
||||
text: device.name.toUpperCase()
|
||||
iconName: app.interfacesToIcon(deviceClass.interfaces)
|
||||
iconColor: app.accentColor
|
||||
batteryCritical: batteryCriticalState && batteryCriticalState.value === true
|
||||
disconnected: connectedState && connectedState.value === false
|
||||
|
||||
backgroundImage: artworkState && artworkState.value.length > 0 ? artworkState.value : ""
|
||||
|
||||
property Device device: null
|
||||
readonly property DeviceClass deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property State connectedState: deviceClass.interfaces.indexOf("connectable") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("connected").id) : null
|
||||
readonly property State batteryCriticalState: deviceClass.interfaces.indexOf("battery") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("batteryCritical").id) : null
|
||||
readonly property State artworkState: deviceClass.interfaces.indexOf("mediametadataprovider") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("artwork").id) : null
|
||||
|
||||
contentItem: Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if (root.deviceClass.interfaces.indexOf("closable") >= 0) {
|
||||
return closableComponent;
|
||||
}
|
||||
if (root.deviceClass.interfaces.indexOf("power") >= 0) {
|
||||
return lightsComponent;
|
||||
}
|
||||
if (root.deviceClass.interfaces.indexOf("sensor") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (root.deviceClass.interfaces.indexOf("weather") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (root.deviceClass.interfaces.indexOf("smartmeter") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (root.deviceClass.interfaces.indexOf("mediacontroller") >= 0) {
|
||||
return mediaComponent;
|
||||
}
|
||||
}
|
||||
Binding { target: loader.item ? loader.item : null; property: "deviceClass"; value: root.deviceClass }
|
||||
Binding { target: loader.item ? loader.item : null; property: "device"; value: root.device }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: lightsComponent
|
||||
RowLayout {
|
||||
property var device: null
|
||||
property var deviceClass: null
|
||||
|
||||
readonly property var powerStateType: deviceClass.stateTypes.findByName("power");
|
||||
readonly property var powerState: device.states.getState(powerStateType.id)
|
||||
|
||||
readonly property var brightnessStateType: deviceClass.stateTypes.findByName("brightness");
|
||||
readonly property var brightnessState: brightnessStateType ? device.states.getState(brightnessStateType.id) : null
|
||||
|
||||
ThrottledSlider {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins / 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
opacity: deviceClass.interfaces.indexOf("dimmablelight") >= 0 ? 1 : 0
|
||||
enabled: opacity > 0
|
||||
from: 0
|
||||
to: 100
|
||||
value: brightnessState ? brightnessState.value : 0
|
||||
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: deviceClass.interfaces.indexOf("light") >= 0
|
||||
? (powerState.value === true ? "../images/light-on.svg" : "../images/light-off.svg")
|
||||
: app.interfacesToIcon(deviceClass.interfaces)
|
||||
color: powerState.value === true ? app.accentColor : keyColor
|
||||
}
|
||||
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"] = !powerState.value;
|
||||
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("noisesensor") >= 0) {
|
||||
tmp.push({iface: "noisesensor", state: "noise"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("co2sensor") >= 0) {
|
||||
tmp.push({iface: "co2sensor", state: "co2"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("smartmeterconsumer") >= 0) {
|
||||
tmp.push({iface: "smartmeterconsumer", state: "totalEnergyConsumed"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("smartmeterproducer") >= 0) {
|
||||
tmp.push({iface: "smartmeterproducer", state: "totalEnergyProduced"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("daylightsensor") >= 0) {
|
||||
tmp.push({iface: "daylightsensor", state: "daylight"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("presencesensor") >= 0) {
|
||||
tmp.push({iface: "presencesensor", state: "isPresent"});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
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)
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
visible: sensorsRoot.currentStateType.type.toLowerCase() !== "bool"
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentStateType.unitString
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentState.value// + " " + sensorsRoot.currentStateType.unitString
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
Led {
|
||||
state: sensorsRoot.currentState.value === true ? "on" : "off"
|
||||
visible: sensorsRoot.currentStateType.type.toLowerCase() === "bool"
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
|
||||
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.accentColor
|
||||
}
|
||||
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: percentageStateType ? device.states.getState(percentageStateType.id) : null
|
||||
from: 0
|
||||
to: 100
|
||||
value: percentateState ? percentateState.value : 0
|
||||
}
|
||||
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.accentColor
|
||||
}
|
||||
onClicked: {
|
||||
var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||
var actionType = deviceClass.actionTypes.findByName("close");
|
||||
engine.deviceManager.executeAction(device.id, actionType.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaComponent
|
||||
RowLayout {
|
||||
id: mediaRoot
|
||||
|
||||
property Device device: null
|
||||
property DeviceClass deviceClass: null
|
||||
|
||||
readonly property State playbackState: device.states.getState(deviceClass.stateTypes.findByName("playbackStatus").id)
|
||||
|
||||
function executeAction(actionName, params) {
|
||||
var actionTypeId = deviceClass.actionTypes.findByName(actionName).id;
|
||||
engine.deviceManager.executeAction(device.id, actionTypeId, params)
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * .9
|
||||
Layout.preferredWidth: height
|
||||
imageSource: "../images/media-skip-backward.svg"
|
||||
longpressImageSource: "../images/media-seek-backward.svg"
|
||||
repeat: true
|
||||
|
||||
onClicked: {
|
||||
mediaRoot.executeAction("skipBack")
|
||||
}
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("fastRewind")
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * 1.3
|
||||
Layout.preferredWidth: height
|
||||
imageSource: mediaRoot.playbackState.value === "Playing" ? "../images/media-playback-pause.svg" : "../images/media-playback-start.svg"
|
||||
longpressImageSource: "../images/media-playback-stop.svg"
|
||||
longpressEnabled: mediaRoot.playbackState.value !== "Stopped"
|
||||
|
||||
onClicked: {
|
||||
if (mediaRoot.playbackState.value === "Playing") {
|
||||
mediaRoot.executeAction("pause")
|
||||
} else {
|
||||
mediaRoot.executeAction("play")
|
||||
}
|
||||
}
|
||||
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("stop")
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * .9
|
||||
Layout.preferredWidth: height
|
||||
imageSource: "../images/media-skip-forward.svg"
|
||||
longpressImageSource: "../images/media-seek-forward.svg"
|
||||
repeat: true
|
||||
onClicked: {
|
||||
mediaRoot.executeAction("skipNext")
|
||||
}
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("fastForward")
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,6 @@ Page {
|
||||
}
|
||||
}
|
||||
function addToGroup() {
|
||||
// engine.tagsManager.tagDevice(root.device.id, "group", "My group 1")
|
||||
var dialog = addToGroupDialog.createObject(root)
|
||||
dialog.open();
|
||||
}
|
||||
@ -122,6 +121,9 @@ Page {
|
||||
headerIcon: "../images/view-grid-symbolic.svg"
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
spacing: app.margins
|
||||
TextField {
|
||||
id: newGroupdTextField
|
||||
Layout.fillWidth: true
|
||||
@ -141,6 +143,8 @@ Page {
|
||||
ListView {
|
||||
Layout.fillWidth: true
|
||||
height: 200
|
||||
clip: true
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
|
||||
model: TagListModel {
|
||||
id: groupTags
|
||||
|
||||
@ -4,6 +4,7 @@ import QtQuick.Controls.Material 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
import "../delegates"
|
||||
|
||||
Page {
|
||||
id: root
|
||||
@ -27,11 +28,28 @@ Page {
|
||||
showStates: true
|
||||
}
|
||||
|
||||
ListView {
|
||||
GridView {
|
||||
id: gridView
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins / 2
|
||||
|
||||
model: devicesInGroup
|
||||
delegate: Label {
|
||||
text: model.name
|
||||
|
||||
readonly property int minTileWidth: 180
|
||||
readonly property int minTileHeight: 240
|
||||
readonly property int tilesPerRow: root.width / minTileWidth
|
||||
|
||||
cellWidth: gridView.width / tilesPerRow
|
||||
cellHeight: cellWidth
|
||||
|
||||
delegate: ThingTile {
|
||||
width: gridView.cellWidth
|
||||
height: gridView.cellHeight
|
||||
|
||||
device: devicesInGroup.get(index)
|
||||
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("../devicepages/" + app.interfaceListToDevicePage(deviceClass.interfaces)), {device: device})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,11 +5,15 @@ import QtQuick.Layouts 1.2
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
property alias count: interfacesGridView.count
|
||||
property alias model: interfacesGridView.model
|
||||
|
||||
// Prevent scroll events to swipe left/right in case they fall through the grid
|
||||
preventStealing: true
|
||||
onWheel: wheel.accepted = true
|
||||
|
||||
GridView {
|
||||
id: interfacesGridView
|
||||
anchors.fill: parent
|
||||
|
||||
@ -4,13 +4,18 @@ import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
import "../delegates"
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
|
||||
property bool editMode: false
|
||||
readonly property int count: tagsProxy.count
|
||||
|
||||
// Prevent scroll events to swipe left/right in case they fall through the grid
|
||||
preventStealing: true
|
||||
onWheel: wheel.accepted = true
|
||||
|
||||
TagsProxyModel {
|
||||
id: tagsProxy
|
||||
tags: engine.tagsManager.tags
|
||||
@ -29,57 +34,16 @@ Item {
|
||||
cellHeight: cellWidth
|
||||
|
||||
model: tagsProxy
|
||||
delegate: MainPageTile {
|
||||
delegate: ThingTile {
|
||||
id: delegateRoot
|
||||
width: gridView.cellWidth
|
||||
height: gridView.cellHeight
|
||||
text: device.name.toUpperCase()
|
||||
iconName: app.interfacesToIcon(deviceClass.interfaces)
|
||||
iconColor: app.accentColor
|
||||
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 Device device: engine.deviceManager.devices.getDevice(deviceId)
|
||||
readonly property DeviceClass deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property State connectedState: deviceClass.interfaces.indexOf("connectable") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("connected").id) : null
|
||||
readonly property State batteryCriticalState: deviceClass.interfaces.indexOf("battery") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("batteryCritical").id) : null
|
||||
device: engine.deviceManager.devices.getDevice(deviceId)
|
||||
|
||||
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("power") >= 0) {
|
||||
return lightsComponent;
|
||||
}
|
||||
if (delegateRoot.deviceClass.interfaces.indexOf("sensor") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (delegateRoot.deviceClass.interfaces.indexOf("weather") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (delegateRoot.deviceClass.interfaces.indexOf("smartmeter") >= 0) {
|
||||
return sensorsComponent;
|
||||
}
|
||||
if (delegateRoot.deviceClass.interfaces.indexOf("mediacontroller") >= 0) {
|
||||
return mediaComponent;
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -174,330 +138,4 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: lightsComponent
|
||||
RowLayout {
|
||||
property var device: null
|
||||
property var deviceClass: null
|
||||
|
||||
readonly property var powerStateType: deviceClass.stateTypes.findByName("power");
|
||||
readonly property var powerState: device.states.getState(powerStateType.id)
|
||||
|
||||
readonly property var brightnessStateType: deviceClass.stateTypes.findByName("brightness");
|
||||
readonly property var brightnessState: brightnessStateType ? device.states.getState(brightnessStateType.id) : null
|
||||
|
||||
ThrottledSlider {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins / 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
opacity: deviceClass.interfaces.indexOf("dimmablelight") >= 0 ? 1 : 0
|
||||
enabled: opacity > 0
|
||||
from: 0
|
||||
to: 100
|
||||
value: brightnessState ? brightnessState.value : 0
|
||||
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: deviceClass.interfaces.indexOf("light") >= 0
|
||||
? (powerState.value === true ? "../images/light-on.svg" : "../images/light-off.svg")
|
||||
: app.interfacesToIcon(deviceClass.interfaces)
|
||||
color: powerState.value === true ? app.accentColor : keyColor
|
||||
}
|
||||
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"] = !powerState.value;
|
||||
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("noisesensor") >= 0) {
|
||||
tmp.push({iface: "noisesensor", state: "noise"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("co2sensor") >= 0) {
|
||||
tmp.push({iface: "co2sensor", state: "co2"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("smartmeterconsumer") >= 0) {
|
||||
tmp.push({iface: "smartmeterconsumer", state: "totalEnergyConsumed"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("smartmeterproducer") >= 0) {
|
||||
tmp.push({iface: "smartmeterproducer", state: "totalEnergyProduced"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("daylightsensor") >= 0) {
|
||||
tmp.push({iface: "daylightsensor", state: "daylight"});
|
||||
}
|
||||
if (deviceClass.interfaces.indexOf("presencesensor") >= 0) {
|
||||
tmp.push({iface: "presencesensor", state: "isPresent"});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
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)
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
visible: sensorsRoot.currentStateType.type.toLowerCase() !== "bool"
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentStateType.unitString
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentState.value// + " " + sensorsRoot.currentStateType.unitString
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
Led {
|
||||
state: sensorsRoot.currentState.value === true ? "on" : "off"
|
||||
visible: sensorsRoot.currentStateType.type.toLowerCase() === "bool"
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
|
||||
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.accentColor
|
||||
}
|
||||
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.accentColor
|
||||
}
|
||||
onClicked: {
|
||||
var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||
var actionType = deviceClass.actionTypes.findByName("close");
|
||||
engine.deviceManager.executeAction(device.id, actionType.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaComponent
|
||||
RowLayout {
|
||||
id: mediaRoot
|
||||
|
||||
property Device device: null
|
||||
property DeviceClass deviceClass: null
|
||||
|
||||
readonly property State playbackState: device.states.getState(deviceClass.stateTypes.findByName("playbackStatus").id)
|
||||
|
||||
function executeAction(actionName, params) {
|
||||
var actionTypeId = deviceClass.actionTypes.findByName(actionName).id;
|
||||
engine.deviceManager.executeAction(device.id, actionTypeId, params)
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * .9
|
||||
Layout.preferredWidth: height
|
||||
imageSource: "../images/media-skip-backward.svg"
|
||||
longpressImageSource: "../images/media-seek-backward.svg"
|
||||
repeat: true
|
||||
|
||||
onClicked: {
|
||||
mediaRoot.executeAction("skipBack")
|
||||
}
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("fastRewind")
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * 1.3
|
||||
Layout.preferredWidth: height
|
||||
imageSource: mediaRoot.playbackState.value === "Playing" ? "../images/media-playback-pause.svg" : "../images/media-playback-start.svg"
|
||||
longpressImageSource: "../images/media-playback-stop.svg"
|
||||
longpressEnabled: mediaRoot.playbackState.value !== "Stopped"
|
||||
|
||||
onClicked: {
|
||||
if (mediaRoot.playbackState.value === "Playing") {
|
||||
mediaRoot.executeAction("pause")
|
||||
} else {
|
||||
mediaRoot.executeAction("play")
|
||||
}
|
||||
}
|
||||
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("stop")
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
ProgressButton {
|
||||
Layout.preferredHeight: app.iconSize * .9
|
||||
Layout.preferredWidth: height
|
||||
imageSource: "../images/media-skip-forward.svg"
|
||||
longpressImageSource: "../images/media-seek-forward.svg"
|
||||
repeat: true
|
||||
onClicked: {
|
||||
mediaRoot.executeAction("skipNext")
|
||||
}
|
||||
onLongpressed: {
|
||||
mediaRoot.executeAction("fastForward")
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,10 @@ import Nymea 1.0
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import "../components"
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
preventStealing: true
|
||||
onWheel: wheel.accepted = true
|
||||
|
||||
readonly property int count: groupsGridView.count
|
||||
|
||||
@ -15,6 +17,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins / 2
|
||||
|
||||
|
||||
readonly property int minTileWidth: 180
|
||||
readonly property int minTileHeight: 180
|
||||
readonly property int tilesPerRow: root.width / minTileWidth
|
||||
@ -48,7 +51,7 @@ Item {
|
||||
|
||||
InterfacesProxy {
|
||||
id: controlsInGroup
|
||||
shownInterfaces: ["light", "simpleclosable"]
|
||||
shownInterfaces: ["light", "simpleclosable", "mediacontroller"]
|
||||
devicesProxyFilter: devicesInGroup
|
||||
showStates: true
|
||||
showActions: true
|
||||
@ -61,7 +64,10 @@ Item {
|
||||
}
|
||||
|
||||
contentItem: ItemDelegate {
|
||||
padding: 0
|
||||
leftPadding: 0
|
||||
topPadding: 0
|
||||
rightPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("../grouping/GroupPage.qml"), {groupTag: model.tagId})
|
||||
@ -74,6 +80,7 @@ Item {
|
||||
color: Qt.rgba(app.foregroundColor.r, app.foregroundColor.g, app.foregroundColor.b, .05)
|
||||
Label {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors { leftMargin: app.margins; rightMargin: app.margins }
|
||||
text: model.tagId.substring(6)
|
||||
elide: Text.ElideRight
|
||||
@ -82,22 +89,35 @@ Item {
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColorIcon {
|
||||
anchors.centerIn: parent
|
||||
height: app.iconSize * 2
|
||||
width: height
|
||||
visible: controlsInGroup.count == 0
|
||||
color: app.accentColor
|
||||
name: "../images/view-grid-symbolic.svg"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: controlsInGroup
|
||||
model: Math.min(controlsInGroup.count, parent.height / 50)
|
||||
delegate: Loader {
|
||||
id: controlLoader
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins / 2
|
||||
Layout.rightMargin: app.margins / 2
|
||||
property string interfaceName: controlsInGroup.get(index).name
|
||||
sourceComponent: {
|
||||
switch (model.name) {
|
||||
switch (interfaceName) {
|
||||
case "simpleclosable":
|
||||
return closableDelegate
|
||||
case "light":
|
||||
return lightDelegate
|
||||
case "mediacontroller":
|
||||
return mediaControllerDelegate
|
||||
}
|
||||
}
|
||||
Binding {
|
||||
@ -111,74 +131,77 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: app.iconSize * 1.2
|
||||
Layout.alignment: Qt.AlignRight
|
||||
color: Qt.rgba(app.foregroundColor.r, app.foregroundColor.g, app.foregroundColor.b, 0.05)
|
||||
}
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: app.iconSize * 1.2
|
||||
color: Qt.rgba(app.foregroundColor.r, app.foregroundColor.g, app.foregroundColor.b, 0.05)
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: sensorsInGroup
|
||||
delegate: Row {
|
||||
ColorIcon {
|
||||
height: app.iconSize * .8
|
||||
width: height
|
||||
name: app.interfaceToIcon(model.name)
|
||||
color: app.interfaceToColor(model.name)
|
||||
Repeater {
|
||||
model: sensorsInGroup
|
||||
delegate: Row {
|
||||
height: parent.height
|
||||
|
||||
ColorIcon {
|
||||
height: app.iconSize * .8
|
||||
width: height
|
||||
name: app.interfaceToIcon(model.name)
|
||||
color: app.interfaceToColor(model.name)
|
||||
}
|
||||
DevicesProxy {
|
||||
id: innerProxy
|
||||
engine: _engine
|
||||
parentProxy: devicesInGroup
|
||||
shownInterfaces: [model.name]
|
||||
}
|
||||
|
||||
Led {
|
||||
visible: ["presencesensor"].indexOf(model.name) >= 0
|
||||
state: {
|
||||
var stateName = null
|
||||
switch (model.name) {
|
||||
case "presencesensor":
|
||||
stateName = "isPresent"
|
||||
break;
|
||||
}
|
||||
DevicesProxy {
|
||||
id: innerProxy
|
||||
engine: _engine
|
||||
parentProxy: devicesInGroup
|
||||
shownInterfaces: [model.name]
|
||||
if (!stateName) {
|
||||
return "off";
|
||||
}
|
||||
var ret = false;
|
||||
for (var i = 0; i < innerProxy.count; i++) {
|
||||
ret |= innerProxy.get(i).states.getState(innerProxy.get(i).deviceClass.stateTypes.findByName(stateName).id).value
|
||||
}
|
||||
return ret ? "on" : "off";
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
height: parent.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: {
|
||||
var stateName = null;
|
||||
switch (model.name) {
|
||||
case "temperaturesensor":
|
||||
stateName = "temperature";
|
||||
break;
|
||||
case "lightsensor":
|
||||
stateName = "lightIntensity"
|
||||
break;
|
||||
}
|
||||
if (!stateName) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Led {
|
||||
visible: ["presencesensor"].indexOf(model.name) >= 0
|
||||
state: {
|
||||
var stateName = null
|
||||
switch (model.name) {
|
||||
case "presencesensor":
|
||||
stateName = "isPresent"
|
||||
break;
|
||||
}
|
||||
if (!stateName) {
|
||||
return "off";
|
||||
}
|
||||
var ret = false;
|
||||
for (var i = 0; i < innerProxy.count; i++) {
|
||||
ret |= innerProxy.get(i).states.getState(innerProxy.get(i).deviceClass.stateTypes.findByName(stateName).id).value
|
||||
}
|
||||
return ret ? "on" : "off";
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: {
|
||||
var stateName = null;
|
||||
switch (model.name) {
|
||||
case "temperaturesensor":
|
||||
stateName = "temperature";
|
||||
break;
|
||||
case "lightsensor":
|
||||
stateName = "lightIntensity"
|
||||
break;
|
||||
}
|
||||
if (!stateName) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var ret = 0
|
||||
for (var i = 0; i < innerProxy.count; i++) {
|
||||
ret += innerProxy.get(i).states.getState(innerProxy.get(i).deviceClass.stateTypes.findByName(stateName).id).value
|
||||
}
|
||||
return (ret / innerProxy.count).toFixed(1)
|
||||
}
|
||||
var ret = 0
|
||||
for (var i = 0; i < innerProxy.count; i++) {
|
||||
ret += innerProxy.get(i).states.getState(innerProxy.get(i).deviceClass.stateTypes.findByName(stateName).id).value
|
||||
}
|
||||
return (ret / innerProxy.count).toFixed(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -351,4 +374,19 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaControllerDelegate
|
||||
MediaControls {
|
||||
property var devices: null
|
||||
DevicesProxy {
|
||||
id: mediaControllers
|
||||
engine: _engine
|
||||
parentProxy: devices
|
||||
shownInterfaces: ["mediacontroller"]
|
||||
}
|
||||
|
||||
device: mediaControllers.parentProxy ? mediaControllers.get(0) : null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,11 +5,15 @@ import Nymea 1.0
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import "../components"
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
|
||||
readonly property int count: interfacesGridView.count
|
||||
|
||||
// Prevent scroll events to swipe left/right in case they fall through the grid
|
||||
preventStealing: true
|
||||
onWheel: wheel.accepted = true
|
||||
|
||||
GridView {
|
||||
id: interfacesGridView
|
||||
anchors.fill: parent
|
||||
|
||||
Reference in New Issue
Block a user