In order to start stabilizing the text interface I've been asking for feedback and reviewing all of the interfaces again myself. As part of this work, I realised just how much more complex things are because of the interfaces for setting text style, rather than strings.
So essentially what I'm proposing is removing the attribute factory and going back to functions on the textblock to add an attribute from string.
A bit of background
Textblock has always used strings for both style and formats (and then attributes). Sometime in the last year interfaces were added to set the font_size, font_weight and etc through code. I kept these because I thought the concept was nice and it would make things easier. In retrospect, this was a mistake. It actually makes things much harder and more complex.
Comparison of Interfaces vs Strings for manipulating formats.
Here are the pros and cons of using the interfaces vs using the strings. These are all the ones I managed to come up with, please let me know if you think I missed anything.
IMPORTANT: I think the main thing is that most people will use *markup* rather than any of these functions to manipulate text style anyway, so given that this is such a niche behaviour, I don't see the point adding all of this complexity.
With the factory method, we will have code completion for the allowed style functions, so it would be easier for developers to discover what functions are allowed and their allowed values.
Find errors at compile time
Because the compiler will be making the validation, we will find errors sooner. In the string case we will only have runtime error checking.
Much much more complex
To support this we need to add two new interfaces (Style and Font properties) with a lot of properties on them, and will need to implement them all.
We also need to implement gradual implementation of style properties rather than all at once.
So for example, with the interfaces it would be:
efl_text_attribute_factory_clear() efl_text_font_family_set(factory, "Sans") efl_text_font_size_set(factory, 12) efl_text_style_background_color_set(factory, color) efl_text_attribute_factory_insert(cur1, cur2, factory)
And the factory will have to understand and implement internally setting them one by one (which is more costly), while the string case will only have:
efl_canvas_text_attribute_insert(cur1, cur2, "font_family=Sans font_size=12, background_color=color")
And requires no special handling for partial setting, because the string is only parsed once for each attribute.
It also necessitates implementing a much more involved way of parsing markup, because the parser would need to parse attributes on its own and translate to these calls, rather than just passing the attribute string as is.
Because we set the style from the theme anyway, we need to have parsing of format styles from string *anyway*. So we end up having it both in the markup class, and in the theme loader in addition to the functions. Instead of just having the style string parser once in the text object.
Can't all of a sudden add a unit to size, or more values to a boolean.
So for example, if we want to add a way to sent the font size as a multiple of the current font size, to implement a tag such as <small> which just makes the text 80% the size of the enclosing tag, you can't. You'd need to add a new function called efl_text_font_size_factor_set because the original doesn't accept a unit, and even if it did, it accepts an int and not a double.
Another example is that HTML supports 3 special values for each property: inherit, initial and unset. We can't sanely support anything like them with the interface based API.
In summary, I'm suggesting going back to how Textblock used to be when it comes to styles. The pros massively outweigh the cons. Am I wrong? Would love to hear. Thanks!