aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/ui/mapper/Mapper.h39
-rw-r--r--src/ui/mapper/ColorMapper.cpp10
-rw-r--r--src/ui/mapper/CursorMapper.cpp6
-rw-r--r--src/ui/mapper/MeasureLengthMapper.cpp4
-rw-r--r--src/ui/mapper/PointMapper.cpp4
-rw-r--r--src/ui/mapper/SizeMapper.cpp6
-rw-r--r--src/ui/mapper/StringMapper.cpp4
-rw-r--r--src/ui/mapper/ThicknessMapper.cpp4
8 files changed, 43 insertions, 34 deletions
diff --git a/include/cru/ui/mapper/Mapper.h b/include/cru/ui/mapper/Mapper.h
index 68ad2ab0..e9e7b851 100644
--- a/include/cru/ui/mapper/Mapper.h
+++ b/include/cru/ui/mapper/Mapper.h
@@ -6,7 +6,7 @@
#include <cru/base/xml/XmlNode.h>
#include <memory>
-#include <type_traits>
+#include <optional>
#include <typeindex>
namespace cru::ui::mapper {
@@ -35,12 +35,9 @@ class CRU_UI_API MapperBase : public Object {
template <typename T>
class CRU_UI_API BasicMapper : public MapperBase {
public:
- static_assert(std::is_default_constructible_v<T>,
- "T must be default constructible.");
-
BasicMapper() : MapperBase(typeid(T)) {}
- virtual T MapFromString(std::string str) {
+ T MapFromString(std::string str) {
if (!SupportMapFromString()) {
throw Exception("This mapper does not support map from string.");
}
@@ -61,8 +58,36 @@ class CRU_UI_API BasicMapper : public MapperBase {
}
protected:
- virtual T DoMapFromString(std::string str) { return {}; }
- virtual T DoMapFromXml(xml::XmlElementNode* node) { return {}; }
+ virtual T DoMapFromString(std::string str) { NotImplemented(); }
+ virtual T DoMapFromXml(xml::XmlElementNode* node) { NotImplemented(); }
+
+ T MapFromXmlAsStringValue(xml::XmlElementNode* node,
+ std::optional<T> default_value = std::nullopt) {
+ std::optional<T>& value = default_value;
+
+ auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
+ if (value_attr) {
+ value = DoMapFromString(*value_attr);
+ }
+
+ for (auto child : node->GetChildren()) {
+ if (child->IsElementNode()) {
+ throw MapException("XML node can't contain element child.");
+ } else if (auto c = child->AsText()) {
+ auto text = c->GetText();
+ if (!text.empty() && value.has_value()) {
+ throw MapException("XML node has multiple values specified.");
+ }
+ value = DoMapFromString(text);
+ }
+ }
+
+ if (!value.has_value()) {
+ throw MapException("XML node has no value specified.");
+ }
+
+ return *value;
+ }
};
template <typename T>
diff --git a/src/ui/mapper/ColorMapper.cpp b/src/ui/mapper/ColorMapper.cpp
index 9283b828..0fd0731b 100644
--- a/src/ui/mapper/ColorMapper.cpp
+++ b/src/ui/mapper/ColorMapper.cpp
@@ -11,19 +11,15 @@ Color ColorMapper::DoMapFromString(std::string str) {
}
Color ColorMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- Color result = colors::transparent;
- if (value_attr) {
- result = DoMapFromString(*value_attr);
- }
+ auto value = MapFromXmlAsStringValue(node, colors::transparent);
auto alpha_value_attr =
node->GetOptionalAttributeValueCaseInsensitive("alpha");
if (alpha_value_attr) {
- result.alpha =
+ value.alpha =
cru::string::ParseToNumber<double>(*alpha_value_attr).value * 255;
}
- return result;
+ return value;
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/CursorMapper.cpp b/src/ui/mapper/CursorMapper.cpp
index c7a8d4fc..00b94b91 100644
--- a/src/ui/mapper/CursorMapper.cpp
+++ b/src/ui/mapper/CursorMapper.cpp
@@ -19,13 +19,11 @@ std::shared_ptr<ICursor> CursorMapper::DoMapFromString(std::string str) {
} else if (cru::string::CaseInsensitiveCompare(str, "ibeam") == 0) {
return cursor_manager->GetSystemCursor(SystemCursorType::IBeam);
} else {
- throw Exception("Unsupported cursor type.");
+ throw MapException("Unknown cursor name.");
}
}
std::shared_ptr<ICursor> CursorMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (!value_attr) return nullptr;
- return DoMapFromString(*value_attr);
+ return MapFromXmlAsStringValue(node, nullptr);
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/MeasureLengthMapper.cpp b/src/ui/mapper/MeasureLengthMapper.cpp
index b695ebae..f35e65d2 100644
--- a/src/ui/mapper/MeasureLengthMapper.cpp
+++ b/src/ui/mapper/MeasureLengthMapper.cpp
@@ -19,8 +19,6 @@ render::MeasureLength MeasureLengthMapper::DoMapFromString(std::string str) {
render::MeasureLength MeasureLengthMapper::DoMapFromXml(
xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (!value_attr) return {};
- return DoMapFromString(*value_attr);
+ return MapFromXmlAsStringValue(node, render::MeasureLength::NotSpecified());
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/PointMapper.cpp b/src/ui/mapper/PointMapper.cpp
index 3bfe03e2..5311522a 100644
--- a/src/ui/mapper/PointMapper.cpp
+++ b/src/ui/mapper/PointMapper.cpp
@@ -14,8 +14,6 @@ Point PointMapper::DoMapFromString(std::string str) {
}
Point PointMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (!value_attr) return {};
- return DoMapFromString(*value_attr);
+ return MapFromXmlAsStringValue(node, Point{});
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/SizeMapper.cpp b/src/ui/mapper/SizeMapper.cpp
index 6161f226..fdf54324 100644
--- a/src/ui/mapper/SizeMapper.cpp
+++ b/src/ui/mapper/SizeMapper.cpp
@@ -9,13 +9,11 @@ Size SizeMapper::DoMapFromString(std::string str) {
} else if (values.size() == 1) {
return {values[0], values[0]};
} else {
- throw Exception("Invalid Point string.");
+ throw Exception("Invalid Size string.");
}
}
Size SizeMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (!value_attr) return {};
- return DoMapFromString(*value_attr);
+ return MapFromXmlAsStringValue(node, Size{});
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/StringMapper.cpp b/src/ui/mapper/StringMapper.cpp
index a021de3a..193dc464 100644
--- a/src/ui/mapper/StringMapper.cpp
+++ b/src/ui/mapper/StringMapper.cpp
@@ -7,8 +7,6 @@ std::string StringMapper::DoMapFromString(std::string str) {
}
std::string StringMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (value_attr) return *value_attr;
- return {};
+ return MapFromXmlAsStringValue(node, "");
}
} // namespace cru::ui::mapper
diff --git a/src/ui/mapper/ThicknessMapper.cpp b/src/ui/mapper/ThicknessMapper.cpp
index ca062ddc..89bb2d98 100644
--- a/src/ui/mapper/ThicknessMapper.cpp
+++ b/src/ui/mapper/ThicknessMapper.cpp
@@ -18,8 +18,6 @@ Thickness ThicknessMapper::DoMapFromString(std::string str) {
}
Thickness ThicknessMapper::DoMapFromXml(xml::XmlElementNode* node) {
- auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
- if (!value_attr) throw Exception("Thickness must have a 'value' attribute.");
- return DoMapFromString(*value_attr);
+ return MapFromXmlAsStringValue(node, Thickness{});
}
} // namespace cru::ui::mapper