Explorar el Código

refactor: 移除 HMI 进度条控件

main
suyu hace 3 semanas
padre
commit
1f094e7324
Se han modificado 14 ficheros con 27 adiciones y 381 borrados
  1. +1
    -10
      app/src/domain/hmi_control_registry.cpp
  2. +0
    -35
      app/src/domain/hmi_model.cpp
  3. +0
    -16
      app/src/domain/hmi_model.h
  4. +0
    -39
      app/src/infrastructure/json_project_storage.cpp
  5. +1
    -12
      app/src/services/hmi_editor_service.cpp
  6. +0
    -42
      app/src/ui/hmi_editor_widget.cpp
  7. +0
    -5
      app/src/ui/main_window.cpp
  8. +6
    -62
      app/src/ui/main_window.ui
  9. +0
    -32
      app/src/ui/property_panel_controller.cpp
  10. +0
    -8
      app/src/ui/toolbar_icon_factory.cpp
  11. +0
    -1
      app/src/ui/toolbar_icon_factory.h
  12. +0
    -40
      app/tests/domain_tests.cpp
  13. +2
    -37
      app/tests/hmi_editor_service_tests.cpp
  14. +17
    -42
      app/tests/project_management_tests.cpp

+ 1
- 10
app/src/domain/hmi_control_registry.cpp Ver fichero

@@ -69,16 +69,7 @@ constexpr std::array kControlDescriptors = {
{0, 0, 360, 136},
HmiBindingKind::None,
HmiRuntimeValueKind::None,
false},
HmiControlDescriptor{HmiControlType::ProgressBar,
"progressBar",
"进度条",
"progress-bar",
"进度",
{0, 0, 240, 36},
HmiBindingKind::Word,
HmiRuntimeValueKind::Word,
true}
false}
};

static_assert(


+ 0
- 35
app/src/domain/hmi_model.cpp Ver fichero

@@ -89,23 +89,6 @@ bool validateAppearanceProperty(

} // namespace

bool HmiProgressBarConfig::isValid() const
{
return minimumValue < maximumValue;
}

int HmiProgressBarConfig::percentageForValue(std::int16_t value) const
{
if (!isValid())
{
return 0;
}
const int minimum = minimumValue;
const int maximum = maximumValue;
const int bounded_value = std::clamp(static_cast<int>(value), minimum, maximum);
return (bounded_value - minimum) * 100 / (maximum - minimum);
}

bool HmiControl::validate(std::string *error) const
{
const HmiControlDescriptor *descriptor = findHmiControlDescriptor(type);
@@ -206,19 +189,6 @@ bool HmiControl::validate(std::string *error) const
setError(error, "非页面跳转控件不能包含跳转配置");
return false;
}
if (type == HmiControlType::ProgressBar)
{
if (!progressBar.has_value() || !progressBar->isValid())
{
setError(error, "进度条最小值必须小于最大值");
return false;
}
}
else if (progressBar.has_value())
{
setError(error, "非进度条控件不能包含进度条配置");
return false;
}
return true;
}

@@ -229,11 +199,6 @@ bool HmiControl::isConfigured() const
{
return false;
}
if (type == HmiControlType::ProgressBar
&& (!progressBar.has_value() || !progressBar->isValid()))
{
return false;
}
if (!descriptor->requiresBindingForRunning
&& type != HmiControlType::PageJump)
{


+ 0
- 16
app/src/domain/hmi_model.h Ver fichero

@@ -10,7 +10,6 @@
#include "register_address.h"
#include "project_limits.h"

#include <cstdint>
#include <map>
#include <optional>
#include <string>
@@ -56,7 +55,6 @@ enum class HmiControlType
Label, // 标签
PageJump, // 页面跳转
AlarmList, // 报警列表
ProgressBar, // 进度条
Count // 已注册控件类型数量,不作为实际控件使用
};

@@ -76,19 +74,6 @@ struct HmiPageJumpConfig
std::string targetPageId;
};

/**
* @brief 进度条的有效值范围和文字显示方式
*/
struct HmiProgressBarConfig
{
std::int16_t minimumValue = 0;
std::int16_t maximumValue = 100;
bool showValue = true;

bool isValid() const;
int percentageForValue(std::int16_t value) const;
};

/**
* @brief 描述一个可保存的 HMI 控件及其显示和寄存器配置
*
@@ -104,7 +89,6 @@ struct HmiControl
std::map<std::string, std::string> properties;
HmiButtonOperation buttonOperation = HmiButtonOperation::MomentaryOn;
std::optional<HmiPageJumpConfig> pageJump;
std::optional<HmiProgressBarConfig> progressBar;

/**
* @brief 校验控件的标识、尺寸、扩展属性和寄存器绑定


+ 0
- 39
app/src/infrastructure/json_project_storage.cpp Ver fichero

@@ -670,14 +670,6 @@ QJsonObject serializeHmiControl(const HmiControl &control)
? control.pageJump->targetPageId
: std::string{}));
}
if (control.type == HmiControlType::ProgressBar)
{
const HmiProgressBarConfig config = control.progressBar.value_or(
HmiProgressBarConfig{});
object.insert(QStringLiteral("minimumValue"), config.minimumValue);
object.insert(QStringLiteral("maximumValue"), config.maximumValue);
object.insert(QStringLiteral("showValue"), config.showValue);
}
return object;
}

@@ -735,37 +727,6 @@ bool parseHmiControl(
}
control->pageJump = HmiPageJumpConfig{std::move(target_page_id)};
}
if (control->type == HmiControlType::ProgressBar)
{
int minimum_value = 0;
int maximum_value = 0;
bool show_value = true;
if (!readInt(
object,
"minimumValue",
context,
std::numeric_limits<std::int16_t>::min(),
std::numeric_limits<std::int16_t>::max(),
&minimum_value,
state)
|| !readInt(
object,
"maximumValue",
context,
std::numeric_limits<std::int16_t>::min(),
std::numeric_limits<std::int16_t>::max(),
&maximum_value,
state)
|| !readBool(object, "showValue", context, &show_value, state))
{
return false;
}
control->progressBar = HmiProgressBarConfig{
static_cast<std::int16_t>(minimum_value),
static_cast<std::int16_t>(maximum_value),
show_value};
}

// binding 允许为 null,其余非空值必须是合法的寄存器地址对象
if (binding.isNull())
{


+ 1
- 12
app/src/services/hmi_editor_service.cpp Ver fichero

@@ -120,12 +120,6 @@ bool HmiEditorService::pagesEqual(
bool HmiEditorService::controlsEqual(
const HmiControl &left, const HmiControl &right)
{
const bool progress_equal = left.progressBar.has_value()
== right.progressBar.has_value()
&& (!left.progressBar.has_value()
|| (left.progressBar->minimumValue == right.progressBar->minimumValue
&& left.progressBar->maximumValue == right.progressBar->maximumValue
&& left.progressBar->showValue == right.progressBar->showValue));
const bool page_jump_equal = left.pageJump.has_value() == right.pageJump.has_value()
&& (!left.pageJump.has_value()
|| left.pageJump->targetPageId == right.pageJump->targetPageId);
@@ -139,8 +133,7 @@ bool HmiEditorService::controlsEqual(
&& left.binding == right.binding
&& left.properties == right.properties
&& left.buttonOperation == right.buttonOperation
&& page_jump_equal
&& progress_equal;
&& page_jump_equal;
}

HmiEditorResult HmiEditorService::historyFailure(const std::string &message)
@@ -811,10 +804,6 @@ HmiControl HmiEditorService::makeControl(
{
control.pageJump = HmiPageJumpConfig{};
}
if (descriptor.type == HmiControlType::ProgressBar)
{
control.progressBar = HmiProgressBarConfig{};
}
const int offset = static_cast<int>(page.controls.size()) * 16;
control.bounds.x = std::min(20 + offset, page.width - control.bounds.width);
control.bounds.y = std::min(20 + offset, page.height - control.bounds.height);


+ 0
- 42
app/src/ui/hmi_editor_widget.cpp Ver fichero

@@ -194,48 +194,6 @@ public:
textWithValue());
break;
}
case HmiControlType::ProgressBar:
{
const HmiProgressBarConfig config = control_.progressBar.value_or(
HmiProgressBarConfig{});
const int percentage = has_runtime_value_
? config.percentageForValue(word_value_) : 0;

painter->setPen(Qt::NoPen);
painter->setBrush(QColor(QStringLiteral("#e4e9e7")));
painter->drawRoundedRect(rect, 4, 4);

const QRectF track = rect.adjusted(2, 2, -2, -2);
if (has_runtime_value_ && percentage > 0)
{
QRectF fill = track;
fill.setWidth(track.width() * percentage / 100.0);
painter->setBrush(QColor(QStringLiteral("#3c8c62")));
painter->drawRoundedRect(fill, 3, 3);
}

painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(QColor(QStringLiteral("#617069")), 1));
painter->drawRoundedRect(rect, 4, 4);

QString display_text = QString::fromUtf8(
control_.text.data(), static_cast<int>(control_.text.size()));
if (config.showValue)
{
const QString percentage_text = has_runtime_value_
? QString::number(percentage) + QLatin1Char('%')
: runtime_active_ ? QStringLiteral("--")
: QStringLiteral("0%");
display_text = display_text.isEmpty()
? percentage_text
: display_text + QStringLiteral(": ") + percentage_text;
}
painter->setPen(configuredTextColor(QColor(QStringLiteral("#20342a"))));
painter->drawText(rect.adjusted(6, 0, -6, 0),
Qt::AlignCenter,
display_text);
break;
}
case HmiControlType::PageJump:
{
const QColor fill = runtime_active_ && page_hovered_


+ 0
- 5
app/src/ui/main_window.cpp Ver fichero

@@ -387,8 +387,6 @@ void MainWindow::configureActions()
[this] { addHmiControl(HmiControlType::NumericDisplay); });
connect(ui_->addNumericInputAction, &QAction::triggered, this,
[this] { addHmiControl(HmiControlType::NumericInput); });
connect(ui_->addProgressBarAction, &QAction::triggered, this,
[this] { addHmiControl(HmiControlType::ProgressBar); });
connect(ui_->addLabelAction, &QAction::triggered, this,
[this] { addHmiControl(HmiControlType::Label); });
connect(ui_->addPageJumpAction, &QAction::triggered, this,
@@ -403,7 +401,6 @@ void MainWindow::configureActions()
QStringLiteral("hmiMoreControlsButton"),
makeUiIcon(UiIcon::More),
QList<QAction *>{
ui_->addProgressBarAction,
ui_->addPageJumpAction,
ui_->addAlarmListAction,
ui_->configureAlarmsAction});
@@ -669,7 +666,6 @@ void MainWindow::configureAppearance()
ui_->addIndicatorAction->setIcon(makeUiIcon(UiIcon::Indicator));
ui_->addNumericDisplayAction->setIcon(makeUiIcon(UiIcon::NumericDisplay));
ui_->addNumericInputAction->setIcon(makeUiIcon(UiIcon::NumericInput));
ui_->addProgressBarAction->setIcon(makeUiIcon(UiIcon::ProgressBar));
ui_->addLabelAction->setIcon(makeUiIcon(UiIcon::Text));
ui_->addPageJumpAction->setIcon(makeUiIcon(UiIcon::PageJump));
ui_->addAlarmListAction->setIcon(makeUiIcon(UiIcon::AlarmList));
@@ -1684,7 +1680,6 @@ void MainWindow::updateModeUi(const QString &message)
ui_->addIndicatorAction->setEnabled(policy.allowsProjectEditing);
ui_->addNumericDisplayAction->setEnabled(policy.allowsProjectEditing);
ui_->addNumericInputAction->setEnabled(policy.allowsProjectEditing);
ui_->addProgressBarAction->setEnabled(policy.allowsProjectEditing);
ui_->addLabelAction->setEnabled(policy.allowsProjectEditing);
ui_->addPageJumpAction->setEnabled(policy.allowsProjectEditing);
ui_->addAlarmListAction->setEnabled(policy.allowsProjectEditing);


+ 6
- 62
app/src/ui/main_window.ui Ver fichero

@@ -671,61 +671,13 @@
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="progressMinimumLabel">
<property name="text">
<string>最小值</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="progressMinimumSpinBox">
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="progressMaximumLabel">
<property name="text">
<string>最大值</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSpinBox" name="progressMaximumSpinBox">
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="progressShowValueLabel">
<property name="text">
<string>数值显示</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="progressShowValueCheckBox">
<property name="text">
<string>显示百分比</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="textColorLabel">
<property name="text">
<string>字体颜色</string>
</property>
</widget>
</item>
<item row="13" column="1">
<item row="10" column="1">
<widget class="QWidget" name="textColorContainer">
<layout class="QHBoxLayout" name="textColorLayout">
<property name="leftMargin"><number>0</number></property>
@@ -749,24 +701,24 @@
</layout>
</widget>
</item>
<item row="14" column="0">
<item row="11" column="0">
<widget class="QLabel" name="fontSizeLabel">
<property name="text">
<string>字号</string>
</property>
</widget>
</item>
<item row="14" column="1">
<item row="11" column="1">
<widget class="QSpinBox" name="fontSizeSpinBox"/>
</item>
<item row="15" column="0">
<item row="12" column="0">
<widget class="QLabel" name="fontBoldLabel">
<property name="text">
<string>字体样式</string>
</property>
</widget>
</item>
<item row="15" column="1">
<item row="12" column="1">
<widget class="QWidget" name="fontStyleContainer">
<layout class="QHBoxLayout" name="fontStyleLayout">
<property name="leftMargin"><number>0</number></property>
@@ -786,7 +738,7 @@
</layout>
</widget>
</item>
<item row="16" column="0" colspan="2">
<item row="13" column="0" colspan="2">
<widget class="QPushButton" name="applyPropertiesButton">
<property name="text">
<string>应用属性</string>
@@ -1104,14 +1056,6 @@
<string>添加数值输入控件</string>
</property>
</action>
<action name="addProgressBarAction">
<property name="text">
<string>进度条</string>
</property>
<property name="toolTip">
<string>添加进度条控件</string>
</property>
</action>
<action name="addLabelAction">
<property name="text">
<string>文本</string>


+ 0
- 32
app/src/ui/property_panel_controller.cpp Ver fichero

@@ -193,9 +193,6 @@ void PropertyPanelController::showControlProperties(const std::string &control_i
static_cast<QWidget *>(ui_.bindingIndexSpinBox),
static_cast<QWidget *>(ui_.targetPageComboBox),
static_cast<QWidget *>(ui_.buttonOperationComboBox),
static_cast<QWidget *>(ui_.progressMinimumSpinBox),
static_cast<QWidget *>(ui_.progressMaximumSpinBox),
static_cast<QWidget *>(ui_.progressShowValueCheckBox),
static_cast<QWidget *>(ui_.textColorEdit),
static_cast<QWidget *>(ui_.textColorButton),
static_cast<QWidget *>(ui_.fontSizeSpinBox),
@@ -218,12 +215,6 @@ void PropertyPanelController::showControlProperties(const std::string &control_i
ui_.targetPageComboBox->setVisible(false);
ui_.buttonOperationLabel->setVisible(false);
ui_.buttonOperationComboBox->setVisible(false);
ui_.progressMinimumLabel->setVisible(false);
ui_.progressMinimumSpinBox->setVisible(false);
ui_.progressMaximumLabel->setVisible(false);
ui_.progressMaximumSpinBox->setVisible(false);
ui_.progressShowValueLabel->setVisible(false);
ui_.progressShowValueCheckBox->setVisible(false);
ui_.textColorEdit->clear();
ui_.textColorButton->setStyleSheet(QString{});
ui_.fontSizeSpinBox->setValue(
@@ -281,22 +272,6 @@ void PropertyPanelController::showControlProperties(const std::string &control_i
ui_.targetPageComboBox->findData(fromUtf8(target_id)));
}

const bool is_progress_bar = control->type == HmiControlType::ProgressBar;
ui_.progressMinimumLabel->setVisible(is_progress_bar);
ui_.progressMinimumSpinBox->setVisible(is_progress_bar);
ui_.progressMaximumLabel->setVisible(is_progress_bar);
ui_.progressMaximumSpinBox->setVisible(is_progress_bar);
ui_.progressShowValueLabel->setVisible(is_progress_bar);
ui_.progressShowValueCheckBox->setVisible(is_progress_bar);
ui_.progressMinimumSpinBox->setEnabled(is_progress_bar);
ui_.progressMaximumSpinBox->setEnabled(is_progress_bar);
ui_.progressShowValueCheckBox->setEnabled(is_progress_bar);
const HmiProgressBarConfig progress_config = control->progressBar.value_or(
HmiProgressBarConfig{});
ui_.progressMinimumSpinBox->setValue(progress_config.minimumValue);
ui_.progressMaximumSpinBox->setValue(progress_config.maximumValue);
ui_.progressShowValueCheckBox->setChecked(progress_config.showValue);

const auto text_color = control->properties.find(
HmiAppearanceProperty::kTextColor);
ui_.textColorEdit->setText(text_color == control->properties.cend()
@@ -572,13 +547,6 @@ void PropertyPanelController::applySelectedControlProperties()
control.pageJump = HmiPageJumpConfig{
toUtf8(ui_.targetPageComboBox->currentData().toString())};
}
if (control.type == HmiControlType::ProgressBar)
{
control.progressBar = HmiProgressBarConfig{
static_cast<std::int16_t>(ui_.progressMinimumSpinBox->value()),
static_cast<std::int16_t>(ui_.progressMaximumSpinBox->value()),
ui_.progressShowValueCheckBox->isChecked()};
}
const std::string text_color = toUtf8(ui_.textColorEdit->text());
if (text_color.empty())
{


+ 0
- 8
app/src/ui/toolbar_icon_factory.cpp Ver fichero

@@ -291,14 +291,6 @@ QPixmap renderIcon(UiIcon icon, int size)
painter.drawLine(QPointF(18, 7), QPointF(18, 17));
break;
}
case UiIcon::ProgressBar:
{
painter.drawRoundedRect(QRectF(2, 8, 20, 8), 2, 2);
painter.setPen(Qt::NoPen);
painter.setBrush(kAccent);
painter.drawRoundedRect(QRectF(4, 10, 11, 4), 1, 1);
break;
}
case UiIcon::Text:
{
painter.drawLine(QPointF(5, 5), QPointF(19, 5));


+ 0
- 1
app/src/ui/toolbar_icon_factory.h Ver fichero

@@ -30,7 +30,6 @@ enum class UiIcon
Indicator, // HMI 指示灯
NumericDisplay, // HMI 数值显示
NumericInput, // HMI 数值输入
ProgressBar, // HMI 进度条
Text, // HMI 文本
PageJump, // HMI 页面跳转
AlarmList, // HMI 报警列表


+ 0
- 40
app/tests/domain_tests.cpp Ver fichero

@@ -187,45 +187,6 @@ void testHmiControlRegistryCompleteness()
"controls without bindings must not resolve a register area");
}

void testProgressBarConfigurationBoundaries()
{
const HmiProgressBarConfig config{-20, 80, true};
require(config.isValid(), "a progress bar range must accept increasing bounds");
require(config.percentageForValue(-20) == 0,
"progress bar minimum must map to zero percent");
require(config.percentageForValue(30) == 50,
"progress bar midpoint must map to fifty percent");
require(config.percentageForValue(80) == 100,
"progress bar maximum must map to one hundred percent");
require(config.percentageForValue(-100) == 0
&& config.percentageForValue(100) == 100,
"progress bar percentages must clamp values outside the range");

HmiProgressBarConfig invalid_range{10, 10, true};
require(!invalid_range.isValid()
&& invalid_range.percentageForValue(10) == 0,
"progress bar must reject an empty range defensively");

HmiControl progress;
progress.id = "progress";
progress.type = HmiControlType::ProgressBar;
progress.progressBar = config;
require(progress.validate(),
"an unbound progress bar with valid configuration must remain a valid draft");
require(!progress.isConfigured(),
"an unbound progress bar must not be ready for running");
progress.binding = RegisterAddress{RegisterArea::D, 0};
require(progress.validate() && progress.isConfigured(),
"a progress bar with a D binding must be ready for running");
progress.progressBar->maximumValue = progress.progressBar->minimumValue;
require(!progress.validate(),
"a progress bar with an invalid range must be rejected");
progress.progressBar = config;
progress.binding = RegisterAddress{RegisterArea::M, 0};
require(!progress.validate(),
"a progress bar must reject an M binding");
}

Project makeValidProject();

void testHmiAppearancePropertyBoundaries()
@@ -851,7 +812,6 @@ int main()
testRegisterAddressParsing();
testRegisterRepositorySeparatesAreas();
testHmiControlRegistryCompleteness();
testProgressBarConfigurationBoundaries();
testHmiAppearancePropertyBoundaries();
testLogicNodeConfigurationBoundaries();
testEdgeAndCommentBoundaries();


+ 2
- 37
app/tests/hmi_editor_service_tests.cpp Ver fichero

@@ -33,26 +33,13 @@ void testControlEditing()
const HmiEditorResult display = service.addControl(
page_id, HmiControlType::NumericDisplay);
const HmiEditorResult input = service.addControl(page_id, HmiControlType::NumericInput);
const HmiEditorResult progress = service.addControl(
page_id, HmiControlType::ProgressBar);
require(button.succeeded && indicator.succeeded && display.succeeded
&& input.succeeded && progress.succeeded,
&& input.succeeded,
"basic HMI controls must be added");

const HmiPage *page = service.findPage(page_id);
require(page != nullptr && page->controls.size() == 5,
require(page != nullptr && page->controls.size() == 4,
"all added controls must be kept in the page model");
const HmiControl *progress_control = service.findControl(page_id, progress.id);
require(progress_control != nullptr
&& progress_control->id == "progress-bar-1"
&& progress_control->text == "进度"
&& progress_control->bounds.width == 240
&& progress_control->bounds.height == 36
&& progress_control->progressBar.has_value()
&& progress_control->progressBar->minimumValue == 0
&& progress_control->progressBar->maximumValue == 100
&& progress_control->progressBar->showValue,
"new progress bars must use the registered defaults");
require(service.moveControl(page_id, button.id, {120, 80, 120, 40}).succeeded,
"a valid control move must succeed");
require(!service.moveControl(page_id, button.id, {790, 460, 120, 40}).succeeded,
@@ -77,20 +64,6 @@ void testControlEditing()
"deleting a selected control must succeed");
require(service.findControl(page_id, indicator.id) == nullptr,
"deleted controls must not remain in the model");

HmiControl configured_progress = *service.findControl(page_id, progress.id);
configured_progress.binding = RegisterAddress{RegisterArea::D, 8};
configured_progress.progressBar->minimumValue = -10;
configured_progress.progressBar->maximumValue = 90;
require(service.updateControl(page_id, progress.id, configured_progress).succeeded,
"a progress bar must accept a valid D binding and value range");
configured_progress.progressBar->maximumValue = -10;
require(!service.updateControl(page_id, progress.id, configured_progress).succeeded,
"a progress bar must reject a non-increasing value range");
configured_progress.progressBar->maximumValue = 90;
configured_progress.binding = RegisterAddress{RegisterArea::M, 8};
require(!service.updateControl(page_id, progress.id, configured_progress).succeeded,
"a progress bar must reject an M binding");
}

void testRuntimeUsesRegisterRepository()
@@ -159,14 +132,6 @@ void testRuntimeUsesRegisterRepository()
require(numeric_value.succeeded && numeric_value.word_value == -18,
"numeric display must read D values through the repository");

HmiControl progress;
progress.id = "progress";
progress.type = HmiControlType::ProgressBar;
progress.binding = RegisterAddress{RegisterArea::D, 9};
progress.progressBar = HmiProgressBarConfig{-20, 80, true};
const HmiRuntimeReadResult progress_value = runtime_service.readControl(progress);
require(progress_value.succeeded && progress_value.word_value == -18,
"progress bars must read D values through the repository");
}

void testHistoryAndAtomicBatchDelete()


+ 17
- 42
app/tests/project_management_tests.cpp Ver fichero

@@ -81,14 +81,6 @@ Project makeExampleProject()
alarm_list.bounds = {10, 200, 360, 180};
alarm_list.text = "Alarms";

HmiControl progress_bar;
progress_bar.id = "progress-bar";
progress_bar.type = HmiControlType::ProgressBar;
progress_bar.bounds = {400, 20, 240, 36};
progress_bar.text = "Completion";
progress_bar.binding = RegisterAddress{RegisterArea::D, 4};
progress_bar.progressBar = HmiProgressBarConfig{-20, 80, true};

HmiPage page;
page.id = "main-page";
page.name = "Main";
@@ -99,7 +91,6 @@ Project makeExampleProject()
page.controls.push_back(title_label);
page.controls.push_back(settings_jump);
page.controls.push_back(alarm_list);
page.controls.push_back(progress_bar);

HmiPage settings_page;
settings_page.id = "settings-page";
@@ -435,10 +426,10 @@ void testExampleProjectRoundTrip()
const QString first_path = directory.filePath("example.json");
const QString second_path = directory.filePath("example-copy.json");
const QString invalid_operation_path = directory.filePath("invalid-operation.json");
const QString unsupported_hmi_type_path = directory.filePath(
"unsupported-hmi-type.json");
const QString missing_initial_path = directory.filePath("missing-initial.json");
const QString missing_target_path = directory.filePath("missing-target.json");
const QString missing_progress_range_path = directory.filePath(
"missing-progress-range.json");
const QString missing_alarms_path = directory.filePath("missing-alarms.json");
const QString missing_register_comments_path = directory.filePath(
"missing-register-comments.json");
@@ -471,11 +462,7 @@ void testExampleProjectRoundTrip()
&& saved_json.contains("\"operation\": \"add\"")
&& saved_json.contains("\"operation\": \"subtract\"")
&& saved_json.contains("\"comment\": \"启动条件与温度检查\"")
&& saved_json.contains("\"type\": \"alarmList\"")
&& saved_json.contains("\"type\": \"progressBar\"")
&& saved_json.contains("\"minimumValue\": -20")
&& saved_json.contains("\"maximumValue\": 80")
&& saved_json.contains("\"showValue\": true"),
&& saved_json.contains("\"type\": \"alarmList\""),
"version 1.0 projects must persist pages and alarm definitions");
require(!saved_json.contains("\"stages\"")
&& !saved_json.contains("\"branches\""),
@@ -491,8 +478,8 @@ void testExampleProjectRoundTrip()
require(project.hmiPages.size() == 2, "HMI page count must survive round trip");
require(project.initialHmiPageId == "main-page",
"the initial HMI page id must survive round trip");
require(project.hmiPages.front().controls.size() == 8,
"register, navigation, AlarmList and ProgressBar controls must survive round trip");
require(project.hmiPages.front().controls.size() == 7,
"register, navigation and AlarmList controls must survive round trip");
require(project.hmiPages.front().controls.front().binding->area()
== RegisterArea::M,
"HMI M binding must survive round trip");
@@ -523,13 +510,6 @@ void testExampleProjectRoundTrip()
require(project.hmiPages.front().controls.at(6).type
== HmiControlType::AlarmList,
"AlarmList control type must survive round trip");
require(project.hmiPages.front().controls.at(7).type
== HmiControlType::ProgressBar
&& project.hmiPages.front().controls.at(7).progressBar.has_value()
&& project.hmiPages.front().controls.at(7).progressBar->minimumValue == -20
&& project.hmiPages.front().controls.at(7).progressBar->maximumValue == 80
&& project.hmiPages.front().controls.at(7).progressBar->showValue,
"ProgressBar configuration must survive round trip");
require(project.alarmDefinitions.size() == 2
&& project.alarmDefinitions.front().condition
== AlarmCondition::MOn
@@ -601,6 +581,18 @@ void testExampleProjectRoundTrip()
require(!service.load(invalid_operation_path.toStdString()).succeeded,
"unsupported HMI button operations must be rejected");

QByteArray unsupported_hmi_type = saved_json;
unsupported_hmi_type.replace(
"\"type\": \"alarmList\"",
"\"type\": \"removedControl\"");
writeText(unsupported_hmi_type_path, unsupported_hmi_type);
const ProjectOperationResult unsupported_type_result = service.load(
unsupported_hmi_type_path.toStdString());
require(!unsupported_type_result.succeeded
&& unsupported_type_result.storageError
== ProjectStorageError::InvalidField,
"removed HMI control types must be rejected during strict loading");

QJsonObject missing_initial = QJsonDocument::fromJson(saved_json).object();
missing_initial.remove(QStringLiteral("initialHmiPageId"));
writeText(
@@ -704,23 +696,6 @@ void testExampleProjectRoundTrip()
&& missing_result.storageError == ProjectStorageError::MissingField,
"the 1.0 schema must require PageJump targetPageId");

QJsonObject missing_progress_range = QJsonDocument::fromJson(saved_json).object();
pages = missing_progress_range.value(QStringLiteral("hmiPages")).toArray();
main_page = pages.at(0).toObject();
controls = main_page.value(QStringLiteral("controls")).toArray();
QJsonObject progress = controls.at(7).toObject();
progress.remove(QStringLiteral("maximumValue"));
controls.replace(7, progress);
main_page.insert(QStringLiteral("controls"), controls);
pages.replace(0, main_page);
missing_progress_range.insert(QStringLiteral("hmiPages"), pages);
writeText(
missing_progress_range_path,
QJsonDocument(missing_progress_range).toJson(QJsonDocument::Compact));
missing_result = service.load(missing_progress_range_path.toStdString());
require(!missing_result.succeeded
&& missing_result.storageError == ProjectStorageError::MissingField,
"the 1.0 schema must require the ProgressBar value range");
}

void testInvalidFiles()


Cargando…
Cancelar
Guardar