improve device editing

This commit is contained in:
Michael Zanetti 2018-04-10 13:39:46 +02:00
parent a53a182364
commit f070e67bfc
17 changed files with 364 additions and 70 deletions

View File

@ -25,8 +25,7 @@
#include <QDebug> #include <QDebug>
Device::Device(QObject *parent) : Device::Device(QObject *parent) :
QObject(parent), QObject(parent)
m_statesProxy(new StatesProxy(this))
{ {
} }
@ -35,14 +34,9 @@ QString Device::name() const
return m_name; return m_name;
} }
QString Device::deviceName() const void Device::setName(const QString &name)
{ {
return m_name; m_name = name;
}
void Device::setDeviceName(const QString &deviceName)
{
m_name = deviceName;
emit nameChanged(); emit nameChanged();
} }
@ -97,12 +91,6 @@ void Device::setStates(States *states)
{ {
m_states = states; m_states = states;
emit statesChanged(); emit statesChanged();
m_statesProxy->setStates(states);
}
StatesProxy *Device::statesProxy() const
{
return m_statesProxy;
} }
bool Device::hasState(const QUuid &stateTypeId) bool Device::hasState(const QUuid &stateTypeId)

View File

@ -36,19 +36,15 @@ class Device : public QObject
Q_PROPERTY(QUuid id READ id CONSTANT) Q_PROPERTY(QUuid id READ id CONSTANT)
Q_PROPERTY(QUuid deviceClassId READ deviceClassId CONSTANT) Q_PROPERTY(QUuid deviceClassId READ deviceClassId CONSTANT)
Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString deviceName READ deviceName NOTIFY nameChanged)
Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged) Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged)
Q_PROPERTY(Params *params READ params NOTIFY paramsChanged) Q_PROPERTY(Params *params READ params NOTIFY paramsChanged)
Q_PROPERTY(States *states READ states NOTIFY statesChanged) Q_PROPERTY(States *states READ states NOTIFY statesChanged)
Q_PROPERTY(StatesProxy *statesProxy READ statesProxy CONSTANT)
public: public:
explicit Device(QObject *parent = 0); explicit Device(QObject *parent = 0);
QString name() const; QString name() const;
void setName(const QString &name);
QString deviceName() const;
void setDeviceName(const QString &deviceName);
QUuid id() const; QUuid id() const;
void setId(const QUuid &id); void setId(const QUuid &id);
@ -65,8 +61,6 @@ public:
States *states() const; States *states() const;
void setStates(States *states); void setStates(States *states);
StatesProxy *statesProxy() const;
Q_INVOKABLE bool hasState(const QUuid &stateTypeId); Q_INVOKABLE bool hasState(const QUuid &stateTypeId);
Q_INVOKABLE QVariant stateValue(const QUuid &stateTypeId); Q_INVOKABLE QVariant stateValue(const QUuid &stateTypeId);
@ -77,9 +71,8 @@ private:
QUuid m_id; QUuid m_id;
QUuid m_deviceClassId; QUuid m_deviceClassId;
bool m_setupComplete; bool m_setupComplete;
Params *m_params; Params *m_params = nullptr;
States *m_states; States *m_states = nullptr;
StatesProxy *m_statesProxy;
signals: signals:
void nameChanged(); void nameChanged();

View File

@ -81,6 +81,7 @@ QVariant Params::data(const QModelIndex &index, int role) const
void Params::addParam(Param *param) void Params::addParam(Param *param)
{ {
param->setParent(this);
beginInsertRows(QModelIndex(), m_params.count(), m_params.count()); beginInsertRows(QModelIndex(), m_params.count(), m_params.count());
//qDebug() << "Params: loaded param" << param->name(); //qDebug() << "Params: loaded param" << param->name();
m_params.append(param); m_params.append(param);

View File

@ -100,9 +100,10 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
} }
dev->setStateValue(data.value("params").toMap().value("stateTypeId").toUuid(), data.value("params").toMap().value("value")); dev->setStateValue(data.value("params").toMap().value("stateTypeId").toUuid(), data.value("params").toMap().value("value"));
} else if (notification == "Devices.DeviceAdded") { } else if (notification == "Devices.DeviceAdded") {
Device *dev = JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), m_devices); Device *dev = new Device();
if (!dev) { if (!JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), dev)) {
qWarning() << "Cannot parse json device:" << data; qWarning() << "Cannot parse json device:" << data;
delete dev;
return; return;
} }
m_devices->addDevice(dev); m_devices->addDevice(dev);
@ -112,6 +113,18 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
Device *device = m_devices->getDevice(deviceId); Device *device = m_devices->getDevice(deviceId);
m_devices->removeDevice(device); m_devices->removeDevice(device);
device->deleteLater(); device->deleteLater();
} else if (notification == "Devices.DeviceChanged") {
QUuid deviceId = data.value("params").toMap().value("device").toMap().value("id").toUuid();
qDebug() << "Device changed notification" << deviceId;
Device *oldDevice = m_devices->getDevice(deviceId);
if (!oldDevice) {
qWarning() << "Received a device changed notification for a device we don't know";
return;
}
if (!JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), oldDevice)) {
qWarning() << "Error parsing device changed notification";
return;
}
} else { } else {
qWarning() << "DeviceManager unhandled device notification received" << notification; qWarning() << "DeviceManager unhandled device notification received" << notification;
} }
@ -176,7 +189,8 @@ void DeviceManager::getPluginConfigResponse(const QVariantMap &params)
} }
QVariantList pluginParams = params.value("params").toMap().value("configuration").toList(); QVariantList pluginParams = params.value("params").toMap().value("configuration").toList();
foreach (const QVariant &paramVariant, pluginParams) { foreach (const QVariant &paramVariant, pluginParams) {
Param* param = JsonTypes::unpackParam(paramVariant.toMap(), p->params()); Param* param = new Param();
JsonTypes::unpackParam(paramVariant.toMap(), param);
p->params()->addParam(param); p->params()->addParam(param);
} }
@ -193,8 +207,11 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap &params)
if (params.value("params").toMap().keys().contains("devices")) { if (params.value("params").toMap().keys().contains("devices")) {
QVariantList deviceList = params.value("params").toMap().value("devices").toList(); QVariantList deviceList = params.value("params").toMap().value("devices").toList();
foreach (QVariant deviceVariant, deviceList) { foreach (QVariant deviceVariant, deviceList) {
Device *device = JsonTypes::unpackDevice(deviceVariant.toMap(), Engine::instance()->deviceManager()->devices()); Device *device = new Device();
if (!device) continue; if (!JsonTypes::unpackDevice(deviceVariant.toMap(), device)) {
qWarning() << "Error parsing device json";
continue;
}
// qDebug() << QJsonDocument::fromVariant(deviceVariant).toJson(); // qDebug() << QJsonDocument::fromVariant(deviceVariant).toJson();
DeviceClass *dc = m_deviceClasses->getDeviceClass(device->deviceClassId()); DeviceClass *dc = m_deviceClasses->getDeviceClass(device->deviceClassId());
@ -235,9 +252,13 @@ void DeviceManager::addDeviceResponse(const QVariantMap &params)
qWarning() << "Failed to add the device:" << params.value("params").toMap().value("deviceError").toString(); qWarning() << "Failed to add the device:" << params.value("params").toMap().value("deviceError").toString();
} else if (params.value("params").toMap().keys().contains("device")) { } else if (params.value("params").toMap().keys().contains("device")) {
QVariantMap deviceVariant = params.value("params").toMap().value("device").toMap(); QVariantMap deviceVariant = params.value("params").toMap().value("device").toMap();
Device *device = JsonTypes::unpackDevice(deviceVariant, m_devices); Device *device = new Device();
qDebug() << "Device added" << device->id().toString(); if (JsonTypes::unpackDevice(deviceVariant, device)) {
m_devices->addDevice(device); qDebug() << "Device added" << device->id().toString();
m_devices->addDevice(device);
} else {
qWarning() << "Error unpacking device json";
}
} }
emit addDeviceReply(params.value("params").toMap()); emit addDeviceReply(params.value("params").toMap());
} }
@ -264,6 +285,12 @@ void DeviceManager::setPluginConfigResponse(const QVariantMap &params)
emit savePluginConfigReply(params); emit savePluginConfigReply(params);
} }
void DeviceManager::editDeviceResponse(const QVariantMap &params)
{
qDebug() << "Edit device response" << params;
emit editDeviceReply(params);
}
void DeviceManager::savePluginConfig(const QUuid &pluginId) void DeviceManager::savePluginConfig(const QUuid &pluginId)
{ {
Plugin *p = m_plugins->getPlugin(pluginId); Plugin *p = m_plugins->getPlugin(pluginId);
@ -318,6 +345,14 @@ void DeviceManager::removeDevice(const QUuid &deviceId)
m_jsonClient->sendCommand("Devices.RemoveConfiguredDevice", params, this, "removeDeviceResponse"); m_jsonClient->sendCommand("Devices.RemoveConfiguredDevice", params, this, "removeDeviceResponse");
} }
void DeviceManager::editDevice(const QUuid &deviceId, const QString &name)
{
QVariantMap params;
params.insert("deviceId", deviceId.toString());
params.insert("name", name);
m_jsonClient->sendCommand("Devices.EditDevice", params, this, "editDeviceResponse");
}
void DeviceManager::executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params) void DeviceManager::executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params)
{ {
qDebug() << "JsonRpc: execute action " << deviceId.toString() << actionTypeId.toString() << params; qDebug() << "JsonRpc: execute action " << deviceId.toString() << actionTypeId.toString() << params;

View File

@ -60,6 +60,7 @@ public:
Q_INVOKABLE void pairDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name); Q_INVOKABLE void pairDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name);
Q_INVOKABLE void confirmPairing(const QUuid &pairingTransactionId, const QString &secret = QString()); Q_INVOKABLE void confirmPairing(const QUuid &pairingTransactionId, const QString &secret = QString());
Q_INVOKABLE void removeDevice(const QUuid &deviceId); Q_INVOKABLE void removeDevice(const QUuid &deviceId);
Q_INVOKABLE void editDevice(const QUuid &deviceId, const QString &name);
Q_INVOKABLE void executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params = QVariantList()); Q_INVOKABLE void executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params = QVariantList());
private: private:
@ -74,6 +75,7 @@ private:
Q_INVOKABLE void pairDeviceResponse(const QVariantMap &params); Q_INVOKABLE void pairDeviceResponse(const QVariantMap &params);
Q_INVOKABLE void confirmPairingResponse(const QVariantMap &params); Q_INVOKABLE void confirmPairingResponse(const QVariantMap &params);
Q_INVOKABLE void setPluginConfigResponse(const QVariantMap &params); Q_INVOKABLE void setPluginConfigResponse(const QVariantMap &params);
Q_INVOKABLE void editDeviceResponse(const QVariantMap &params);
public slots: public slots:
void savePluginConfig(const QUuid &pluginId); void savePluginConfig(const QUuid &pluginId);
@ -84,6 +86,7 @@ signals:
void addDeviceReply(const QVariantMap &params); void addDeviceReply(const QVariantMap &params);
void removeDeviceReply(const QVariantMap &params); void removeDeviceReply(const QVariantMap &params);
void savePluginConfigReply(const QVariantMap &params); void savePluginConfigReply(const QVariantMap &params);
void editDeviceReply(const QVariantMap &params);
void fetchingDataChanged(); void fetchingDataChanged();
private: private:

View File

@ -47,7 +47,7 @@ Device *Devices::getDevice(const QUuid &deviceId) const
return device; return device;
} }
} }
return 0; return nullptr;
} }
int Devices::rowCount(const QModelIndex &parent) const int Devices::rowCount(const QModelIndex &parent) const
@ -65,8 +65,6 @@ QVariant Devices::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case RoleName: case RoleName:
return device->name(); return device->name();
case RoleDeviceName:
return device->deviceName();
case RoleId: case RoleId:
return device->id().toString(); return device->id().toString();
case RoleDeviceClass: case RoleDeviceClass:
@ -86,10 +84,21 @@ QVariant Devices::data(const QModelIndex &index, int role) const
void Devices::addDevice(Device *device) void Devices::addDevice(Device *device)
{ {
device->setParent(this);
beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count()); beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count());
// qDebug() << "Devices: add device" << device->name(); // qDebug() << "Devices: add device" << device->name();
m_devices.append(device); m_devices.append(device);
endInsertRows(); endInsertRows();
connect(device, &Device::nameChanged, this, [device, this]() {
int idx = m_devices.indexOf(device);
if (idx < 0) return;
emit dataChanged(index(idx), index(idx), {RoleName});
});
connect(device, &Device::setupCompleteChanged, this, [device, this]() {
int idx = m_devices.indexOf(device);
if (idx < 0) return;
emit dataChanged(index(idx), index(idx), {RoleSetupComplete});
});
emit countChanged(); emit countChanged();
} }
@ -117,7 +126,6 @@ QHash<int, QByteArray> Devices::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
roles[RoleName] = "name"; roles[RoleName] = "name";
roles[RoleDeviceName] = "deviceName";
roles[RoleId] = "id"; roles[RoleId] = "id";
roles[RoleDeviceClass] = "deviceClassId"; roles[RoleDeviceClass] = "deviceClassId";
roles[RoleSetupComplete] = "setupComplete"; roles[RoleSetupComplete] = "setupComplete";

View File

@ -35,7 +35,6 @@ class Devices : public QAbstractListModel
public: public:
enum Roles { enum Roles {
RoleName, RoleName,
RoleDeviceName,
RoleId, RoleId,
RoleDeviceClass, RoleDeviceClass,
RoleSetupComplete, RoleSetupComplete,

View File

@ -34,10 +34,11 @@ void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry)
if (!entry.name().startsWith("nymea") || entry.serviceType() != "_jsonrpc._tcp" || entry.hostAddress().protocol() == QAbstractSocket::IPv6Protocol) { if (!entry.name().startsWith("nymea") || entry.serviceType() != "_jsonrpc._tcp" || entry.hostAddress().protocol() == QAbstractSocket::IPv6Protocol) {
return; return;
} }
// qDebug() << "avahi service entry added" << entry.name() << entry.hostAddress() << entry.port() << entry.txt() << entry.serviceType(); qDebug() << "avahi service entry added" << entry.name() << entry.hostAddress() << entry.port() << entry.txt() << entry.serviceType();
QString uuid; QString uuid;
bool sslEnabled = false; bool sslEnabled = false;
QString serverName;
foreach (const QString &txt, entry.txt()) { foreach (const QString &txt, entry.txt()) {
QPair<QString, QString> txtRecord = qMakePair<QString, QString>(txt.split("=").first(), txt.split("=").at(1)); QPair<QString, QString> txtRecord = qMakePair<QString, QString>(txt.split("=").first(), txt.split("=").at(1));
if (!sslEnabled && txtRecord.first == "sslEnabled") { if (!sslEnabled && txtRecord.first == "sslEnabled") {
@ -46,6 +47,9 @@ void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry)
if (txtRecord.first == "uuid") { if (txtRecord.first == "uuid") {
uuid = txtRecord.second; uuid = txtRecord.second;
} }
if (txtRecord.first == "name") {
serverName = txtRecord.second;
}
} }
DiscoveryDevice dev = m_discoveryModel->find(entry.hostAddress()); DiscoveryDevice dev = m_discoveryModel->find(entry.hostAddress());
@ -56,7 +60,7 @@ void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry)
dev.setUuid(uuid); dev.setUuid(uuid);
dev.setHostAddress(entry.hostAddress()); dev.setHostAddress(entry.hostAddress());
dev.setPort(entry.port()); dev.setPort(entry.port());
dev.setFriendlyName(entry.hostName()); dev.setFriendlyName(serverName + " on " + entry.hostName());
QHostAddress address = entry.hostAddress(); QHostAddress address = entry.hostAddress();
QString addressString; QString addressString;
if (address.protocol() == QAbstractSocket::IPv6Protocol) { if (address.protocol() == QAbstractSocket::IPv6Protocol) {

View File

@ -117,9 +117,10 @@ DeviceClass *JsonTypes::unpackDeviceClass(const QVariantMap &deviceClassMap, QOb
return deviceClass; return deviceClass;
} }
Param *JsonTypes::unpackParam(const QVariantMap &paramMap, QObject *parent) void JsonTypes::unpackParam(const QVariantMap &paramMap, Param *param)
{ {
return new Param(paramMap.value("paramTypeId").toString(), paramMap.value("value"), parent); param->setParamTypeId(paramMap.value("paramTypeId").toString());
param->setValue(paramMap.value("value"));
} }
ParamType *JsonTypes::unpackParamType(const QVariantMap &paramTypeMap, QObject *parent) ParamType *JsonTypes::unpackParamType(const QVariantMap &paramTypeMap, QObject *parent)
@ -187,25 +188,32 @@ ActionType *JsonTypes::unpackActionType(const QVariantMap &actionTypeMap, QObjec
return actionType; return actionType;
} }
Device *JsonTypes::unpackDevice(const QVariantMap &deviceMap, QObject *parent) bool JsonTypes::unpackDevice(const QVariantMap &deviceMap, Device *device)
{ {
Device *device = new Device(parent); device->setName(deviceMap.value("name").toString());
device->setDeviceName(deviceMap.value("name").toString());
device->setId(deviceMap.value("id").toUuid()); device->setId(deviceMap.value("id").toUuid());
device->setDeviceClassId(deviceMap.value("deviceClassId").toUuid()); device->setDeviceClassId(deviceMap.value("deviceClassId").toUuid());
device->setSetupComplete(deviceMap.value("setupComplete").toBool()); device->setSetupComplete(deviceMap.value("setupComplete").toBool());
Params *params = new Params(device); Params *params = device->params();
if (!params) {
params = new Params(device);
device->setParams(params);
}
foreach (QVariant param, deviceMap.value("params").toList()) { foreach (QVariant param, deviceMap.value("params").toList()) {
params->addParam(JsonTypes::unpackParam(param.toMap(), params)); Param *p = params->getParam(param.toMap().value("paramTypeId").toString());
if (!p) {
p = new Param();
params->addParam(p);
}
JsonTypes::unpackParam(param.toMap(), p);
} }
device->setParams(params); device->setParams(params);
DeviceClass *deviceClass = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId()); DeviceClass *deviceClass = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId());
if (!deviceClass) { if (!deviceClass) {
qWarning() << "Cannot find a device class for this device..." << device->deviceClassId() << "Skipping..."; qWarning() << "Cannot find a device class for this device..." << device->deviceClassId() << "Skipping...";
delete device; return false;
return nullptr;
} }
States *states = new States(device); States *states = new States(device);
foreach (StateType *stateType, deviceClass->stateTypes()->stateTypes()) { foreach (StateType *stateType, deviceClass->stateTypes()->stateTypes()) {
@ -214,7 +222,7 @@ Device *JsonTypes::unpackDevice(const QVariantMap &deviceMap, QObject *parent)
} }
device->setStates(states); device->setStates(states);
return device; return true;
} }
QVariantMap JsonTypes::packRule(Rule *rule) QVariantMap JsonTypes::packRule(Rule *rule)

View File

@ -53,12 +53,12 @@ public:
static Vendor *unpackVendor(const QVariantMap &vendorMap, QObject *parent); static Vendor *unpackVendor(const QVariantMap &vendorMap, QObject *parent);
static Plugin *unpackPlugin(const QVariantMap &pluginMap, QObject *parent); static Plugin *unpackPlugin(const QVariantMap &pluginMap, QObject *parent);
static DeviceClass *unpackDeviceClass(const QVariantMap &deviceClassMap, QObject *parent); static DeviceClass *unpackDeviceClass(const QVariantMap &deviceClassMap, QObject *parent);
static Param *unpackParam(const QVariantMap &paramMap, QObject *parent); static void unpackParam(const QVariantMap &paramMap, Param *param);
static ParamType *unpackParamType(const QVariantMap &paramTypeMap, QObject *parent); static ParamType *unpackParamType(const QVariantMap &paramTypeMap, QObject *parent);
static StateType *unpackStateType(const QVariantMap &stateTypeMap, QObject *parent); static StateType *unpackStateType(const QVariantMap &stateTypeMap, QObject *parent);
static EventType *unpackEventType(const QVariantMap &eventTypeMap, QObject *parent); static EventType *unpackEventType(const QVariantMap &eventTypeMap, QObject *parent);
static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent); static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent);
static Device *unpackDevice(const QVariantMap &deviceMap, QObject *parent); static bool unpackDevice(const QVariantMap &deviceMap, Device *device);
static QVariantMap packRule(Rule* rule); static QVariantMap packRule(Rule* rule);
static QVariantList packRuleActions(RuleActions* ruleActions); static QVariantList packRuleActions(RuleActions* ruleActions);

View File

@ -107,7 +107,6 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<State>(uri, 1, 0, "State", "Can't create this in QML. Get it from the States."); qmlRegisterUncreatableType<State>(uri, 1, 0, "State", "Can't create this in QML. Get it from the States.");
qmlRegisterUncreatableType<States>(uri, 1, 0, "States", "Can't create this in QML. Get it from the Device."); qmlRegisterUncreatableType<States>(uri, 1, 0, "States", "Can't create this in QML. Get it from the Device.");
qmlRegisterUncreatableType<StatesProxy>(uri, 1, 0, "StatesProxy", "Can't create this in QML. Get it from the Device.");
qmlRegisterUncreatableType<Vendor>(uri, 1, 0, "Vendor", "Can't create this in QML. Get it from the Vendors."); qmlRegisterUncreatableType<Vendor>(uri, 1, 0, "Vendor", "Can't create this in QML. Get it from the Vendors.");
qmlRegisterUncreatableType<Vendors>(uri, 1, 0, "Vendors", "Can't create this in QML. Get it from the DeviceManager."); qmlRegisterUncreatableType<Vendors>(uri, 1, 0, "Vendors", "Can't create this in QML. Get it from the DeviceManager.");

View File

@ -155,7 +155,7 @@ void LogsModel::update()
void LogsModel::logsReply(const QVariantMap &data) void LogsModel::logsReply(const QVariantMap &data)
{ {
qDebug() << "logs reply" << data; qDebug() << "logs reply";// << data;
m_busy = false; m_busy = false;
emit busyChanged(); emit busyChanged();
beginResetModel(); beginResetModel();

View File

@ -141,5 +141,6 @@
<file>ui/magic/SelectStateDescriptorParamsPage.qml</file> <file>ui/magic/SelectStateDescriptorParamsPage.qml</file>
<file>ui/magic/SelectStateDescriptorPage.qml</file> <file>ui/magic/SelectStateDescriptorPage.qml</file>
<file>ui/images/select-none.svg</file> <file>ui/images/select-none.svg</file>
<file>ui/images/edit.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -65,7 +65,8 @@ Page {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
ThrottledSlider { ThrottledSlider {
visible: model.interfaces.indexOf("dimmablelight") >= 0 id: inlineSlider
visible: model.interfaces.indexOf("dimmablelight") >= 0 && parent.width > 350
property var stateType: deviceClass.stateTypes.findByName("brightness"); property var stateType: deviceClass.stateTypes.findByName("brightness");
property var actionType: deviceClass.actionTypes.findByName("brightness"); property var actionType: deviceClass.actionTypes.findByName("brightness");
property var actionState: device.states.getState(stateType.id) property var actionState: device.states.getState(stateType.id)

View File

@ -15,10 +15,26 @@ Page {
onBackPressed: pageStack.pop() onBackPressed: pageStack.pop()
HeaderButton { HeaderButton {
imageSource: "../images/delete.svg" imageSource: "../images/navigation-menu.svg"
color: "red" onClicked: deviceMenu.open()
onClicked: { }
Engine.deviceManager.removeDevice(root.device.id) }
Menu {
id: deviceMenu
width: implicitWidth + app.margins
x: parent.width - width
IconMenuItem {
iconSource: "../images/delete.svg"
text: "Delete Thing"
onTriggered: Engine.deviceManager.removeDevice(root.device.id)
}
IconMenuItem {
iconSource: "../images/edit.svg"
text: "Rename Thing"
onTriggered: {
var popup = renameDialog.createObject(root);
popup.open();
} }
} }
} }
@ -35,19 +51,61 @@ Page {
} }
} }
ListView { Flickable {
anchors.fill: parent anchors.fill: parent
model: root.device.params
delegate: ParamDelegate { ColumnLayout {
width: parent.width width: parent.width
paramType: root.deviceClass.paramTypes.getParamType(model.id)
param: root.device.params.get(index) Label {
writable: false Layout.fillWidth: true
Layout.leftMargin: app.margins
Layout.rightMargin: app.margins
Layout.topMargin: app.margins
text: "Thing parameters".toUpperCase()
color: app.guhAccent
}
Repeater {
model: root.device.params
delegate: ParamDelegate {
Layout.fillWidth: true
paramType: root.deviceClass.paramTypes.getParamType(model.id)
param: root.device.params.get(index)
writable: false
}
}
// ThinDivider {}
} }
} }
Component { Component {
id: errorDialog id: errorDialog
ErrorDialog { } ErrorDialog { }
} }
Component {
id: renameDialog
Dialog {
id: dialog
width: parent.width * .8
x: (parent.width - width) / 2
y: app.margins
standardButtons: Dialog.Ok | Dialog.Cancel
TextField {
id: textField
text: root.device.name
width: parent.width
}
onAccepted: {
Engine.deviceManager.editDevice(root.device.id, textField.text)
dialog.destroy();
}
}
}
} }

188
mea/ui/images/edit.svg Normal file
View File

@ -0,0 +1,188 @@
<?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"
width="96"
height="96"
id="svg4874"
version="1.1"
inkscape:version="0.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="edit.svg">
<defs
id="defs4876" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.024999"
inkscape:cx="-13.537374"
inkscape:cy="33.04625"
inkscape:document-units="px"
inkscape:current-layer="g4780"
showgrid="false"
showborder="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-global="true">
<inkscape:grid
type="xygrid"
id="grid5451"
empspacing="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="92,-8.0000001"
id="guide4075" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="0,1"
position="-5,12"
id="guide4078" />
<sodipodi:guide
orientation="1,0"
position="84,-9.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
</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>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(67.857146,-78.50504)">
<g
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
id="g4845"
style="display:inline">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="next01.png"
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
id="g4778"
inkscape:label="Layer 1">
<g
transform="matrix(-1,0,0,1,575.99999,611)"
id="g4780"
style="display:inline">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
id="rect4782"
width="96.037987"
height="96"
x="-438.00244"
y="345.36221"
transform="scale(-1,1)" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.0904,368.96573 c -0.0215,-0.0161 -0.0354,-0.0404 -0.0567,-0.0566 -0.0253,-0.0201 -0.057,-0.0305 -0.0821,-0.0508 z"
id="path4157" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.07673,417.80167 -0.13873,0.10742 c 0.0251,-0.0203 0.0569,-0.0307 0.0821,-0.0508 0.0214,-0.0162 0.0353,-0.0405 0.0567,-0.0566 z"
id="path4344" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.49851656;marker:none;enable-background:accumulate"
d="M 73.474609 8.0058594 L 18.333984 63.923828 L 18.248047 64.064453 C 18.005787 64.45113 16.664719 66.691559 14.792969 70.496094 C 12.921219 74.300638 10.617605 79.508457 8.765625 85.347656 L 7.890625 88.103516 L 10.648438 87.232422 C 16.492718 85.380035 21.703733 83.074485 25.507812 81.203125 C 29.311892 79.331775 31.549084 77.990865 31.933594 77.75 L 32.074219 77.666016 L 87.994141 22.529297 L 74.542969 9.0722656 L 73.474609 8.0058594 z M 68 60 L 68 64 L 88 64 L 88 60 L 68 60 z M 20.619141 65.958984 L 30.039062 75.380859 C 29.741627 75.558259 27.613295 76.823574 24.181641 78.511719 C 22.53428 79.322111 20.557327 80.203146 18.400391 81.091797 L 14.90625 77.597656 C 15.793924 75.442282 16.674151 73.467187 17.484375 71.820312 C 19.172169 68.389683 20.439857 66.259428 20.619141 65.958984 z "
transform="matrix(0,-1,-1.0003957,0,438.00245,441.36222)"
id="rect3972-1" />
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.5;marker:none;enable-background:accumulate"
id="rect3974-0"
width="32.000008"
height="4.0015807"
x="-385.36221"
y="-365.97397"
transform="matrix(0,-1,-1,0,0,0)" />
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.5;marker:none;enable-background:accumulate"
id="rect3976-5"
width="43.999897"
height="4.0014324"
x="-397.36221"
y="-353.96921"
transform="matrix(0,-1,-1,0,0,0)" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,6 +1,6 @@
import QtQuick 2.8 import QtQuick 2.8
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import QtQuick.Controls 2.1 import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1 import QtQuick.Controls.Material 2.1
import Mea 1.0 import Mea 1.0
import "../components" import "../components"
@ -102,21 +102,29 @@ ItemDelegate {
text: root.paramType.minValue text: root.paramType.minValue
} }
Slider { Slider {
id: slider
Layout.fillWidth: true Layout.fillWidth: true
from: root.paramType.minValue from: root.paramType.minValue
to: root.paramType.maxValue to: root.paramType.maxValue
value: root.param.value value: root.param.value
stepSize: { stepSize: {
switch (root.paramType.type) { switch (root.paramType.type.toLowerCase()) {
case "Int": case "int":
return 1; return 1;
} }
return 0.01; return 0.01;
} }
onMoved: { onMoved: {
root.param.value = value; var newValue
switch (root.paramType.type.toLowerCase()) {
case "int":
newValue = Math.round(value)
break;
default:
newValue = Math.round(value * 10) / 10
}
root.param.value = newValue;
} }
} }
Label { Label {