Commit 6a9a151d authored by Leander Schulten's avatar Leander Schulten
Browse files

Added ControlItem System:

-ControlPane
-ControlItems
-ControlItemData
parent 0533e34c
#include "controlitem.h"
#include <cmath>
ControlItem::ControlItem()
{
setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
setKeepMouseGrab(true);
setAcceptHoverEvents(true);
}
void ControlItem::setBlockWidth(int width){
if(width!=blockWidth){
blockWidth = width;
setWidth(width*rasterSize);
emit blockWidthChanged();
}
}
void ControlItem::setBlockHeight(int height){
if(height!=blockHeight){
blockHeight = height;
setHeight(height*rasterSize);
emit blockHeightChanged();
}
}
void ControlItem::savePositionInControlData(){
if (data) {
data->setStartXBlock(x()/rasterSize);
data->setStartYBlock(y()/rasterSize);
}
}
void ControlItem::setMoveable(bool m){
if(m!=moveable){
moveable=m;
emit moveableChanged();
}
}
void ControlItem::setControlData(ControlItemData *c){
if(data!=c){
if(c){
setX(c->getStartXBlock()*rasterSize);
setY(c->getStartYBlock()*rasterSize);
}
data = c;
emit controlDataChanged();
}
}
void ControlItem::mousePressEvent(QMouseEvent *event){
if(event->buttons()&Qt::LeftButton&&moveable){
event->accept();
grabPos = event->globalPos();
startPos.setX(x());
startPos.setY(y());
}
}
void ControlItem::mouseMoveEvent(QMouseEvent *event){
if(event->buttons()&Qt::LeftButton&&moveable){
event->accept();
const auto diffPos = grabPos-event->globalPos();
auto newPos = startPos-diffPos;
newPos /= rasterSize;
newPos *= rasterSize;
if(newPos.x()<0){
newPos.setX(0);
}
if(newPos.x()+width()>(parentItem()->width()/rasterSize)*rasterSize){
newPos.setX((parentItem()->width()/rasterSize)*rasterSize-width());
}
if(newPos.y()<0){
newPos.setY(0);
}
if(newPos.y()+height()>(parentItem()->height()/rasterSize)*rasterSize){
newPos.setY((parentItem()->height()/rasterSize)*rasterSize-height());
}
setProperty("x",newPos.x());
setProperty("y",newPos.y());
}
}
void ControlItem::mouseReleaseEvent(QMouseEvent *event){
event->accept();
if(event->button()&Qt::LeftButton){
}else if(event->button()&Qt::RightButton){
emit openPopup(event->x(),event->y());
}
}
void ControlItem::itemChange(ItemChange change, const ItemChangeData &value){
if(change==QQuickItem::ItemChildAddedChange){
if(childItems().size()<=3)
return;
const auto last = childItems().at(childItems().size()-2);
if(last->x()+last->width()+value.item->width()>width()){
value.item->setY(last->y()+last->height());
value.item->setX(0);
}else{
value.item->setY(last->y());
value.item->setX(last->x()+last->width());
}
}
QQuickItem::itemChange(change, value);
}
void ControlItem::hoverEnterEvent(QHoverEvent *event){
event->accept();
auto newManLength = std::sqrt(std::powf(width() - event->posF().x(),2) + std::powf(event->posF().y(),2));
if(newManLength<40)
emit settingVisibleChange(true);
}
void ControlItem::hoverMoveEvent(QHoverEvent *event){
event->accept();
auto oldManLength = std::sqrt(std::pow(width() - event->oldPosF().x(),2) + std::pow(event->oldPosF().y(),2));
auto newManLength = std::sqrt(std::powf(width() - event->posF().x(),2) + std::powf(event->posF().y(),2));
if(oldManLength<40&&newManLength>=40)
emit settingVisibleChange(false);
else if(oldManLength>40&&newManLength<=40)
emit settingVisibleChange(true);
}
void ControlItem::hoverLeaveEvent(QHoverEvent *event){
event->accept();
emit settingVisibleChange(false);
}
#ifndef CONTROLITEM_H
#define CONTROLITEM_H
#include <QQuickItem>
#include "controlitemdata.h"
class ControlItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(int rasterSize MEMBER rasterSize NOTIFY rasterSizeChanged)
Q_PROPERTY(int blockWidth READ getBlockWidth WRITE setBlockWidth NOTIFY blockWidthChanged)
Q_PROPERTY(int blockHeight READ getBlockHeight WRITE setBlockHeight NOTIFY blockHeightChanged)
Q_PROPERTY(ControlItemData * controlData READ getControlData WRITE setControlData NOTIFY controlDataChanged)
Q_PROPERTY(bool moveable READ isMoveable WRITE setMoveable NOTIFY moveableChanged)
private:
ControlItemData * data = nullptr;
int blockWidth= 0;
int blockHeight= 0;
int rasterSize = 50;
bool moveable = false;
QPoint grabPos;
QPoint startPos;
public:
ControlItem();
void setBlockWidth(int width);
void setBlockHeight(int height);
void setMoveable(bool m);
int getBlockWidth()const{return blockWidth;}
int getBlockHeight()const{return blockHeight;}
bool isMoveable()const{return moveable;}
void setControlData(ControlItemData * );
ControlItemData * getControlData()const{return data;}
void savePositionInControlData();
protected:
virtual void mousePressEvent(QMouseEvent * event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void itemChange(ItemChange change, const ItemChangeData &value);
virtual void hoverEnterEvent(QHoverEvent *event);
virtual void hoverMoveEvent(QHoverEvent *event);
virtual void hoverLeaveEvent(QHoverEvent *event);
signals:
void rasterSizeChanged();
void blockWidthChanged();
void blockHeightChanged();
void settingVisibleChange(bool visible);
void openPopup(int x, int y);
void controlDataChanged();
void moveableChanged();
public slots:
};
#endif // CONTROLITEM_H
#include "controlitemdata.h"
#include <QJsonArray>
ControlItemData::ControlItemData(Type t,QObject *parent) : QObject(parent),type(t)
{
}
ControlItemData::ControlItemData(const QJsonObject &o):
startXBlock(o["startXBlock"].toInt()),
startYBlock(o["startYBlock"].toInt()),
type(static_cast<Type>(o["type"].toInt())){
}
void ControlItemData::writeJsonObject(QJsonObject &o){
o.insert("type",type);
o.insert("startXBlock",startXBlock);
o.insert("startYBlock",startYBlock);
}
void ControlItemData::setStartXBlock(int i){
if(i!=startXBlock){
startXBlock=i;
emit startXBlockChanged();
}
}
void ControlItemData::setStartYBlock(int i){
if(i!=startYBlock){
startYBlock=i;
emit startYBlockChanged();
}
}
// start ProgrammControlItemData
ProgrammControlItemData::ProgrammControlItemData(Programm * p,QObject *parent):ControlItemData(ControlItemData::PROGRAMM,parent),programm(p){
}
ProgrammControlItemData::ProgrammControlItemData(const QJsonObject &o):
ControlItemData(o),
programm(IDBase<Programm>::getIDBaseObjectByID(o["programm"])){
}
void ProgrammControlItemData::writeJsonObject(QJsonObject &o){
ControlItemData::writeJsonObject(o);
o.insert("programm",QString::number(programm->getID().value()));
}
void ProgrammControlItemData::setProgramm(Programm *p){
if(p!=programm){
programm = p;
emit programmChanged();
}
}
// Group Model
GroupModel::GroupModel(DataModel *deviceModel):deviceModel(deviceModel){
assert(deviceModel!=nullptr);
QObject::connect(deviceModel,&DataModel::rowsAboutToBeInserted,this,&GroupModel::handleRowsAboutToBeInserted);
QObject::connect(deviceModel,&DataModel::rowsAboutToBeRemoved,this,&GroupModel::handleRowsAboutToBeRemoved);
QObject::connect(deviceModel,&DataModel::rowsInserted,this,&GroupModel::handleRowsInserted);
QObject::connect(deviceModel,&DataModel::rowsRemoved,this,&GroupModel::handleRowsRemoved);
enabled.resize(deviceModel->rowCount(QModelIndex()));
}
void GroupModel::handleRowsAboutToBeInserted(const QModelIndex &parent, int start, int end){
beginInsertRows(parent,start,end);
}
void GroupModel::handleRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end){
beginRemoveRows(parent,start,end);
}
void GroupModel::handleRowsInserted(const QModelIndex &parent, int first, int last){
Q_UNUSED(parent);
enabled.insert(enabled.cbegin()+first,first-last,false);
endInsertRows();
}
void GroupModel::handleRowsRemoved(const QModelIndex &parent, int first, int last){
Q_UNUSED(parent)
enabled.erase(enabled.cbegin()+first,enabled.cend()+last);
endRemoveRows();
}
// GroupControlItemData
GroupControlItemData::GroupControlItemData(const QJsonObject &o):ControlItemData(o),name(o["name"].toString()){
const auto enabled = o["enabledDevices"].toArray();
auto iter = IDBase<Device>::getAllIDBases().cbegin();
int index = 0;
for(const auto e_ : enabled){
const auto e = e_.toString().toLongLong();
const auto start = iter;
while (iter!=IDBase<Device>::getAllIDBases().cend()) {
if((**iter).getID()==e){
groupModel.setEnabled(index,true);
++iter;
++index;
continue;
}
++iter;
++index;
}
iter = IDBase<Device>::getAllIDBases().cbegin();
index = 0;
while (iter!=start) {
if((**iter).getID()==e){
groupModel.setEnabled(index,true);
++iter;
++index;
continue;
}
++iter;
++index;
}
}
}
void GroupControlItemData::writeJsonObject(QJsonObject &o){
QJsonArray a;
auto prog = IDBase<Device>::getAllIDBases().cbegin();
auto en = groupModel.getEnabledVector().cbegin();
for(;en!=groupModel.getEnabledVector().cend();++prog,++en){
if(*en){
a.append(QString::number((**prog).getID().value()));
}
}
o.insert("enabledDevices",a);
o.insert("name",name);
ControlItemData::writeJsonObject(o);
}
void GroupControlItemData::forEach(std::function<void (Device *)> f){
auto prog = IDBase<Device>::getAllIDBases().cbegin();
auto en = groupModel.getEnabledVector().cbegin();
for(;en!=groupModel.getEnabledVector().cend();++prog,++en){
if(*en){
f(*prog);
}
}
}
void GroupControlItemData::setName(QString n){
if(name!=n){
name = n;
emit nameChanged();
}
}
// SwitchGroupControlItemData
SwitchGroupControlItemData::SwitchGroupControlItemData(const QJsonObject &o):GroupControlItemData(o),
activated(o["activated"].toBool()),
activateCooldown(o["activateCooldown"].toInt()),
deactivateCooldown(o["deactivateCooldown"].toInt()){
}
void SwitchGroupControlItemData::writeJsonObject(QJsonObject &o){
GroupControlItemData::writeJsonObject(o);
o.insert("activated",activated);
o.insert("activateCooldown",activateCooldown);
o.insert("deactivateCooldown",deactivateCooldown);
}
void SwitchGroupControlItemData::setActivateCooldown(int c){
if(c!=activateCooldown){
activateCooldown = c;
emit activateCooldownChanged();
}
}
void SwitchGroupControlItemData::setDeactivateCooldown(int c){
if(c!=deactivateCooldown){
deactivateCooldown = c;
emit deactivateCooldownChanged();
}
}
void SwitchGroupControlItemData::setActivated(bool a){
if(a!=activated){
activated = a;
forEach([this](Device * d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setValue(255*activated);
});
emit activatedChanged();
}
}
// DimmerGroupControlItemData
DimmerGroupControlItemData::DimmerGroupControlItemData(const QJsonObject &o):GroupControlItemData(o),
maxOperation(static_cast<Operation>(o["maxOperation"].toInt())),
minOperation(static_cast<Operation>(o["minOperation"].toInt())),
maxValue( o["maxValue"].toInt()),
minValue( o["minValue"].toInt()),
value( o["value"].toInt()),
shouldOverrideValue_(o["shouldOverride"].toBool())
{
}
void DimmerGroupControlItemData::writeJsonObject(QJsonObject &o){
GroupControlItemData::writeJsonObject(o);
o.insert("maxOperation",maxOperation);
o.insert("minOperation",minOperation);
o.insert("maxValue",maxValue);
o.insert("minValue",minValue);
o.insert("value",value);
o.insert("shouldOverride",shouldOverrideValue_);
}
void DimmerGroupControlItemData::setMaxOperation(Operation o){
if(maxOperation!=o){
maxOperation = o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setMaxOperation(o);
});
emit maxOperationChanged();
}
}
void DimmerGroupControlItemData::setMinOperation(Operation o){
if(minOperation!=o){
minOperation = o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setMinOperation(o);
});
emit minOperationChanged();
}
}
void DimmerGroupControlItemData::setMaxValue(unsigned char o){
if(maxValue!=o){
maxValue = o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setMaxValue(o);
});
emit maxValueChanged();
}
}
void DimmerGroupControlItemData::setMinValue(unsigned char o){
if(minValue!=o){
minValue = o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setMinValue(o);
});
emit minValueChanged();
}
}
void DimmerGroupControlItemData::setValue(unsigned char o){
if(value!=o){
value = o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->setValue(o);
});
emit valueChanged();
}
}
void DimmerGroupControlItemData::shouldOverrideValue(bool o){
if(shouldOverrideValue_!=o){
shouldOverrideValue_=o;
forEach([=](Device* d){
auto filter = d->getFilterForChannelindex(0);
if(filter)filter->shouldOverrideValue(o);
});
emit shouldOverrideValueChanged();
}
}
#ifndef CONTROLITEMDATA_H
#define CONTROLITEMDATA_H
#include <QObject>
#include "programm.h"
#include "device.h"
class ControlItemData : public QObject
{
Q_OBJECT
Q_PROPERTY(int startXBlock READ getStartXBlock WRITE setStartXBlock NOTIFY startXBlockChanged)
Q_PROPERTY(int startYBlock READ getStartYBlock WRITE setStartYBlock NOTIFY startYBlockChanged)
private:
int startXBlock=0;
int startYBlock=0;
public:
enum Type{PROGRAMM, SWITCH_GROUP, DIMMER_GROUP};
private:
Type type;
public:
explicit ControlItemData(Type t, QObject *parent = nullptr);
ControlItemData(const QJsonObject &o);
virtual void writeJsonObject(QJsonObject &o);
int getStartXBlock()const{return startXBlock;}
int getStartYBlock()const{return startYBlock;}
void setStartXBlock(int);
void setStartYBlock(int);
signals:
void startXBlockChanged();
void startYBlockChanged();
};
class ProgrammControlItemData : public ControlItemData{
Q_OBJECT
Q_PROPERTY(Programm* programm READ getProgramm WRITE setProgramm NOTIFY programmChanged)
Programm * programm=nullptr;
public:
ProgrammControlItemData(Programm * p,QObject *parent = nullptr);
ProgrammControlItemData(const QJsonObject &o);
virtual void writeJsonObject(QJsonObject &o);
void setProgramm(Programm * );
Programm * getProgramm()const{return programm;}
signals:
void programmChanged();
};
class GroupModel : public QAbstractListModel{
Q_OBJECT
typedef IDBaseDataModel<Device> DataModel;
DataModel * deviceModel;
std::vector<bool> enabled;
protected:
void handleRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
void handleRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
void handleRowsInserted(const QModelIndex &parent, int first, int last);
void handleRowsRemoved(const QModelIndex &parent, int first, int last);
public:
GroupModel(DataModel * deviceModel = DataModel::singletone());
enum GroupModelRoles{
EnableDataRole = IDBaseDataModel<Programm*>::ItemDataRole + 1
};
const std::vector<bool>& getEnabledVector()const{return enabled;}
void setEnabled(int index, bool enabled = true){
if(index>=0 && index<rowCount(QModelIndex())){
this->enabled[index] = enabled;
}
}
virtual int rowCount(const QModelIndex &parent = QModelIndex())const override {return deviceModel->rowCount(parent);}
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)const override{
if(role == EnableDataRole){
if(index.row()>=0 && index.row()<rowCount(index)){
return QVariant(enabled.at(index.row()));
}else{
qDebug()<<"index out of range row x colum : "<<index.row()<<' '<<index.column();
}
return QVariant("Index Out of Range");
}else{
return deviceModel->data(index,role);
}
return QVariant("Keine EnableDataRole");
}
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)override{
if(role==EnableDataRole){
if(index.row()>=0 && index.row()<rowCount(index)){
if(enabled[index.row()] != value.toBool()){
enabled[index.row()] = value.toBool();
emit dataChanged(index,index,{EnableDataRole});
return true;
}
}
}
return false;
}
virtual Qt::ItemFlags flags(const QModelIndex &index) const override{
auto r = deviceModel->flags(index);
r.setFlag(Qt::ItemIsEditable);
return r;
}
QHash<int,QByteArray> roleNames() const override{
auto r = deviceModel->roleNames();
r[EnableDataRole] = "use";
return r;
}
};
class GroupControlItemData : public ControlItemData{
Q_OBJECT
Q_PROPERTY(GroupModel* groupModel READ getGroupModel CONSTANT)
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
GroupModel groupModel;
QString name;
public:
GroupControlItemData(ControlItemData::Type t, QObject *parent = nullptr):ControlItemData(t,parent){}
GroupControlItemData(const QJsonObject &o);
virtual void writeJsonObject(QJsonObject &o);
GroupModel * getGroupModel(){return &groupModel;}
void forEach(std::function<void(Device*)> f);
void setName(QString n);
QString getName()const{return name;}
signals:
void nameChanged();
};
class SwitchGroupControlItemData : public GroupControlItemData{
Q_OBJECT
Q_PROPERTY(bool activated READ isActivated WRITE setActivated NOTIFY activatedChanged)
Q_PROPERTY(int activateCooldown READ getActivateCooldown WRITE setActivateCooldown NOTIFY activateCooldownChanged)
Q_PROPERTY(int deactivateCooldown READ getDeactivateCooldown WRITE setDeactivateCooldown NOTIFY deactivateCooldownChanged)
bool activated = false;
int activateCooldown = 1000;
int deactivateCooldown = 1000;
public:
SwitchGroupControlItemData(QObject *parent = nullptr):GroupControlItemData(SWITCH_GROUP,parent){}
SwitchGroupControlItemData(const QJsonObject &o);
virtual void writeJsonObject(QJsonObject &o);
void setActivated(bool a);
bool isActivated()const{return activated;}
void setActivateCooldown(int c);
void setDeactivateCooldown(int c);
int getActivateCooldown()const{return activateCooldown;}
int getDeactivateCooldown()const{return deactivateCooldown;}
signals:
void activatedChanged();
void activateCooldownChanged();
void deactivateCooldownChanged();
};