Skip to content

Commit

Permalink
iio-widgets: Add empty data strategy
Browse files Browse the repository at this point in the history
Signed-off-by: Andrei-Fabian-Pop <[email protected]>
  • Loading branch information
Andrei-Fabian-Pop committed Sep 2, 2024
1 parent fb84036 commit 448f410
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 84 deletions.
5 changes: 2 additions & 3 deletions gr-util/src/grdeviceaddon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ QWidget *GRDeviceAddon::createAttrMenu(QWidget *parent)
MenuSectionWidget *attrContainer = new MenuSectionWidget(parent);
MenuCollapseSection *attr =
new MenuCollapseSection("ATTRIBUTES", MenuCollapseSection::MHCW_NONE, attrContainer);
QList<IIOWidget *> attrWidgets = IIOWidgetBuilder().device(m_src->iioDev()).parent(parent).buildAll();
QList<IIOWidget *> attrWidgets = IIOWidgetBuilder(parent).device(m_src->iioDev()).buildAll();
const struct iio_context *ctx = iio_device_get_context(m_src->iioDev());
attrWidgets.append(IIOWidgetBuilder()
attrWidgets.append(IIOWidgetBuilder(parent)
.context(const_cast<iio_context *>(ctx))
.device(m_src->iioDev())
.attribute("Triggers")
.uiStrategy(IIOWidgetBuilder::UIS::ComboUi)
.dataStrategy(IIOWidgetBuilder::DS::TriggerData)
.parent(parent)
.buildSingle());

auto layout = new QVBoxLayout();
Expand Down
2 changes: 1 addition & 1 deletion gr-util/src/grtimechanneladdon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ QWidget *GRTimeChannelAddon::createAttrMenu(QWidget *parent)
MenuSectionWidget *attrcontainer = new MenuSectionWidget(parent);
MenuCollapseSection *attr =
new MenuCollapseSection("ATTRIBUTES", MenuCollapseSection::MHCW_NONE, attrcontainer);
QList<IIOWidget *> attrWidgets = IIOWidgetBuilder().channel(grch()->channel()).parent(parent).buildAll();
QList<IIOWidget *> attrWidgets = IIOWidgetBuilder(parent).channel(grch()->channel()).buildAll();

auto layout = new QVBoxLayout();
layout->setSpacing(10);
Expand Down
36 changes: 36 additions & 0 deletions iio-widgets/include/iio-widgets/datastrategy/emptydatastrategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef EMPTYDATASTRATEGY_H
#define EMPTYDATASTRATEGY_H

#include <QObject>
#include "datastrategy/datastrategyinterface.h"
#include "scopy-iio-widgets_export.h"

namespace scopy {
class SCOPY_IIO_WIDGETS_EXPORT EmptyDataStrategy : public QObject, public DataStrategyInterface
{
Q_OBJECT
Q_INTERFACES(scopy::DataStrategyInterface)
public:
explicit EmptyDataStrategy(QObject *parent = nullptr);

QString data() override;
QString optionalData() override;

public Q_SLOTS:
int write(QString data) override;
QPair<QString, QString> read() override;
void writeAsync(QString data) override;
void readAsync() override;

Q_SIGNALS:
void sendData(QString data, QString dataOptions) override;
void aboutToWrite(QString oldData, QString newData) override;
void emitStatus(QDateTime timestamp, QString oldData, QString newData, int returnCode, bool isReadOp) override;

private:
QString m_data;
QString m_previousData;
};
} // namespace scopy

#endif // EMPTYDATASTRATEGY_H
2 changes: 2 additions & 0 deletions iio-widgets/include/iio-widgets/iioconfigurationpopup.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOConfigurationPopup : public QWidget

Q_SIGNALS:
void selectButtonClicked(IIOItem *selected);
void emptyButtonClicked();
void exitButtonClicked();

protected Q_SLOTS:
Expand All @@ -39,6 +40,7 @@ protected Q_SLOTS:
IIOWidgetSelector *m_widgetSelector;
QPushButton *m_exitButton;
QPushButton *m_selectButton;
QPushButton *m_emptyButton;
IIOItem *m_root;
};
} // namespace scopy
Expand Down
6 changes: 3 additions & 3 deletions iio-widgets/include/iio-widgets/iiowidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,19 @@ protected Q_SLOTS:
void setLastOperationTimestamp(QDateTime timestamp);
void setLastOperationState(IIOWidget::State state);

// Core variables
/* Core variables */
GuiStrategyInterface *m_uiStrategy;
DataStrategyInterface *m_dataStrategy;
IIOWidgetFactoryRecipe m_recipe;

// Logged data
/* Logged data */
QString m_lastData;
SmallProgressBar *m_progressBar;
QDateTime *m_lastOpTimestamp;
int m_lastReturnCode;
IIOWidget::State *m_lastOpState;

// Optional configuration
/* Optional configuration */
QPushButton *m_configBtn;
IIOConfigurationPopup *m_configPopup;
bool m_isConfigurable;
Expand Down
17 changes: 10 additions & 7 deletions iio-widgets/include/iio-widgets/iiowidgetbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOWidgetBuilder : public QObject
TriggerData,
DeviceAttrData,
ContextAttrData,
EmptyData,
};

enum UIS
Expand All @@ -53,7 +54,7 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOWidgetBuilder : public QObject
RangeUi,
};

explicit IIOWidgetBuilder(QObject *parent = nullptr);
explicit IIOWidgetBuilder(QWidget *parent = nullptr);
~IIOWidgetBuilder();

/**
Expand Down Expand Up @@ -101,6 +102,13 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOWidgetBuilder : public QObject
*/
IIOWidgetBuilder &configMode(bool isConfigurable);

/**
* @brief title Sets the title of the IIOWidget
* @param title QString
* @return
*/
IIOWidgetBuilder &title(QString title);

/**
* @brief Sets the context that will be used, if no iio_device or iio_channel
* is set, the build functions will work with the context.
Expand Down Expand Up @@ -160,12 +168,6 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOWidgetBuilder : public QObject
*/
IIOWidgetBuilder &uiStrategy(IIOWidgetBuilder::UIS uiStrategy);

/**
* @brief Sets the parent of the IIOWidget that will be built.
* @param parent
*/
IIOWidgetBuilder &parent(QWidget *parent);

private:
DataStrategyInterface *createDS();
GuiStrategyInterface *createUIS();
Expand All @@ -179,6 +181,7 @@ class SCOPY_IIO_WIDGETS_EXPORT IIOWidgetBuilder : public QObject
QString m_attribute;
QString m_optionsAttribute;
QString m_optionsValues;
QString m_title;
IIOWidgetBuilder::DS m_dataStrategy;
IIOWidgetBuilder::UIS m_uiStrategy;
QWidget *m_widgetParent;
Expand Down
38 changes: 38 additions & 0 deletions iio-widgets/src/datastrategy/emptydatastrategy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "emptydatastrategy.h"

using namespace scopy;

EmptyDataStrategy::EmptyDataStrategy(QObject *parent)
: QObject{parent}
, m_data("")
, m_previousData("")
{}

QString EmptyDataStrategy::data() { return m_data; }

QString EmptyDataStrategy::optionalData() { return ""; }

int EmptyDataStrategy::write(QString data)
{
m_previousData = data;
m_data = data;
return 0;
}

QPair<QString, QString> EmptyDataStrategy::read() { return {m_data, ""}; }

void EmptyDataStrategy::writeAsync(QString data)
{
int res = write(data);
Q_EMIT emitStatus(QDateTime::currentDateTime(), m_data, data, (int)(res), false);
readAsync();
}

void EmptyDataStrategy::readAsync()
{
QPair<QString, QString> res = read();
Q_EMIT emitStatus(QDateTime::currentDateTime(), m_previousData, m_data, 0, true);
Q_EMIT sendData(res.first, res.second);
}

#include "moc_emptydatastrategy.cpp"
13 changes: 7 additions & 6 deletions iio-widgets/src/iioconfigurationpopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ void IIOConfigurationPopup::init()

Q_EMIT selectButtonClicked(iioItem);
});
QObject::connect(m_emptyButton, &QPushButton::clicked, this, &IIOConfigurationPopup::emptyButtonClicked);
QObject::connect(m_exitButton, &QPushButton::clicked, this, &IIOConfigurationPopup::exitButtonClicked);
m_selectButton->setDisabled(true);
}
Expand Down Expand Up @@ -161,12 +162,11 @@ void IIOConfigurationPopup::initUI()
buttonGroupLayout->setSpacing(10);

m_selectButton = new QPushButton("Select", buttonGroup);
m_selectButton->setObjectName("selectButton");

m_emptyButton = new QPushButton("No Data", buttonGroup);
m_exitButton = new QPushButton("Exit", buttonGroup);
m_exitButton->setObjectName("exitButton");

buttonGroupLayout->addWidget(m_exitButton);
buttonGroupLayout->addWidget(m_emptyButton);
buttonGroupLayout->addWidget(m_selectButton);

backgroundLayout->addWidget(m_titleLabel);
Expand All @@ -175,9 +175,10 @@ void IIOConfigurationPopup::initUI()

backgroundWidget->setLayout(backgroundLayout);

StyleHelper::TutorialChapterTitleLabel(m_titleLabel, "titleLabel");
StyleHelper::BlueButton(m_selectButton, "selectButton");
StyleHelper::BlueButton(m_exitButton, "exitButton");
StyleHelper::TutorialChapterTitleLabel(m_titleLabel, "TitleLabel");
StyleHelper::BlueButton(m_selectButton, "SelectButton");
StyleHelper::BlueButton(m_emptyButton, "EmptyButton");
StyleHelper::BlueButton(m_exitButton, "ExitButton");
StyleHelper::OverlayMenu(this, "IIOConfigurationPopupOverlay");
}

Expand Down
69 changes: 49 additions & 20 deletions iio-widgets/src/iiowidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@
*/

#include "iiowidget.h"
#include "channelattrdatastrategy.h"
#include "contextattrdatastrategy.h"
#include "deviceattrdatastrategy.h"
#include "iiowidgetselector.h"
#include "datastrategy/channelattrdatastrategy.h"
#include "datastrategy/contextattrdatastrategy.h"
#include "datastrategy/deviceattrdatastrategy.h"
#include "datastrategy/emptydatastrategy.h"

#include <iioutil/connectionprovider.h>
#include <QDateTime>
#include <QApplication>
#include <pluginbase/preferences.h>
#include <gui/utils.h>

#include <QDateTime>
#include <QApplication>

using namespace scopy;

Q_LOGGING_CATEGORY(CAT_IIOWIDGET, "iioWidget")
Expand All @@ -44,41 +46,61 @@ IIOWidget::IIOWidget(GuiStrategyInterface *uiStrategy, DataStrategyInterface *da
, m_lastReturnCode(0)
, m_isConfigurable(false)
{
// Config button
m_configBtn->setStyleSheet("border-image: url(\":/gui/icons/scopy-default/icons/gear_wheel.svg\");");
m_configBtn->setVisible(m_isConfigurable);

// General layout
setLayout(new QVBoxLayout(this));
layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

QWidget *topWidget = new QWidget(this);
topWidget->setLayout(new QHBoxLayout(topWidget));
topWidget->layout()->setContentsMargins(0, 0, 0, 0);

QWidget *ui = m_uiStrategy->ui();
if(ui) {
layout()->addWidget(ui);
topWidget->layout()->addWidget(ui);
}
topWidget->layout()->addWidget(m_configBtn);

layout()->addWidget(topWidget);
layout()->addWidget(m_progressBar);

QObject *uiStrategyObject = dynamic_cast<QObject *>(m_uiStrategy);
QObject *dataStrategyObject = dynamic_cast<QObject *>(m_dataStrategy);
QObject *uiStrategyWidget = dynamic_cast<QObject *>(m_uiStrategy);
QObject *dataStrategyWidget = dynamic_cast<QObject *>(m_dataStrategy);

uiStrategyObject->setParent(this);
dataStrategyObject->setParent(this);
uiStrategyWidget->setParent(this);
dataStrategyWidget->setParent(this);

connect(m_configBtn, &QPushButton::clicked, this, &IIOWidget::reconfigure);
connect(m_progressBar, &SmallProgressBar::progressFinished, this, [this]() { this->saveData(m_lastData); });

connect(uiStrategyObject, SIGNAL(emitData(QString)), this, SLOT(startTimer(QString)));
connect(uiStrategyWidget, SIGNAL(emitData(QString)), this, SLOT(startTimer(QString)));
connect(uiStrategyWidget, SIGNAL(emitData(QString)), this, SIGNAL(emitData(QString)));
connect(uiStrategyWidget, SIGNAL(displayedNewData(QString, QString)), this,
SIGNAL(displayedNewData(QString, QString)));

connect(dataStrategyObject, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this,
connect(dataStrategyWidget, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this,
SLOT(emitDataStatus(QDateTime, QString, QString, int, bool)));

// forward data request from ui strategy to data strategy
connect(uiStrategyObject, SIGNAL(requestData()), dataStrategyObject, SLOT(readAsync()));
connect(uiStrategyWidget, SIGNAL(requestData()), dataStrategyWidget, SLOT(readAsync()));
connect(dataStrategyWidget, SIGNAL(sendData(QString, QString)), this, SIGNAL(sendData(QString, QString)));
connect(dataStrategyWidget, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this,
SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)));

// forward data from data strategy to ui strategy
connect(dataStrategyObject, SIGNAL(sendData(QString, QString)), uiStrategyObject,
connect(dataStrategyWidget, SIGNAL(sendData(QString, QString)), uiStrategyWidget,
SLOT(receiveData(QString, QString)));
connect(dataStrategyWidget, SIGNAL(aboutToWrite(QString, QString)), this,
SIGNAL(aboutToWrite(QString, QString)));

// intercept the sendData from dataStrategy to collect information
connect(dataStrategyObject, SIGNAL(sendData(QString, QString)), this, SLOT(storeReadInfo(QString, QString)));
connect(dataStrategyWidget, SIGNAL(sendData(QString, QString)), this, SLOT(storeReadInfo(QString, QString)));

// The data will be populated here
bool useLazyLoading = Preferences::GetInstance()->get("iiowidgets_use_lazy_loading").toBool();
if(!useLazyLoading) { // force skip lazy load
LAZY_LOAD(initialize);
Expand All @@ -95,9 +117,9 @@ void IIOWidget::writeAsync(QString data) { m_dataStrategy->writeAsync(data); }

DataStrategyInterface *IIOWidget::swapDataStrategy(DataStrategyInterface *dataStrategy)
{
QWidget *dataStrategyWidget = dynamic_cast<QWidget *>(m_dataStrategy);
QWidget *uiStrategyWidget = dynamic_cast<QWidget *>(m_uiStrategy);
QWidget *newDataStrategyWidget = dynamic_cast<QWidget *>(dataStrategy);
QObject *dataStrategyWidget = dynamic_cast<QObject *>(m_dataStrategy);
QObject *uiStrategyWidget = dynamic_cast<QObject *>(m_uiStrategy);
QObject *newDataStrategyWidget = dynamic_cast<QObject *>(dataStrategy);

// disconnect old data strategy
disconnect(dataStrategyWidget, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this,
Expand Down Expand Up @@ -241,6 +263,13 @@ void IIOWidget::reconfigure()

connect(m_configPopup, &IIOConfigurationPopup::exitButtonClicked, this,
[&]() { m_configPopup->deleteLater(); });
connect(m_configPopup, &IIOConfigurationPopup::emptyButtonClicked, this, [&]() {
DataStrategyInterface *ds = new EmptyDataStrategy(this);
DataStrategyInterface *oldDS = swapDataStrategy(ds);
delete oldDS;
delete m_configPopup;
m_uiStrategy->changeName("Empty");
});
connect(m_configPopup, &IIOConfigurationPopup::selectButtonClicked, this, [&](IIOItem *item) {
DataStrategyInterface *dsCreated = nullptr;
switch(item->type()) {
Expand Down
Loading

0 comments on commit 448f410

Please sign in to comment.