Add support for signals

This commit is contained in:
uvos 2022-02-12 00:38:31 +01:00
parent 872488d174
commit 039c093b15
13 changed files with 565 additions and 237 deletions

View File

@ -13,6 +13,7 @@
#include "items/itemstore.h"
#include "items/train.h"
#include "items/turnout.h"
#include "items/signal.h"
#define BAUD QSerialPort::Baud38400
@ -94,6 +95,7 @@ int main(int argc, char *argv[])
Train::micro = µ
Turnout::micro = µ
Signal::micro = µ
ItemStore items;
QObject::connect(&micro, &Microcontroller::gotItemList, &items, &ItemStore::addItems);

View File

@ -4,6 +4,7 @@
#include <thread>
#include "items/train.h"
#include "items/turnout.h"
#include "items/signal.h"
void Microcontroller::trainSetSpeed(uint8_t id, int8_t speed)
{
@ -34,6 +35,13 @@ void Microcontroller::tunoutSetDirection(uint8_t id, bool direction)
write(ss.str().c_str());
}
void Microcontroller::signalSetValue(uint8_t id, uint8_t state)
{
std::stringstream ss;
ss<<"signal "<<(unsigned)id<<" set "<<(unsigned)state<<'\n';
write(ss.str().c_str());
}
void Microcontroller::setPower(bool on)
{
write(on ? "power on\n" : "power off\n");
@ -77,6 +85,7 @@ void Microcontroller::requestState()
{
write("train list\n");
write("turnout list\n");
write("signal list\n");
}
//housekeeping
@ -94,7 +103,7 @@ Microcontroller::~Microcontroller()
{
}
void Microcontroller::setIODevice(QIODevice *port)
void Microcontroller::setIODevice(QIODevice* port)
{
_port = port;
QObject::connect(_port, &QIODevice::readyRead, this, &Microcontroller::isReadyRead);
@ -122,6 +131,17 @@ std::shared_ptr<Item> Microcontroller::processTurnoutLine(const QString& buffer)
return nullptr;
}
std::shared_ptr<Item> Microcontroller::processSignalLine(const QString& buffer)
{
QStringList bufferList = buffer.split(' ');
if(bufferList.size() >= 13 && buffer.startsWith("SIGNAL NUMBER:"))
{
return std::shared_ptr<Item>(new Signal(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[6].toInt(),
bufferList[8].toInt(), bufferList[13].toInt()));
}
return nullptr;
}
void Microcontroller::processList(const QString& buffer)
{
QStringList bufferList = buffer.split(' ');
@ -133,6 +153,8 @@ void Microcontroller::processList(const QString& buffer)
item = processTrainLine(buffer);
else if(listMode == TURNOUT_LIST)
item = processTurnoutLine(buffer);
else if(listMode == SIGNAL_LIST)
item = processSignalLine(buffer);
if(item)
itemList.push_back(item);
}
@ -150,10 +172,17 @@ void Microcontroller::processList(const QString& buffer)
void Microcontroller::processItemState(const QString& buffer)
{
std::shared_ptr<Item> item = processTrainLine(buffer);
if(_buffer.startsWith("TRAIN NUMBER:"))
itemChanged(static_cast<ItemData>(*processTrainLine(buffer)));
item = processTrainLine(buffer);
else if(_buffer.startsWith("TURNOUT NUMBER:"))
itemChanged(static_cast<ItemData>(*processTurnoutLine(buffer)));
item = processTurnoutLine(buffer);
else if(_buffer.startsWith("SIGNAL NUMBER:"))
item = processSignalLine(buffer);
if(item)
itemChanged(static_cast<ItemData>(*item));
else
qWarning()<<__func__<<"failed to process status line";
}
@ -172,7 +201,12 @@ void Microcontroller::processMicroReturn()
{
listMode = TURNOUT_LIST;
}
else if(_buffer.startsWith("TRAIN NUMBER:") || _buffer.startsWith("TURNOUT NUMBER:"))
else if(_buffer.startsWith("Signals:"))
{
listMode = SIGNAL_LIST;
}
else if(_buffer.startsWith("TRAIN NUMBER:") || _buffer.startsWith("TURNOUT NUMBER:") ||
_buffer.startsWith("SIGNAL NUMBER:"))
{
processItemState(_buffer);
}

View File

@ -32,6 +32,7 @@ private:
static constexpr int TRAIN_LIST = 1;
static constexpr int TURNOUT_LIST = 2;
static constexpr int SIGNAL_LIST = 3;
int listMode = 0;
@ -49,6 +50,7 @@ private:
void processItemState(const QString& buffer);
std::shared_ptr<Item> processTrainLine(const QString& buffer);
std::shared_ptr<Item> processTurnoutLine(const QString& buffer);
std::shared_ptr<Item> processSignalLine(const QString& buffer);
void write(char *buffer, const size_t length);
void write(const QByteArray& buffer);
@ -67,6 +69,7 @@ public slots:
void trainReverse(uint8_t id);
void trainSetFunction(uint8_t id, uint8_t function, bool on);
void tunoutSetDirection(uint8_t id, bool direction);
void signalSetValue(uint8_t id, uint8_t state);
void estop();
void setPower(bool on);

View File

@ -3,7 +3,10 @@
#include "ui_relayscrollbox.h"
#include "../items/train.h"
#include "../items/turnout.h"
#include "../items/signal.h"
#include "../trainjs.h"
#include "trainwidget.h"
#include "signalwidget.h"
ItemScrollBox::ItemScrollBox(QWidget *parent) :
QWidget(parent),
@ -23,44 +26,53 @@ void ItemScrollBox::addItem(std::weak_ptr<Item> item)
{
if(auto workItem = item.lock())
{
widgets_.push_back(new ItemWidget(item, this));
Train* train = dynamic_cast<Train*>(workItem.get());
Turnout* turnout = dynamic_cast<Turnout*>(workItem.get());
Signal* signal = dynamic_cast<Signal*>(workItem.get());
if(train)
{
TrainWidget *widget = new TrainWidget(item, this);
widgets_.push_back(widget);
if(train->getTrainId() == 0)
widgets_.back()->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z));
widget->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z));
else if(train->getTrainId() == 1)
widgets_.back()->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X));
widget->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X));
else if(train->getTrainId() == 2)
widgets_.back()->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C));
widget->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C));
else if(train->getTrainId() == 3)
widgets_.back()->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V));
widget->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V));
else if(train->getTrainId() == 4)
widgets_.back()->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B));
widget->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B));
}
else if(turnout)
{
TrainWidget *widget = new TrainWidget(item, this);
widgets_.push_back(widget);
if(turnout->getTurnoutId() == 0)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_1));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_1));
else if(turnout->getTurnoutId() == 1)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_2));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_2));
else if(turnout->getTurnoutId() == 2)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_3));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_3));
else if(turnout->getTurnoutId() == 3)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_4));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_4));
else if(turnout->getTurnoutId() == 4)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_5));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_5));
else if(turnout->getTurnoutId() == 5)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_6));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_6));
else if(turnout->getTurnoutId() == 6)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_7));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_7));
else if(turnout->getTurnoutId() == 7)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_8));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_8));
else if(turnout->getTurnoutId() == 8)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_9));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_9));
else if(turnout->getTurnoutId() == 9)
widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_0));
widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_0));
}
else if(signal)
{
SignalWidget *widget = new SignalWidget(item, this);
widgets_.push_back(widget);
}
ui->relayWidgetVbox->addWidget(widgets_.back());
connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);

View File

@ -1,5 +1,4 @@
#include "itemwidget.h"
#include "ui_itemwidget.h"
#include <QCheckBox>
#include <QDebug>
@ -9,152 +8,10 @@
ItemWidget::ItemWidget(std::weak_ptr<Item> item, QWidget *parent) :
QWidget(parent),
item_(item),
ui(new Ui::ItemWidget)
item_(item)
{
ui->setupUi(this);
qDebug()<<__func__<<" "<<(bool)item_.lock();
if(auto workingItem = item_.lock())
{
ui->label->setText(workingItem->getName());
connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::setValue);
connect(ui->checkBox_f1, &QCheckBox::stateChanged, this, &ItemWidget::f1);
connect(ui->checkBox_f2, &QCheckBox::stateChanged, this, &ItemWidget::f2);
connect(ui->checkBox_f3, &QCheckBox::stateChanged, this, &ItemWidget::f3);
connect(ui->checkBox_f4, &QCheckBox::stateChanged, this, &ItemWidget::f4);
connect(ui->pushButton_reverse, &QPushButton::clicked, this, &ItemWidget::reverse);
connect(ui->radioButton_left, &QRadioButton::clicked, this, [this]()
{
setValue(0);
});
connect(ui->radioButton_right, &QRadioButton::clicked, this, [this]()
{
setValue(1);
});
connect(workingItem.get(), &Item::valueChanged, this, &ItemWidget::moveToValue);
Train* train = dynamic_cast<Train*>(workingItem.get());
Turnout* turnout = dynamic_cast<Turnout*>(workingItem.get());
if(turnout)
{
ui->checkBox_f1->hide();
ui->checkBox_f2->hide();
ui->checkBox_f3->hide();
ui->checkBox_f4->hide();
ui->slider->hide();
}
if(!train)
{
ui->pushButton_reverse->hide();
}
else
{
ui->radioButton_left->hide();
ui->radioButton_right->hide();
uint8_t functionMask = train->getFunctionMask();
qDebug()<<"functionMask: "<<(int)functionMask;
if(!(functionMask & (1 << 0)))
ui->checkBox_f1->hide();
if(!(functionMask & (1 << 1)))
ui->checkBox_f2->hide();
if(!(functionMask & (1 << 2)))
ui->checkBox_f3->hide();
if(!(functionMask & (1 << 3)))
ui->checkBox_f4->hide();
}
}
else disable();
}
void ItemWidget::deleteItem()
{
if(auto workingItem = item_.lock())
{
deleteRequest(*workingItem);
}
}
void ItemWidget::setValue(int8_t value)
{
if(auto workingItem = item_.lock())
workingItem->setValue(value);
else
disable();
}
void ItemWidget::moveToValue(int8_t value)
{
ui->slider->blockSignals(true);
ui->radioButton_left->blockSignals(true);
ui->radioButton_right->blockSignals(true);
ui->pushButton_reverse->setText(value == 0 ? "Reverse" : "Stop");
ui->slider->setValue(value);
ui->radioButton_left->setChecked(!value);
ui->radioButton_right->setChecked(value);
ui->slider->blockSignals(false);
ui->radioButton_left->blockSignals(false);
ui->radioButton_right->blockSignals(false);
}
void ItemWidget::f1(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(0, value == Qt::Checked);
else disable();
}
void ItemWidget::f2(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(1, value == Qt::Checked);
else disable();
}
void ItemWidget::f3(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(2, value == Qt::Checked);
else disable();
}
void ItemWidget::f4(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(3, value == Qt::Checked);
else disable();
}
void ItemWidget::reverse()
{
if(auto workingItem = item_.lock())
{
Train* train = dynamic_cast<Train*>(workingItem.get());
if(train && workingItem->getValue() == 0)
train->reverse();
else
{
setValue(!((bool)workingItem->getValue()));
}
}
else disable();
}
void ItemWidget::disable()
{
ui->checkBox_f1->setEnabled(false);
ui->checkBox_f2->setEnabled(false);
ui->checkBox_f3->setEnabled(false);
ui->checkBox_f4->setEnabled(false);
ui->label->setEnabled(false);
ui->slider->setEnabled(false);
ui->pushButton_reverse->setEnabled(false);
}
bool ItemWidget::controles(const ItemData& relay)
@ -169,41 +26,11 @@ bool ItemWidget::controles(const ItemData& relay)
return true;
}
void ItemWidget::stepUp()
{
setValue(ui->slider->value()+1);
}
void ItemWidget::stepDown()
{
setValue(ui->slider->value()-1);
}
void ItemWidget::setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev)
{
shortcuts_.clear();
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(up, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::stepUp);
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(down, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::stepDown);
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(rev, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::reverse);
}
std::weak_ptr<Item> ItemWidget::getItem()
{
return item_;
}
void ItemWidget::stateChanged(int state)
{
qDebug()<<"widget got state "<<state;
ui->slider->blockSignals(true);
ui->slider->setValue(state);
ui->slider->blockSignals(false);
}
ItemWidget::~ItemWidget()
{
delete ui;
}

View File

@ -1,5 +1,4 @@
#ifndef RELAYWIDGET_H
#define RELAYWIDGET_H
#pragma once
#include <QWidget>
#include <memory>
@ -7,52 +6,26 @@
#include "itemsettingsdialog.h"
#include "../items/item.h"
namespace Ui
{
class ItemWidget;
}
class ItemWidget : public QWidget
{
Q_OBJECT
private:
protected:
std::weak_ptr<Item> item_;
std::vector< std::unique_ptr<QShortcut> > shortcuts_;
void disable();
virtual void disable(){}
signals:
void deleteRequest(const ItemData& item);
private slots:
void setValue(int8_t value);
void moveToValue(int8_t value);
void deleteItem();
void stepUp();
void stepDown();
void f1(int state);
void f2(int state);
void f3(int state);
void f4(int state);
void reverse();
public:
explicit ItemWidget(std::weak_ptr<Item> item, QWidget *parent);
std::weak_ptr<Item> getItem();
bool controles(const ItemData& relay);
~ItemWidget();
void setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev);
public slots:
void stateChanged(int state);
private:
Ui::ItemWidget *ui;
virtual void stateChanged(int state){(void)state;}
};
#endif // RELAYWIDGET_H

93
src/ui/signalwidget.cpp Normal file
View File

@ -0,0 +1,93 @@
#include "signalwidget.h"
#include "ui_signalwidget.h"
#include <QDebug>
#include <QRadioButton>
#include <memory>
#include "../items/signal.h"
SignalWidget::SignalWidget(std::weak_ptr<Item> item, QWidget *parent) :
ItemWidget(item, parent),
ui(new Ui::SignalWidget)
{
ui->setupUi(this);
if(auto workingItem = item_.lock())
{
std::shared_ptr<Signal> signal = std::dynamic_pointer_cast<Signal>(workingItem);
if(signal)
{
ui->label->setText(workingItem->getName());
connect(ui->radioButton_go, &QRadioButton::clicked, this, [this]()
{
setValue(Signal::GO);
});
connect(ui->radioButton_slow, &QRadioButton::clicked, this, [this]()
{
setValue(Signal::SLOW);
});
connect(ui->radioButton_stop, &QRadioButton::clicked, this, [this]()
{
setValue(Signal::STOP);
});
connect(signal.get(), &Item::valueChanged, this, &SignalWidget::moveToValue);
}
}
else
{
qWarning("SignalWidget got invalid item");
SignalWidget::disable();
}
}
void SignalWidget::deleteItem()
{
if(auto workingItem = item_.lock())
{
deleteRequest(*workingItem);
}
}
void SignalWidget::setValue(int8_t value)
{
if(auto workingItem = item_.lock())
workingItem->setValue(value);
else
disable();
}
void SignalWidget::moveToValue(int8_t value)
{
qDebug()<<"got value"<<value;
ui->radioButton_go->blockSignals(true);
ui->radioButton_slow->blockSignals(true);
ui->radioButton_stop->blockSignals(true);
ui->radioButton_go->setChecked(value == Signal::GO);
ui->radioButton_slow->setChecked(value == Signal::SLOW);
ui->radioButton_stop->setChecked(value == Signal::STOP);
ui->radioButton_go->blockSignals(false);
ui->radioButton_slow->blockSignals(false);
ui->radioButton_stop->blockSignals(false);
}
void SignalWidget::disable()
{
ui->radioButton_go->setEnabled(false);
ui->radioButton_slow->setEnabled(false);
ui->radioButton_stop->setEnabled(false);
}
void SignalWidget::stateChanged(int state)
{
moveToValue(state);
}
SignalWidget::~SignalWidget()
{
delete ui;
}

36
src/ui/signalwidget.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include <QWidget>
#include <memory>
#include <QShortcut>
#include "../items/signal.h"
#include "itemwidget.h"
namespace Ui
{
class SignalWidget;
}
class SignalWidget : public ItemWidget
{
Q_OBJECT
protected:
virtual void disable();
private slots:
void moveToValue(int8_t value);
void setValue(int8_t value);
void deleteItem();
public:
explicit SignalWidget(std::weak_ptr<Item> item, QWidget *parent);
~SignalWidget();
public slots:
virtual void stateChanged(int state);
private:
Ui::SignalWidget *ui;
};

98
src/ui/signalwidget.ui Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SignalWidget</class>
<widget class="QWidget" name="SignalWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>312</width>
<height>78</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="radioButton_go">
<property name="text">
<string>Go</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_slow">
<property name="text">
<string>Slow</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_stop">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

194
src/ui/trainwidget.cpp Normal file
View File

@ -0,0 +1,194 @@
#include "trainwidget.h"
#include "ui_trainwidget.h"
#include <QCheckBox>
#include <QDebug>
#include <QSlider>
#include "../items/train.h"
#include "../items/turnout.h"
TrainWidget::TrainWidget(std::weak_ptr<Item> item, QWidget *parent) :
ItemWidget(item, parent),
ui(new Ui::TrainWidget)
{
ui->setupUi(this);
if(auto workingItem = item_.lock())
{
ui->label->setText(workingItem->getName());
connect(ui->slider, &QSlider::valueChanged, this, &TrainWidget::setValue);
connect(ui->checkBox_f1, &QCheckBox::stateChanged, this, &TrainWidget::f1);
connect(ui->checkBox_f2, &QCheckBox::stateChanged, this, &TrainWidget::f2);
connect(ui->checkBox_f3, &QCheckBox::stateChanged, this, &TrainWidget::f3);
connect(ui->checkBox_f4, &QCheckBox::stateChanged, this, &TrainWidget::f4);
connect(ui->pushButton_reverse, &QPushButton::clicked, this, &TrainWidget::reverse);
connect(ui->radioButton_left, &QRadioButton::clicked, this, [this]()
{
setValue(0);
});
connect(ui->radioButton_right, &QRadioButton::clicked, this, [this]()
{
setValue(1);
});
connect(workingItem.get(), &Item::valueChanged, this, &TrainWidget::moveToValue);
Train* train = dynamic_cast<Train*>(workingItem.get());
Turnout* turnout = dynamic_cast<Turnout*>(workingItem.get());
if(turnout)
{
ui->checkBox_f1->hide();
ui->checkBox_f2->hide();
ui->checkBox_f3->hide();
ui->checkBox_f4->hide();
ui->slider->hide();
}
if(!train)
{
ui->pushButton_reverse->hide();
}
else
{
ui->radioButton_left->hide();
ui->radioButton_right->hide();
uint8_t functionMask = train->getFunctionMask();
qDebug()<<"functionMask: "<<(int)functionMask;
if(!(functionMask & (1 << 0)))
ui->checkBox_f1->hide();
if(!(functionMask & (1 << 1)))
ui->checkBox_f2->hide();
if(!(functionMask & (1 << 2)))
ui->checkBox_f3->hide();
if(!(functionMask & (1 << 3)))
ui->checkBox_f4->hide();
}
}
else
{
qWarning("TrainWidget got invalid item");
TrainWidget::disable();
}
}
void TrainWidget::deleteItem()
{
if(auto workingItem = item_.lock())
{
deleteRequest(*workingItem);
}
}
void TrainWidget::setValue(int8_t value)
{
if(auto workingItem = item_.lock())
workingItem->setValue(value);
else
disable();
}
void TrainWidget::moveToValue(int8_t value)
{
ui->slider->blockSignals(true);
ui->radioButton_left->blockSignals(true);
ui->radioButton_right->blockSignals(true);
ui->pushButton_reverse->setText(value == 0 ? "Reverse" : "Stop");
ui->slider->setValue(value);
ui->radioButton_left->setChecked(!value);
ui->radioButton_right->setChecked(value);
ui->slider->blockSignals(false);
ui->radioButton_left->blockSignals(false);
ui->radioButton_right->blockSignals(false);
}
void TrainWidget::f1(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(0, value == Qt::Checked);
else disable();
}
void TrainWidget::f2(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(1, value == Qt::Checked);
else disable();
}
void TrainWidget::f3(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(2, value == Qt::Checked);
else disable();
}
void TrainWidget::f4(int value)
{
if(auto workingItem = item_.lock())
workingItem->setFunction(3, value == Qt::Checked);
else disable();
}
void TrainWidget::reverse()
{
if(auto workingItem = item_.lock())
{
Train* train = dynamic_cast<Train*>(workingItem.get());
if(train && workingItem->getValue() == 0)
train->reverse();
else
{
setValue(!((bool)workingItem->getValue()));
}
}
else disable();
}
void TrainWidget::disable()
{
ui->checkBox_f1->setEnabled(false);
ui->checkBox_f2->setEnabled(false);
ui->checkBox_f3->setEnabled(false);
ui->checkBox_f4->setEnabled(false);
ui->label->setEnabled(false);
ui->slider->setEnabled(false);
ui->pushButton_reverse->setEnabled(false);
}
void TrainWidget::stepUp()
{
setValue(ui->slider->value()+1);
}
void TrainWidget::stepDown()
{
setValue(ui->slider->value()-1);
}
void TrainWidget::setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev)
{
shortcuts_.clear();
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(up, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::stepUp);
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(down, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::stepDown);
shortcuts_.push_back(std::unique_ptr<QShortcut>(new QShortcut(rev, this)));
connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::reverse);
}
void TrainWidget::stateChanged(int state)
{
qDebug()<<"widget got state "<<state;
ui->slider->blockSignals(true);
ui->slider->setValue(state);
ui->slider->blockSignals(false);
}
TrainWidget::~TrainWidget()
{
delete ui;
}

49
src/ui/trainwidget.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include <QWidget>
#include <memory>
#include <QShortcut>
#include "itemsettingsdialog.h"
#include "../items/item.h"
#include "itemwidget.h"
namespace Ui
{
class TrainWidget;
}
class TrainWidget : public ItemWidget
{
Q_OBJECT
protected:
std::vector< std::unique_ptr<QShortcut> > shortcuts_;
void disable();
private slots:
void setValue(int8_t value);
void moveToValue(int8_t value);
void deleteItem();
void stepUp();
void stepDown();
void f1(int state);
void f2(int state);
void f3(int state);
void f4(int state);
void reverse();
public:
explicit TrainWidget(std::weak_ptr<Item> item, QWidget *parent);
~TrainWidget();
void setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev);
public slots:
virtual void stateChanged(int state);
private:
Ui::TrainWidget *ui;
};

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ItemWidget</class>
<widget class="QWidget" name="ItemWidget">
<class>TrainWidget</class>
<widget class="QWidget" name="TrainWidget">
<property name="geometry">
<rect>
<x>0</x>

View File

@ -25,13 +25,16 @@ QMAKE_CXXFLAGS += -std=c++17 -O2
SOURCES += \
src/items/train.cpp \
src/items/turnout.cpp \
src/mainobject.cpp \
src/trainjs.cpp \
src/items/turnout.cpp \
src/mainobject.cpp \
src/trainjs.cpp \
src/QJoysticks.cpp \
src/jsbackend/SDL_Joysticks.cpp \
src/jsbackend/VirtualJoystick.cpp \
src/ui/itemwidget.cpp \
src/ui/trainwidget.cpp \
src/items/signal.cpp \
src/ui/signalwidget.cpp \
src/ui/itemscrollbox.cpp \
src/ui/mainwindow.cpp \
src/items/item.cpp \
@ -41,16 +44,19 @@ SOURCES += \
HEADERS += \
src/items/train.h \
src/items/turnout.h \
src/mainobject.h \
src/trainjs.h \
src/items/turnout.h \
src/mainobject.h \
src/trainjs.h \
src/QJoysticks.h \
src/jsbackend/SDL_Joysticks.h \
src/jsbackend/VirtualJoystick.h \
src/jsbackend/JoysticksCommon.h \
src/ui/itemwidget.h \
src/ui/trainwidget.h \
src/items/signal.h \
src/ui/signalwidget.h \
src/ui/itemscrollbox.h \
src/ui/mainwindow.h \
src/ui/mainwindow.h \
src/items/item.h \
src/items/itemstore.h
@ -61,5 +67,6 @@ INCLUDEPATH += src/ui/
FORMS += \
src/ui/mainwindow.ui \
src/ui/relayscrollbox.ui \
src/ui/itemwidget.ui
src/ui/relayscrollbox.ui \
src/ui/trainwidget.ui \
src/ui/signalwidget.ui