45 return ((
category(aType) & (ui_element_type::Widget | ui_element_type::Layout)) != ui_element_type::Invalid);
62 struct element_not_found : std::runtime_error { element_not_found(std::string
const& aElement) :
std::runtime_error{
"Element '" + aElement +
"' not found." } {} };
63 struct element_ill_formed : std::runtime_error { element_ill_formed(std::string
const& aElement) :
std::runtime_error{
"Element '" + aElement +
"' ill-formed." } {} };
64 struct unsupported_member_element : std::runtime_error { unsupported_member_element() :
std::runtime_error{
"Unsupported member element." } {} };
65 struct unknown_data_type : std::runtime_error { unknown_data_type() :
std::runtime_error{
"Unknown data type." } {} };
70 typedef i_ui_element abstract_type;
72 typedef i_ui_element_parser::data_t data_t;
73 typedef i_ui_element_parser::array_data_t array_data_t;
75 struct no_parent : std::logic_error { no_parent() :
std::logic_error{
"neogfx::nrc::i_ui_element::no_parent" } {} };
76 struct wrong_type : std::logic_error { wrong_type() :
std::logic_error{
"neogfx::nrc::i_ui_element::wrong_type" } {} };
78 virtual ~i_ui_element() =
default;
80 virtual const i_ui_element_parser& parser()
const = 0;
88 virtual bool is_member_element()
const = 0;
89 virtual bool anonymous()
const = 0;
92 virtual void generate_anonymous_id(
neolib::i_string& aNewAnonymousId)
const = 0;
95 virtual const i_ui_element& fragment()
const = 0;
96 virtual i_ui_element& fragment() = 0;
97 virtual bool has_parent()
const = 0;
98 virtual const i_ui_element& parent()
const = 0;
99 virtual i_ui_element& parent() = 0;
100 virtual const children_t& children()
const = 0;
101 virtual children_t& children() = 0;
104 virtual void parse(
const neolib::i_string& aType,
const array_data_t& aData) = 0;
107 virtual const neolib::i_string& generate_ctor_params(
bool aParamsAfter =
false)
const = 0;
108 virtual const neolib::i_string& generate_base_ctor_args(
bool aArgsAfter =
false)
const = 0;
109 virtual void emit()
const = 0;
110 virtual void emit_preamble()
const = 0;
111 virtual void emit_ctor()
const = 0;
112 virtual void emit_body()
const = 0;
114 virtual void instantiate(i_app& aApp) = 0;
115 virtual void instantiate(i_widget& aWidget) = 0;
116 virtual void instantiate(i_layout& aLayout) = 0;
121 generate_anonymous_id(newAnonymousId);
122 return newAnonymousId;
126 if (!anonymous() &&
id() == aId)
129 return parent().ancestor(aId);
134 return const_cast<i_ui_element&
>(
to_const(*this).ancestor(aId));
139 auto part = fullRef.find_first_of(
'.');
140 auto ref = fullRef.substr(0, part);
142 if (!resolved || (part == std::string::npos && resolved->fragment_name() != fragment_name()))
146 template <
typename T>
147 T get_enum(
const data_t& aData)
const
151 template <
typename T>
152 T get_enum(
const array_data_t& aArrayData)
const
155 return get_enum<T>(aArrayData, ignore);
157 template <
typename T>
158 T get_enum(
const array_data_t& aArrayData,
bool& aUseDefault,
const std::optional<std::string>& aDefault = {})
const
163 for (
auto const& a : aArrayData)
166 if (aDefault && e == aDefault)
174 result =
static_cast<T
>(
static_cast<std::underlying_type_t<T>
>(result) |
static_cast<std::underlying_type_t<T>
>(
neolib::string_to_enum<T>(e)));
180 template <
typename T>
181 static T ffs1(
auto&& v)
183 return T{
static_cast<typename T::value_type
>(v) };
185 template <
typename T>
186 static T ffs2(
auto&& v)
188 return T::from_string(v);
191 template <
typename T>
192 T get_scalar(
const data_t& aData)
const
197 typedef std::decay_t<
decltype(v)> vt;
198 bool constexpr sourceIsBool = std::is_same_v<vt, bool>;
199 bool constexpr destIsBool = std::is_same_v<T, bool>;
200 bool constexpr sourceIsArithmetic = std::is_arithmetic_v<vt> && !sourceIsBool;
201 bool constexpr destIsArithmetic = std::is_arithmetic_v<T> && !destIsBool;
202 if constexpr (sourceIsArithmetic && destIsArithmetic)
203 result =
static_cast<T
>(v);
204 else if constexpr (sourceIsBool && destIsBool)
207 else if constexpr (std::is_class_v<T> && sourceIsArithmetic)
208 result = T{
static_cast<typename T::value_type
>(v) };
209 else if constexpr (std::is_class_v<T> && std::is_same_v<vt, neolib::i_string>)
210 result = T::from_string(v.to_std_string());
212 else if constexpr (std::is_class_v<T> && sourceIsArithmetic)
214 else if constexpr (std::is_class_v<T> && std::is_same_v<vt, neolib::i_string>)
215 result = ffs2<T>(v.to_std_string());
222 template <
typename T>
223 std::vector<T> get_scalars(
const array_data_t& aArrayData)
const
225 std::vector<T> result;
226 for (
auto const& e : aArrayData)
227 result.push_back(get_scalar<T>(e));
230 template <
typename T>
231 T get_scalar(std::string
const& aKey)
const
233 return get_scalar<T>(parser().get_data(aKey));
235 template <
typename T>
236 std::vector<T> get_scalars(std::string
const& aKey)
const
238 return get_scalars<T>(parser().get_array_data(aKey));
240 template <
typename T,
typename Target>
243 std::vector<T> scalars;
244 if (parser().data_exists(aKey))
245 scalars.push_back(get_scalar<T>(parser().get_data(aKey)));
246 else if (parser().array_data_exists(aKey))
247 scalars = get_scalars<T>(parser().get_array_data(aKey));
250 switch (scalars.size())
253 aTarget.emplace(scalars[0]);
256 aTarget.emplace(scalars[0], scalars[1]);
262 template <
typename T,
typename Target>
265 std::vector<T> scalars;
266 if (parser().data_exists(aKey))
267 scalars.push_back(get_scalar<T>(parser().get_data(aKey)));
268 else if (parser().array_data_exists(aKey))
269 scalars = get_scalars<T>(parser().get_array_data(aKey));
272 switch (scalars.size())
275 aTarget.emplace(scalars[0]);
278 aTarget.emplace(scalars[0], scalars[1]);
281 aTarget.emplace(scalars[0], scalars[1], scalars[2], scalars[3]);
287 color get_color(
const data_t& aData)
const
292 typedef std::decay_t<
decltype(v)> vt;
293 if constexpr (std::is_same_v<vt, int64_t>)
294 result = color{
static_cast<uint32_t
>(v) };
295 else if constexpr (std::is_same_v<vt, neolib::i_string>)
296 result = v.to_std_string();
302 color get_color(
const array_data_t& aArrayData)
const
304 if (aArrayData.size() == 3)
306 else if (aArrayData.size() == 4)
316 if (gradientDirection != std::nullopt)
318 gradient::color_stop_list stops;
320 auto interval = 1.0 / (aArrayData.size() - 2);
321 for (std::size_t i = 1; i < aArrayData.size(); ++i)
322 stops.push_back(gradient::color_stop{ (i - 1) * interval, get_color(aArrayData[i]) });
323 return gradient{ stops, *gradientDirection };
326 return get_color(aArrayData);
329 return get_color(aArrayData);
332 template <
typename Enum>
337 return aEnumName +
"::" + es;
339 return "static_cast<" + aEnumName +
">(" + es +
")";
341 template <
typename T>
342 static const T& convert_emit_argument(
const T& aArgument)
346 static std::string convert_emit_argument(
const bool& aArgument)
348 return aArgument ?
"true" :
"false";
353 for (
auto const ch : aArgument)
382 static std::string convert_emit_argument(
const neolib::string& aArgument)
384 return convert_emit_argument(
static_cast<const neolib::i_string&
>(aArgument));
386 static std::string convert_emit_argument(std::string
const& aArgument)
390 static std::string convert_emit_argument(
const length& aArgument)
392 return aArgument.to_string(
true);
394 static std::string convert_emit_argument(
const size_policy& aArgument)
397 aArgument.to_string(hp, vp);
399 return "size_constraint::" + hp;
401 return "size_constraint::" + hp +
", size_constraint::" + vp;
403 static std::string convert_emit_argument(
const color& aArgument)
405 std::ostringstream result;
406 result <<
"0x" << std::uppercase << std::hex << std::setfill(
'0') << std::setw(8) << aArgument.as_argb() <<
"u";
409 static std::string convert_emit_argument(
const gradient& aArgument)
411 std::ostringstream result;
413 result <<
"gradient::color_stop_list{ ";
414 for (
auto s = aArgument.color_stops().begin(); s != aArgument.color_stops().end(); ++s)
416 if (s != aArgument.color_stops().begin())
418 result <<
"gradient::color_stop{ " << s->first() <<
", color{ " << convert_emit_argument(sRGB_color{ s->second() }) <<
" } }";
420 result <<
" }, " << enum_to_string<gradient_direction>(
"gradient_direction", aArgument.direction());
std::string_view to_std_string_view() const noexcept
std::string to_std_string() const
#define end_declare_enum(enumName)
#define declare_enum_string(enumName, enumEnumerator)
#define begin_declare_enum(enumName)
constexpr bool is_widget_or_layout(ui_element_type aType)
object_type ui_element_type
const member_element_t member_element
constexpr object_type category(object_type aType)
basic_length< default_geometry_value_type > length
neolib::variant< color, gradient > color_or_gradient
std::string to_std_string(T const &aValue)
ref_ptr< ConcreteType > make_ref(Args &&... args)
to_const_reference_t< T > to_const(T &&object)
StringT enum_to_string(Enum aEnumerator, bool aMustEnumerate=false)
constexpr decltype(auto) visit(Visitor &&vis, neolib::variant< Types... > &&var)