feat: Grid size tuple support closes #90

- Add grid_size keyword parameter to Grid.__init__
- Accept tuple or list of two integers
- Override grid_x/grid_y if grid_size provided
- Maintain backward compatibility
- Add comprehensive test coverage
This commit is contained in:
John McCardle 2025-07-06 00:31:29 -04:00
commit da7180f5ed
4 changed files with 143 additions and 19 deletions

View file

@ -298,23 +298,24 @@ 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", nullptr };
static const char* keywords[] = { "x", "y", "texture", "sprite_index", "scale", "click", nullptr };
float x = 0.0f, y = 0.0f, scale = 1.0f;
int sprite_index = 0;
PyObject* texture = NULL;
PyObject* click_handler = NULL;
// First try to parse as (x, y, texture, ...)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ffOif",
const_cast<char**>(keywords), &x, &y, &texture, &sprite_index, &scale))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ffOifO",
const_cast<char**>(keywords), &x, &y, &texture, &sprite_index, &scale, &click_handler))
{
PyErr_Clear(); // Clear the error
// Try to parse as ((x,y), texture, ...) or (Vector, texture, ...)
PyObject* pos_obj = nullptr;
const char* alt_keywords[] = { "pos", "texture", "sprite_index", "scale", nullptr };
const char* alt_keywords[] = { "pos", "texture", "sprite_index", "scale", "click", nullptr };
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOif", const_cast<char**>(alt_keywords),
&pos_obj, &texture, &sprite_index, &scale))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOifO", const_cast<char**>(alt_keywords),
&pos_obj, &texture, &sprite_index, &scale, &click_handler))
{
return -1;
}
@ -352,6 +353,15 @@ int UISprite::init(PyUISpriteObject* self, PyObject* args, PyObject* kwds)
self->data = std::make_shared<UISprite>(texture_ptr, sprite_index, sf::Vector2f(x, y), scale);
self->data->setPosition(sf::Vector2f(x, y));
// Process click handler if provided
if (click_handler && click_handler != Py_None) {
if (!PyCallable_Check(click_handler)) {
PyErr_SetString(PyExc_TypeError, "click must be callable");
return -1;
}
self->data->click_register(click_handler);
}
return 0;
}