You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ovdCBoxProxy.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "ovdCBoxProxy.h"
  2. #include "ovdTAttributeHandler.h"
  3. #include <fs/Files.h>
  4. namespace OpenViBE {
  5. namespace Designer {
  6. CBoxProxy::CBoxProxy(const Kernel::IKernelContext& ctx, Kernel::IScenario& scenario, const CIdentifier& boxID)
  7. : m_kernelCtx(ctx), m_constBox(scenario.getBoxDetails(boxID)), m_box(scenario.getBoxDetails(boxID)),
  8. m_isDeprecated(m_kernelCtx.getPluginManager().isPluginObjectFlaggedAsDeprecated(m_constBox->getAlgorithmClassIdentifier()))
  9. {
  10. m_isBoxAlgorithmPresent = false;
  11. if (m_constBox)
  12. {
  13. if (m_constBox->getAlgorithmClassIdentifier() == OVP_ClassId_BoxAlgorithm_Metabox)
  14. {
  15. CIdentifier metaboxId;
  16. metaboxId.fromString(m_constBox->getAttributeValue(OVP_AttributeId_Metabox_ID));
  17. const CString path(m_kernelCtx.getMetaboxManager().getMetaboxFilePath(metaboxId));
  18. m_isBoxAlgorithmPresent = FS::Files::fileExists(path.toASCIIString());
  19. }
  20. else { m_isBoxAlgorithmPresent = m_kernelCtx.getPluginManager().canCreatePluginObject(m_constBox->getAlgorithmClassIdentifier()); }
  21. const TAttributeHandler handler(*m_constBox);
  22. m_centerX = handler.getAttributeValue<int>(OV_AttributeId_Box_XCenterPosition);
  23. m_centerY = handler.getAttributeValue<int>(OV_AttributeId_Box_YCenterPosition);
  24. }
  25. m_showOriginalNameWhenModified = m_kernelCtx.getConfigurationManager().expandAsBoolean("${Designer_ShowOriginalBoxName}", true);
  26. }
  27. int CBoxProxy::getWidth(GtkWidget* widget) const
  28. {
  29. int x, y;
  30. updateSize(widget, getLabel(), getStatusLabel(), &x, &y);
  31. return x;
  32. }
  33. int CBoxProxy::getHeight(GtkWidget* widget) const
  34. {
  35. int x, y;
  36. updateSize(widget, getLabel(), getStatusLabel(), &x, &y);
  37. return y;
  38. }
  39. void CBoxProxy::setCenter(const int x, const int y)
  40. {
  41. m_centerX = x;
  42. m_centerY = y;
  43. m_applied = false;
  44. }
  45. void CBoxProxy::setBoxAlgorithmDescriptorOverride(const Plugins::IBoxAlgorithmDesc* pBoxAlgorithmDescriptor)
  46. {
  47. m_boxAlgorithmDescOverride = pBoxAlgorithmDescriptor;
  48. }
  49. void CBoxProxy::apply()
  50. {
  51. if (m_box)
  52. {
  53. TAttributeHandler handler(*m_box);
  54. if (handler.hasAttribute(OV_AttributeId_Box_XCenterPosition)) { handler.setAttributeValue<int>(OV_AttributeId_Box_XCenterPosition, m_centerX); }
  55. else { handler.addAttribute<int>(OV_AttributeId_Box_XCenterPosition, m_centerX); }
  56. if (handler.hasAttribute(OV_AttributeId_Box_YCenterPosition)) { handler.setAttributeValue<int>(OV_AttributeId_Box_YCenterPosition, m_centerY); }
  57. else { handler.addAttribute<int>(OV_AttributeId_Box_YCenterPosition, m_centerY); }
  58. m_applied = true;
  59. }
  60. }
  61. const char* CBoxProxy::getLabel() const
  62. {
  63. const bool canChangeInput(
  64. m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanModifyInput) || m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanAddInput));
  65. const bool canChangeOutput(
  66. m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanModifyOutput) || m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanAddOutput));
  67. const bool canChangeSetting(
  68. m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanModifySetting) || m_constBox->hasAttribute(OV_AttributeId_Box_FlagCanAddSetting));
  69. const Plugins::IPluginObjectDesc* desc = (m_boxAlgorithmDescOverride == nullptr
  70. ? m_kernelCtx.getPluginManager().getPluginObjectDescCreating(m_constBox->getAlgorithmClassIdentifier())
  71. : m_boxAlgorithmDescOverride);
  72. std::string name(m_constBox->getName());
  73. const std::string red("#602020"), green("#206020"), grey("#404040");
  74. // pango is used in the box diplay to format the box name (e.g. bold to tell it's a configurable box)
  75. // incidently, this makes the box name pango-enabled. If an error appears in the markup, the box display would be wrong.
  76. if (!pango_parse_markup(name.c_str(), -1, 0, nullptr, nullptr, nullptr, nullptr))
  77. {
  78. // the name uses invalid markup characters
  79. // we sanitize the markup tag overture '<'
  80. // markup should not be used in the box name anyway (hidden feature),
  81. // but the character '<' may actually be useful in a valid name
  82. for (size_t c = 0; c < name.size(); ++c)
  83. {
  84. if (name[c] == '<')
  85. {
  86. name[c] = ';';
  87. name.insert(c, "&lt");
  88. }
  89. else if (name[c] == '&')
  90. {
  91. name[c] = ';';
  92. name.insert(c, "&amp");
  93. }
  94. }
  95. }
  96. m_label = name;
  97. if (name.empty()) { m_label = "Unnamed Box"; }
  98. const std::string boxNameColor = "#000000";
  99. if (m_constBox->getSettingCount() != 0) { m_label = "<span color=\"" + boxNameColor + R"(" weight="bold">)" + m_label + "</span>"; }
  100. if (m_showOriginalNameWhenModified)
  101. {
  102. const std::string boxOriginalName(desc ? std::string(desc->getName()) : name);
  103. if (boxOriginalName != name) { m_label = "<small><i><span foreground=\"" + grey + "\">" + boxOriginalName + "</span></i></small>\n" + m_label; }
  104. }
  105. if (canChangeInput || canChangeOutput || canChangeSetting)
  106. {
  107. m_label += "\n<span size=\"smaller\">";
  108. m_label += "<span foreground=\"" + (canChangeInput ? green : red) + "\">In</span>";
  109. m_label += "|<span foreground=\"" + (canChangeOutput ? green : red) + "\">Out</span>";
  110. m_label += "|<span foreground=\"" + (canChangeSetting ? green : red) + "\">Set</span>";
  111. m_label += "</span>";
  112. }
  113. return m_label.c_str();
  114. }
  115. const char* CBoxProxy::getStatusLabel() const
  116. {
  117. const bool toBeUpdated(m_box->hasAttribute(OV_AttributeId_Box_ToBeUpdated));
  118. const bool pendingDeprecatedInterfacors(m_box->hasAttribute(OV_AttributeId_Box_PendingDeprecatedInterfacors));
  119. const bool isDeprecated(this->isBoxAlgorithmPluginPresent() && this->isDeprecated());
  120. const bool isDisabled(this->isDisabled());
  121. const std::string blue("#202060");
  122. m_status = "";
  123. if (isDeprecated || toBeUpdated || isDisabled || pendingDeprecatedInterfacors)
  124. {
  125. m_status += R"(<span size="smaller" foreground=")" + blue + "\">";
  126. if (isDeprecated) { m_status += " <span style=\"italic\">deprecated</span>"; }
  127. if (toBeUpdated) { m_status += " <span style=\"italic\">update</span>"; }
  128. if (isDisabled) { m_status += " <span style=\"italic\">disabled</span>"; }
  129. if (pendingDeprecatedInterfacors) { m_status += " <span style=\"italic\">deprecated I/O/S</span>"; }
  130. m_status += " </span>";
  131. }
  132. return m_status.c_str();
  133. }
  134. bool CBoxProxy::isDisabled() const
  135. {
  136. const TAttributeHandler handler(*m_constBox);
  137. return handler.hasAttribute(OV_AttributeId_Box_Disabled);
  138. }
  139. void CBoxProxy::updateSize(GtkWidget* widget, const char* label, const char* status, int* xSize, int* ySize) const
  140. {
  141. PangoRectangle labelRect;
  142. PangoRectangle statusRect;
  143. PangoContext* context = gtk_widget_create_pango_context(widget);
  144. PangoLayout* layout = pango_layout_new(context);
  145. pango_layout_set_markup(layout, label, -1);
  146. pango_layout_get_pixel_extents(layout, nullptr, &labelRect);
  147. pango_layout_set_markup(layout, status, -1);
  148. pango_layout_get_pixel_extents(layout, nullptr, &statusRect);
  149. if (!strlen(status))
  150. {
  151. statusRect.width = 0;
  152. statusRect.height = 0;
  153. }
  154. *xSize = std::max(labelRect.width, statusRect.width);
  155. *ySize = labelRect.height + statusRect.height;
  156. g_object_unref(layout);
  157. g_object_unref(context);
  158. }
  159. } // namespace Designer
  160. } // namespace OpenViBE