I was using the SFML just now and attempting to center a sf::Text object at the top of the screen, which was accomplished with the following:
text.setString("SFML");
text.setOrigin(text.getLocalBounds().width / 2, text.getLocalBounds().height / 2);
text.setPosition(WindowWidth / 2, WindowHeight / 10);
This was simple enough, but it's not very good if my text happens to change size, as the origin is no longer relevant for its intended purposes.
This left me wondering is why SFML's sf::Transformable objects do not have something along the lines of a setAnchor() method, which would be able to set a relative point instead of an absolute for object manipulations. This way, users would be able to accomplish cleaner code that works for something like this:
// Anchor the text to it's center, then center the text.
// (0, 0) would be considered top-left, and (1, 1) bottom-right.
text.setString("SFML");
text.setAnchor(0.5, 0.5);
text.setPosition(WindowWidth / 2, WindowHeight / 10);
// The text's string changed, but the text is still centered at the top of the screen.
// In the first example, this would result in the text stretching off to the right.
text.setString("Hello, World!");
This method of manipulation is seen in other APIs such as Apple's SpriteKit. Would any of the authors know why this design decision was made, or if we could possible see features like this in the future?
Or possibly?
union m_Origin {
Vector2f absolute;
enum {
TopLeft,
TopCenter,
TopRight,
MidLeft,
...
} relative;
};
Breaking code before SFML 3 is not an option.
An anchor that would directly modify the origin is not a meaningful addition (see my link above for explanation). The only possible way I see is as follows:
class Transformable
{
public:
void setOrigin(Vector2f origin)
{
m_origin = origin;
m_useAnchor = false;
}
void setAnchor(Vector2f anchor)
{
m_origin = anchor;
m_useAnchor = true;
}
// everywhere else: case differentiations
private:
Vector2f m_origin;
bool m_useAnchor;
};
However, the API is going to be rather unintuitive if both origin (absolute) and anchor (relative) are coexisting attributes of sf::Transformable. It would introduce additional state and thus complexity, furthermore the case differentiations will come with decent overhead.
Might I suggest from a purely semantic point of view (ignoring whether or not the implementation is possible/good), that setAnchor() alongside setOrigin() makes it sound like setAnchor() is changing something that is not the origin. Even if in the implementation it does, the point that the object transforms around is its origin and the name setAnchor() would suggest to me that you are changing something other than the point around which the object transforms. Aside from this, it seems like a good idea. Personally, I'd suggest something like sf::Transformable::setRelativeOrigin()