feat: Complete position argument standardization for all UI classes

- Frame and Sprite now support pos keyword override
- Entity now accepts x,y arguments (was pos-only before)
- All UI classes now consistently support:
  - (x, y) positional
  - ((x, y)) tuple
  - x=x, y=y keywords
  - pos=(x,y) keyword
  - pos=Vector keyword
- Improves API consistency and flexibility
This commit is contained in:
John McCardle 2025-07-06 01:14:45 -04:00
commit 75f75d250f
3 changed files with 94 additions and 57 deletions

View file

@ -1,6 +1,7 @@
#include "UISprite.h"
#include "GameEngine.h"
#include "PyVector.h"
#include "PyPositionHelper.h"
UIDrawable* UISprite::click_at(sf::Vector2f point)
{
@ -297,34 +298,47 @@ PyObject* UISprite::repr(PyUISpriteObject* self)
int UISprite::init(PyUISpriteObject* self, PyObject* args, PyObject* kwds)
{
//std::cout << "Init called\n";
static const char* keywords[] = { "x", "y", "texture", "sprite_index", "scale", "click", nullptr };
static const char* keywords[] = { "x", "y", "texture", "sprite_index", "scale", "click", "pos", nullptr };
float x = 0.0f, y = 0.0f, scale = 1.0f;
int sprite_index = 0;
PyObject* texture = NULL;
PyObject* click_handler = NULL;
PyObject* pos_obj = NULL;
// First try to parse as (x, y, texture, ...)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ffOifO",
const_cast<char**>(keywords), &x, &y, &texture, &sprite_index, &scale, &click_handler))
// Try to parse all arguments with keywords
if (PyArg_ParseTupleAndKeywords(args, kwds, "|ffOifOO",
const_cast<char**>(keywords), &x, &y, &texture, &sprite_index, &scale, &click_handler, &pos_obj))
{
// If pos was provided, it overrides x,y
if (pos_obj && pos_obj != Py_None) {
PyVectorObject* vec = PyVector::from_arg(pos_obj);
if (!vec) {
PyErr_SetString(PyExc_TypeError, "pos must be a Vector or tuple (x, y)");
return -1;
}
x = vec->data.x;
y = vec->data.y;
}
}
else
{
PyErr_Clear(); // Clear the error
// Try to parse as ((x,y), texture, ...) or (Vector, texture, ...)
PyObject* pos_obj = nullptr;
// Try alternative: first arg is pos tuple/Vector
const char* alt_keywords[] = { "pos", "texture", "sprite_index", "scale", "click", nullptr };
PyObject* pos = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOifO", const_cast<char**>(alt_keywords),
&pos_obj, &texture, &sprite_index, &scale, &click_handler))
&pos, &texture, &sprite_index, &scale, &click_handler))
{
return -1;
}
// Convert position argument to x, y
if (pos_obj) {
PyVectorObject* vec = PyVector::from_arg(pos_obj);
if (pos && pos != Py_None) {
PyVectorObject* vec = PyVector::from_arg(pos);
if (!vec) {
PyErr_SetString(PyExc_TypeError, "First argument must be a tuple (x, y) or Vector when not providing x, y separately");
PyErr_SetString(PyExc_TypeError, "pos must be a Vector or tuple (x, y)");
return -1;
}
x = vec->data.x;