PropertyDefinition.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "../../Include/RmlUi/Core/PropertyDefinition.h"
  2. #include "../../Include/RmlUi/Core/Log.h"
  3. #include "../../Include/RmlUi/Core/StyleSheetSpecification.h"
  4. namespace Rml {
  5. PropertyDefinition::PropertyDefinition(PropertyId id, const String& _default_value, bool _inherited, bool _forces_layout) :
  6. id(id), default_value(_default_value, Unit::UNKNOWN), relative_target(RelativeTarget::None)
  7. {
  8. inherited = _inherited;
  9. forces_layout = _forces_layout;
  10. default_value.definition = this;
  11. }
  12. PropertyDefinition::~PropertyDefinition() {}
  13. PropertyDefinition& PropertyDefinition::AddParser(const String& parser_name, const String& parser_parameters)
  14. {
  15. ParserState new_parser;
  16. // Fetch the parser.
  17. new_parser.parser = StyleSheetSpecification::GetParser(parser_name);
  18. if (new_parser.parser == nullptr)
  19. {
  20. Log::Message(Log::LT_ERROR, "Property was registered with invalid parser '%s'.", parser_name.c_str());
  21. return *this;
  22. }
  23. // Split the parameter list, and set up the map.
  24. if (!parser_parameters.empty())
  25. {
  26. StringList parameter_list;
  27. StringUtilities::ExpandString(parameter_list, parser_parameters);
  28. int parameter_value = 0;
  29. for (const String& parameter : parameter_list)
  30. {
  31. // Look for an optional parameter value such as in "normal=400".
  32. const size_t i_equal = parameter.find('=');
  33. if (i_equal != String::npos)
  34. {
  35. if (!TypeConverter<String, int>::Convert(parameter.substr(i_equal + 1), parameter_value))
  36. {
  37. Log::Message(Log::LT_ERROR, "Parser was added with invalid parameter '%s'.", parameter.c_str());
  38. return *this;
  39. }
  40. }
  41. new_parser.parameters[parameter.substr(0, i_equal)] = parameter_value;
  42. parameter_value += 1;
  43. }
  44. }
  45. const int parser_index = (int)parsers.size();
  46. parsers.push_back(new_parser);
  47. // If the default value has not been parsed successfully yet, run it through the new parser.
  48. if (default_value.unit == Unit::UNKNOWN)
  49. {
  50. String unparsed_value = default_value.value.Get<String>();
  51. if (new_parser.parser->ParseValue(default_value, unparsed_value, new_parser.parameters))
  52. {
  53. default_value.parser_index = parser_index;
  54. }
  55. else
  56. {
  57. default_value.value = unparsed_value;
  58. default_value.unit = Unit::UNKNOWN;
  59. }
  60. }
  61. return *this;
  62. }
  63. bool PropertyDefinition::ParseValue(Property& property, const String& value) const
  64. {
  65. for (size_t i = 0; i < parsers.size(); i++)
  66. {
  67. if (parsers[i].parser->ParseValue(property, value, parsers[i].parameters))
  68. {
  69. property.definition = this;
  70. property.parser_index = (int)i;
  71. return true;
  72. }
  73. }
  74. property.unit = Unit::UNKNOWN;
  75. return false;
  76. }
  77. bool PropertyDefinition::GetValue(String& value, const Property& property) const
  78. {
  79. value = property.value.Get<String>();
  80. switch (property.unit)
  81. {
  82. case Unit::KEYWORD:
  83. {
  84. int parser_index = property.parser_index;
  85. if (parser_index < 0 || parser_index >= (int)parsers.size())
  86. {
  87. // Look for the keyword parser in the property's list of parsers
  88. const auto* keyword_parser = StyleSheetSpecification::GetParser("keyword");
  89. for (int i = 0; i < (int)parsers.size(); i++)
  90. {
  91. if (parsers[i].parser == keyword_parser)
  92. {
  93. parser_index = i;
  94. break;
  95. }
  96. }
  97. // If we couldn't find it, exit now
  98. if (parser_index < 0 || parser_index >= (int)parsers.size())
  99. return false;
  100. }
  101. int keyword = property.value.Get<int>();
  102. for (const auto& name_keyword : parsers[parser_index].parameters)
  103. {
  104. if (name_keyword.second == keyword)
  105. {
  106. value = name_keyword.first;
  107. break;
  108. }
  109. }
  110. return false;
  111. }
  112. break;
  113. default: value += ToString(property.unit); break;
  114. }
  115. return true;
  116. }
  117. bool PropertyDefinition::IsInherited() const
  118. {
  119. return inherited;
  120. }
  121. bool PropertyDefinition::IsLayoutForced() const
  122. {
  123. return forces_layout;
  124. }
  125. const Property* PropertyDefinition::GetDefaultValue() const
  126. {
  127. return &default_value;
  128. }
  129. RelativeTarget PropertyDefinition::GetRelativeTarget() const
  130. {
  131. return relative_target;
  132. }
  133. PropertyId PropertyDefinition::GetId() const
  134. {
  135. return id;
  136. }
  137. PropertyDefinition& PropertyDefinition::SetRelativeTarget(RelativeTarget relative_target)
  138. {
  139. this->relative_target = relative_target;
  140. return *this;
  141. }
  142. } // namespace Rml