综合平台编程器项目的远程存储
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

173 linhas
4.6 KiB

  1. /**
  2. * @file hmi_model.h
  3. * @brief 定义可保存的 HMI 页面、控件和寄存器绑定模型
  4. * @author suyu
  5. * @date 2026-08-10
  6. */
  7. #pragma once
  8. #include "register_address.h"
  9. #include "register_value_type.h"
  10. #include "project_limits.h"
  11. #include <map>
  12. #include <optional>
  13. #include <string>
  14. #include <variant>
  15. #include <vector>
  16. namespace HmiAppearanceProperty
  17. {
  18. inline constexpr const char kTextColor[] = "textColor";
  19. inline constexpr const char kFontSize[] = "fontSize";
  20. inline constexpr const char kFontBold[] = "fontBold";
  21. inline constexpr const char kFontItalic[] = "fontItalic";
  22. } // namespace HmiAppearanceProperty
  23. /**
  24. * @brief 描述 HMI 控件在页面坐标系中的位置和尺寸
  25. *
  26. * 页面校验要求矩形的左上角非负且完整位于页面范围内
  27. */
  28. struct HmiRect
  29. {
  30. static constexpr int kDefaultWidth = 80;
  31. static constexpr int kDefaultHeight = 32;
  32. int x = 0;
  33. int y = 0;
  34. int width = kDefaultWidth;
  35. int height = kDefaultHeight;
  36. };
  37. /**
  38. * @brief HMI 控件的基础类型
  39. *
  40. * 按钮和指示灯只能绑定 M 位,数值控件只能绑定 D 字
  41. */
  42. enum class HmiControlType
  43. {
  44. Button, // 按钮
  45. Indicator, // 指示灯
  46. NumericDisplay, // 数值显示
  47. NumericInput, // 数值输入
  48. Label, // 标签
  49. StatusText, // 状态文本
  50. PageJump, // 页面跳转
  51. AlarmList, // 报警列表
  52. Count // 已注册控件类型数量,不作为实际控件使用
  53. };
  54. /**
  55. * @brief 按钮对绑定 M 位执行的操作
  56. */
  57. enum class HmiButtonOperation
  58. {
  59. SetOn, // 按下时写入 1
  60. SetOff, // 按下时写入 0
  61. Toggle, // 按下时写入当前读回值的反值
  62. MomentaryOn // 按下时写入 1,释放时写入 0
  63. };
  64. struct HmiPageJumpConfig
  65. {
  66. std::string targetPageId;
  67. };
  68. struct HmiStatusBitTextConfig
  69. {
  70. std::string offText;
  71. std::string onText;
  72. bool operator==(const HmiStatusBitTextConfig &other) const
  73. {
  74. return offText == other.offText && onText == other.onText;
  75. }
  76. };
  77. struct HmiStatusValueRange
  78. {
  79. std::optional<double> lowerBound;
  80. std::optional<double> upperBound;
  81. std::string text;
  82. bool operator==(const HmiStatusValueRange &other) const
  83. {
  84. return lowerBound == other.lowerBound
  85. && upperBound == other.upperBound
  86. && text == other.text;
  87. }
  88. };
  89. struct HmiStatusWordTextConfig
  90. {
  91. std::vector<HmiStatusValueRange> ranges;
  92. bool operator==(const HmiStatusWordTextConfig &other) const
  93. {
  94. return ranges == other.ranges;
  95. }
  96. };
  97. using HmiStatusTextConfig = std::variant<
  98. HmiStatusBitTextConfig,
  99. HmiStatusWordTextConfig>;
  100. /**
  101. * @brief 描述一个可保存的 HMI 控件及其显示和寄存器配置
  102. *
  103. * `properties` 保存未纳入公共字段的字符串扩展属性
  104. */
  105. struct HmiControl
  106. {
  107. std::string id;
  108. HmiControlType type = HmiControlType::Label;
  109. HmiRect bounds;
  110. std::string text;
  111. std::optional<RegisterAddress> binding;
  112. RegisterDataType dataType = RegisterDataType::Int16;
  113. std::map<std::string, std::string> properties;
  114. HmiButtonOperation buttonOperation = HmiButtonOperation::MomentaryOn;
  115. std::optional<HmiPageJumpConfig> pageJump;
  116. std::optional<HmiStatusTextConfig> statusText;
  117. /**
  118. * @brief 校验控件的标识、尺寸、扩展属性和寄存器绑定
  119. * @param error 可选错误输出,失败时写入首个校验原因
  120. * @return 配置完整且满足控件类型绑定规则时返回 true
  121. *
  122. * 位控件必须绑定有效 M 地址,字控件必须绑定有效 D 地址
  123. */
  124. bool validate(std::string *error = nullptr) const;
  125. bool isConfigured() const;
  126. };
  127. /**
  128. * @brief 描述一个 HMI 页面及其控件集合
  129. *
  130. * 控件标识在同一页面内必须唯一,所有控件必须完整位于页面边界内
  131. */
  132. struct HmiPage
  133. {
  134. std::string id;
  135. std::string name;
  136. int width = ProjectLimits::kDefaultHmiPageWidth;
  137. int height = ProjectLimits::kDefaultHmiPageHeight;
  138. std::vector<HmiControl> controls;
  139. /**
  140. * @brief 校验页面尺寸、控件标识唯一性和全部控件配置
  141. * @param error 可选错误输出,失败时写入首个校验原因
  142. * @return 页面及其全部控件有效时返回 true
  143. */
  144. bool validate(
  145. const ProjectLimitSettings &limits,
  146. std::string *error = nullptr) const;
  147. bool validateForRunning(
  148. const ProjectLimitSettings &limits,
  149. std::string *error = nullptr) const;
  150. };