mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-31 17:42:55 +08:00
Begin working on bar widget
This commit is contained in:
parent
000c202a10
commit
1bf1d2a714
@ -55,6 +55,7 @@ Widgets.Window {
|
||||
//
|
||||
ColumnLayout {
|
||||
x: app.spacing
|
||||
spacing: app.spacing / 2
|
||||
width: parent.width - 10 - 2 * app.spacing
|
||||
|
||||
//
|
||||
|
@ -5,6 +5,7 @@ import QtGraphicalEffects 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
visible: count > 0
|
||||
spacing: app.spacing
|
||||
|
||||
property int count: 0
|
||||
@ -72,6 +73,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
Item {
|
||||
height: hideAll.checked ? 0 : app.spacing
|
||||
height: app.spacing
|
||||
visible: !hideAll.checked && count > 0
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +174,25 @@ Widgets.Window {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Widget maximum value
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Alarm value:")
|
||||
visible: widget.currentIndex == 1 || widget.currentIndex == 2
|
||||
} TextField {
|
||||
id: alarm
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_JSON_Editor.datasetWidgetAlarm(group, dataset)
|
||||
visible: widget.currentIndex == 1 || widget.currentIndex == 2
|
||||
onTextChanged: Cpp_JSON_Editor.setDatasetWidgetAlarm(group, dataset, text)
|
||||
|
||||
validator: DoubleValidator {
|
||||
top: parseFloat(max.text)
|
||||
bottom: parseFloat(min.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
|
@ -144,7 +144,7 @@ Widgets.Window {
|
||||
columnSpacing: app.spacing
|
||||
Layout.fillHeight: repeater.model > 0
|
||||
columns: Math.floor(column.width / 320)
|
||||
Layout.minimumHeight: (repeater.model / columns) * 300
|
||||
Layout.minimumHeight: (repeater.model / columns) * 320
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
@ -154,7 +154,7 @@ Widgets.Window {
|
||||
group: root.group
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 320
|
||||
Layout.minimumHeight: 300
|
||||
Layout.minimumHeight: 320
|
||||
showGroupWidget: widget.currentIndex > 0
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
"graphDialBorder":"#222222",
|
||||
"datasetTextPrimary":"#24476a",
|
||||
"datasetTextSecondary":"#666666",
|
||||
"datasetWindowBackground":"#fafafa",
|
||||
"datasetWindowBackground":"#e8e8e8",
|
||||
"datasetWindowBorder":"#336698",
|
||||
"embeddedWindowBackground":"#f1f1f1",
|
||||
"ledEnabled":"#0072C3",
|
||||
|
@ -46,6 +46,30 @@ bool Dataset::graph() const
|
||||
return m_graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum value of the dataset
|
||||
*/
|
||||
double Dataset::min() const
|
||||
{
|
||||
return m_min.toDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum value of the dataset
|
||||
*/
|
||||
double Dataset::max() const
|
||||
{
|
||||
return m_max.toDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alarm level of the dataset
|
||||
*/
|
||||
double Dataset::alarm() const
|
||||
{
|
||||
return m_alarm.toDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The title/description of this dataset
|
||||
*/
|
||||
@ -103,22 +127,34 @@ bool Dataset::read(const QJsonObject &object)
|
||||
auto value = object.value("v").toVariant().toString();
|
||||
auto units = object.value("u").toVariant().toString();
|
||||
auto widget = object.value("w").toVariant().toString();
|
||||
auto min = object.value("min").toVariant().toString();
|
||||
auto max = object.value("max").toVariant().toString();
|
||||
auto alarm = object.value("alarm").toVariant().toString();
|
||||
|
||||
min = min.replace("\n", "");
|
||||
min = min.replace("\r", "");
|
||||
max = max.replace("\n", "");
|
||||
max = max.replace("\r", "");
|
||||
title = title.replace("\n", "");
|
||||
title = title.replace("\r", "");
|
||||
value = value.replace("\n", "");
|
||||
value = value.replace("\r", "");
|
||||
units = units.replace("\n", "");
|
||||
units = units.replace("\r", "");
|
||||
alarm = alarm.replace("\n", "");
|
||||
alarm = alarm.replace("\r", "");
|
||||
widget = widget.replace("\n", "");
|
||||
widget = widget.replace("\r", "");
|
||||
|
||||
if (!value.isEmpty() && !title.isEmpty())
|
||||
{
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
m_graph = graph;
|
||||
m_title = title;
|
||||
m_units = units;
|
||||
m_value = value;
|
||||
m_alarm = alarm;
|
||||
m_widget = widget;
|
||||
m_jsonData = object;
|
||||
|
||||
|
@ -57,6 +57,9 @@ public:
|
||||
Dataset(QObject *parent = nullptr);
|
||||
|
||||
bool graph() const;
|
||||
double min() const;
|
||||
double max() const;
|
||||
double alarm() const;
|
||||
QString title() const;
|
||||
QString value() const;
|
||||
QString units() const;
|
||||
@ -77,6 +80,7 @@ private:
|
||||
int m_index;
|
||||
QString m_max;
|
||||
QString m_min;
|
||||
QString m_alarm;
|
||||
friend class Editor;
|
||||
};
|
||||
}
|
||||
|
@ -311,6 +311,7 @@ bool Editor::saveJsonFile()
|
||||
dataset.insert("v", "%" + QString::number(datasetIndex(i, j)));
|
||||
dataset.insert("min", datasetWidgetMin(i, j).toDouble());
|
||||
dataset.insert("max", datasetWidgetMax(i, j).toDouble());
|
||||
dataset.insert("alarm", datasetWidgetAlarm(i, j).toDouble());
|
||||
|
||||
// Add dataset to array
|
||||
datasets.append(dataset);
|
||||
@ -548,6 +549,27 @@ QString Editor::datasetWidgetMax(const int group, const int dataset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the widget alarm value of the specified dataset.
|
||||
* This option is used by the bar & gauge widgets.
|
||||
*
|
||||
* @param group index of the group in which the dataset belongs
|
||||
* @param dataset index of the dataset
|
||||
*/
|
||||
QString Editor::datasetWidgetAlarm(const int group, const int dataset)
|
||||
{
|
||||
auto set = getDataset(group, dataset);
|
||||
if (set)
|
||||
{
|
||||
if (set->m_alarm.isEmpty())
|
||||
return set->m_max;
|
||||
else
|
||||
return set->m_alarm;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Public slots
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -669,8 +691,10 @@ void Editor::openJsonFile(const QString &path)
|
||||
// Get max/min texts
|
||||
auto min = jsonDataset.value("min").toDouble();
|
||||
auto max = jsonDataset.value("max").toDouble();
|
||||
auto alarm = jsonDataset.value("alarm").toDouble();
|
||||
setDatasetWidgetMin(group, dataset, QString::number(min));
|
||||
setDatasetWidgetMax(group, dataset, QString::number(max));
|
||||
setDatasetWidgetAlarm(group, dataset, QString::number(alarm));
|
||||
|
||||
// Calculate dataset index
|
||||
auto index = jsonDataset.value("v").toString();
|
||||
@ -1118,6 +1142,25 @@ void Editor::setDatasetWidgetData(const int group, const int dataset,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the @a alarm value used by the bar & gauge widgets for the given
|
||||
* @a dataset. The value is specified in a @c QString to facilitate integration
|
||||
* with the QML user interface.
|
||||
*
|
||||
* @param group index of the group in which the dataset belongs
|
||||
* @param dataset index of the dataset
|
||||
*/
|
||||
void Editor::setDatasetWidgetAlarm(const int group, const int dataset,
|
||||
const QString &alarm)
|
||||
{
|
||||
auto set = getDataset(group, dataset);
|
||||
if (set)
|
||||
{
|
||||
set->m_alarm = alarm;
|
||||
emit datasetChanged(group, dataset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the @a modified flag of the current JSON project.
|
||||
* This flag is used to know if we should ask the user to save
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
Q_INVOKABLE int datasetWidgetIndex(const int group, const int dataset);
|
||||
Q_INVOKABLE QString datasetWidgetMin(const int group, const int dataset);
|
||||
Q_INVOKABLE QString datasetWidgetMax(const int group, const int dataset);
|
||||
Q_INVOKABLE QString datasetWidgetAlarm(const int group, const int dataset);
|
||||
|
||||
Q_INVOKABLE bool setGroupWidget(const int group, const int widgetId);
|
||||
|
||||
@ -142,6 +143,7 @@ public slots:
|
||||
void setDatasetWidgetMin(const int group, const int dataset, const QString &minimum);
|
||||
void setDatasetWidgetMax(const int group, const int dataset, const QString &maximum);
|
||||
void setDatasetWidgetData(const int group, const int dataset, const QString &widget);
|
||||
void setDatasetWidgetAlarm(const int group, const int dataset, const QString &alarm);
|
||||
|
||||
private slots:
|
||||
void setModified(const bool modified);
|
||||
|
@ -84,6 +84,14 @@ JSON::Group *Dashboard::getGroup(const int index)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSON::Dataset *Dashboard::getBar(const int index)
|
||||
{
|
||||
if (index < m_barWidgets.count())
|
||||
return m_barWidgets.at(index);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSON::Dataset *Dashboard::getCompass(const int index)
|
||||
{
|
||||
if (index < m_compassWidgets.count())
|
||||
|
@ -126,6 +126,7 @@ public:
|
||||
|
||||
QFont monoFont() const;
|
||||
JSON::Group *getGroup(const int index);
|
||||
JSON::Dataset *getBar(const int index);
|
||||
JSON::Dataset *getCompass(const int index);
|
||||
|
||||
QString title();
|
||||
|
@ -21,3 +21,60 @@
|
||||
*/
|
||||
|
||||
#include "Bar.h"
|
||||
#include "UI/Dashboard.h"
|
||||
#include "Misc/ThemeManager.h"
|
||||
|
||||
using namespace Widgets;
|
||||
|
||||
Bar::Bar(const int index)
|
||||
: m_index(index)
|
||||
{
|
||||
if (m_index >= 0)
|
||||
{
|
||||
// Configure thermo & add it to layout
|
||||
m_layout.addWidget(&m_thermo);
|
||||
m_layout.setContentsMargins(24, 24, 24, 24);
|
||||
setLayout(&m_layout);
|
||||
|
||||
// Get thermo color
|
||||
QString color;
|
||||
auto theme = Misc::ThemeManager::getInstance();
|
||||
auto barcl = theme->barWidgetColors();
|
||||
if (barcl.count() > m_index)
|
||||
color = barcl.at(m_index);
|
||||
else
|
||||
color = barcl.at(barcl.count() % m_index);
|
||||
|
||||
// Configure thermo style
|
||||
m_thermo.setPipeWidth(64);
|
||||
m_thermo.setFillBrush(QBrush(QColor(color)));
|
||||
|
||||
// Set window background
|
||||
// clang-format off
|
||||
auto qss = QString("background-color: %1;").arg(theme->datasetWindowBackground().name());
|
||||
setStyleSheet(qss);
|
||||
|
||||
// React to dashboard events
|
||||
connect(UI::Dashboard::getInstance(),
|
||||
&UI::Dashboard::updated,
|
||||
this, &Bar::update);
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
void Bar::update()
|
||||
{
|
||||
// Widget not enabled, do nothing
|
||||
if (!isEnabled())
|
||||
return;
|
||||
|
||||
// Update bar level
|
||||
auto dataset = UI::Dashboard::getInstance()->getBar(m_index);
|
||||
if (dataset)
|
||||
{
|
||||
m_thermo.setAlarmLevel(dataset->alarm());
|
||||
m_thermo.setAlarmEnabled(m_thermo.alarmLevel() > 0);
|
||||
m_thermo.setScale(dataset->min(), dataset->max());
|
||||
m_thermo.setValue(dataset->value().toDouble());
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,26 @@
|
||||
#ifndef WIDGETS_BAR_H
|
||||
#define WIDGETS_BAR_H
|
||||
|
||||
#include <QwtThermo>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
class Bar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Bar(const int index = -1);
|
||||
|
||||
private slots:
|
||||
void update();
|
||||
|
||||
private:
|
||||
int m_index;
|
||||
QwtThermo m_thermo;
|
||||
QVBoxLayout m_layout;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -29,6 +29,9 @@
|
||||
|
||||
using namespace Widgets;
|
||||
|
||||
/**
|
||||
* Configures the compass widget style & the signals/slots with the dashboard module
|
||||
*/
|
||||
Compass::Compass(const int index)
|
||||
: m_index(index)
|
||||
{
|
||||
@ -36,32 +39,43 @@ Compass::Compass(const int index)
|
||||
if (m_index < 0)
|
||||
return;
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Configure compass
|
||||
m_compass.setScale(0, 360);
|
||||
m_compass.setNeedle(
|
||||
new QwtCompassMagnetNeedle(QwtCompassMagnetNeedle::TriangleStyle));
|
||||
m_compass.setLineWidth(2);
|
||||
m_compass.setFrameShadow(QwtDial::Sunken);
|
||||
m_compass.setNeedle(new QwtCompassMagnetNeedle(QwtCompassMagnetNeedle::TriangleStyle));
|
||||
|
||||
// Set stylesheet
|
||||
auto theme = Misc::ThemeManager::getInstance();
|
||||
auto qss = QString("background-color: %1;").arg(theme->datasetWindowBackground().name());
|
||||
setStyleSheet(qss);
|
||||
|
||||
// Add compass to layout
|
||||
m_layout.addWidget(&m_compass);
|
||||
m_layout.setContentsMargins(24, 24, 24, 24);
|
||||
setLayout(&m_layout);
|
||||
|
||||
// Set stylesheet
|
||||
auto theme = Misc::ThemeManager::getInstance();
|
||||
auto qss
|
||||
= QString("background-color: %1;").arg(theme->datasetWindowBackground().name());
|
||||
setStyleSheet(qss);
|
||||
|
||||
// React to dashboard events
|
||||
connect(UI::Dashboard::getInstance(), &UI::Dashboard::updated, this,
|
||||
&Compass::update);
|
||||
connect(UI::Dashboard::getInstance(),
|
||||
&UI::Dashboard::updated,
|
||||
this, &Compass::update);
|
||||
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the widget's data
|
||||
*/
|
||||
void Compass::update()
|
||||
{
|
||||
auto dash = UI::Dashboard::getInstance();
|
||||
auto data = dash->getCompass(m_index);
|
||||
// Widget not enabled, do nothing
|
||||
if (!isEnabled())
|
||||
return;
|
||||
|
||||
if (data)
|
||||
m_compass.setValue(data->value().toDouble());
|
||||
// Update compass heading
|
||||
auto dataset = UI::Dashboard::getInstance()->getCompass(m_index);
|
||||
if (dataset)
|
||||
m_compass.setValue(dataset->value().toDouble());
|
||||
}
|
||||
|
@ -28,17 +28,26 @@
|
||||
|
||||
using namespace Widgets;
|
||||
|
||||
/**
|
||||
* Generates the user interface elements & layout
|
||||
*/
|
||||
DataGroup::DataGroup(const int index)
|
||||
: m_index(index)
|
||||
{
|
||||
if (m_index >= 0)
|
||||
{
|
||||
// clang-format off
|
||||
createUserInterface();
|
||||
connect(UI::Dashboard::getInstance(), &UI::Dashboard::updated, this,
|
||||
&DataGroup::updateUserInterface);
|
||||
connect(UI::Dashboard::getInstance(),
|
||||
&UI::Dashboard::updated,
|
||||
this, &DataGroup::updateUserInterface);
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the memory allocated for each label that represents a dataset
|
||||
*/
|
||||
DataGroup::~DataGroup()
|
||||
{
|
||||
foreach (auto icon, m_icons)
|
||||
@ -55,6 +64,11 @@ DataGroup::~DataGroup()
|
||||
delete m_mainLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a grid layout that contains the labels for each dataset.
|
||||
* The grid layout is then configured to be contained by a scroll area,
|
||||
* which is useful in the case that a group has a lot of elements inside it.
|
||||
*/
|
||||
void DataGroup::createUserInterface()
|
||||
{
|
||||
// Get group pointer
|
||||
@ -155,6 +169,9 @@ void DataGroup::createUserInterface()
|
||||
m_dataContainer->setStyleSheet(windwQSS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the dataset labels corresponding to the group that this widget is visualizing.
|
||||
*/
|
||||
void DataGroup::updateUserInterface()
|
||||
{
|
||||
// Widget not enabled, do nothing
|
||||
|
@ -19,3 +19,5 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Gauge.h"
|
||||
|
@ -23,4 +23,16 @@
|
||||
#ifndef WIDGETS_GAUGE_H
|
||||
#define WIDGETS_GAUGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QwtDial>
|
||||
#include <QwtDialNeedle>
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
class Gauge : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -57,10 +57,12 @@ WidgetLoader::WidgetLoader(QQuickItem *parent)
|
||||
m_window.setMinimumHeight(480);
|
||||
|
||||
// Configure window style sheet
|
||||
// clang-format off
|
||||
auto theme = Misc::ThemeManager::getInstance();
|
||||
auto qss
|
||||
= QString("background-color: %1;").arg(theme->datasetWindowBackground().name());
|
||||
auto qss = QString("background-color: %1;").arg(
|
||||
theme->datasetWindowBackground().name());
|
||||
m_window.setStyleSheet(qss);
|
||||
// clang-format on
|
||||
|
||||
// Resize widget to fit QML item size
|
||||
connect(this, &QQuickPaintedItem::widthChanged, this,
|
||||
@ -244,7 +246,8 @@ void WidgetLoader::setWidgetIndex(const int index)
|
||||
m_widget = new QPushButton("Plot");
|
||||
break;
|
||||
case UI::Dashboard::WidgetType::Bar:
|
||||
m_widget = new QPushButton("Bar");
|
||||
m_widget = new Bar(relativeIndex());
|
||||
m_window.setCentralWidget(new Bar(relativeIndex()));
|
||||
break;
|
||||
case UI::Dashboard::WidgetType::Gauge:
|
||||
m_widget = new QPushButton("Gauge");
|
||||
|
Loading…
x
Reference in New Issue
Block a user