feat: Standardize position arguments across all UI classes
- Create PyPositionHelper for consistent position parsing - Grid.at() now accepts (x,y), ((x,y)), x=x, y=y, pos=(x,y) - Caption now accepts x,y args in addition to pos - Grid init fully supports keyword arguments - Maintain backward compatibility for all formats - Consistent error messages across classes
This commit is contained in:
parent
fe5976c425
commit
c48c91e5d7
3 changed files with 223 additions and 88 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "UIGrid.h"
|
||||
#include "GameEngine.h"
|
||||
#include "McRFPy_API.h"
|
||||
#include "PyPositionHelper.h"
|
||||
#include <algorithm>
|
||||
|
||||
UIGrid::UIGrid()
|
||||
|
|
@ -281,8 +282,8 @@ int UIGrid::init(PyUIGridObject* self, PyObject* args, PyObject* kwds) {
|
|||
static const char* keywords[] = {"grid_x", "grid_y", "texture", "pos", "size", "grid_size", NULL};
|
||||
|
||||
// First try parsing with keywords
|
||||
if (kwds && PyArg_ParseTupleAndKeywords(args, kwds, "|iiOOOO", const_cast<char**>(keywords),
|
||||
&grid_x, &grid_y, &textureObj, &pos, &size, &grid_size_obj)) {
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|iiOOOO", const_cast<char**>(keywords),
|
||||
&grid_x, &grid_y, &textureObj, &pos, &size, &grid_size_obj)) {
|
||||
// If grid_size is provided, use it to override grid_x and grid_y
|
||||
if (grid_size_obj && grid_size_obj != Py_None) {
|
||||
if (PyTuple_Check(grid_size_obj) && PyTuple_Size(grid_size_obj) == 2) {
|
||||
|
|
@ -566,72 +567,17 @@ PyObject* UIGrid::get_texture(PyUIGridObject* self, void* closure) {
|
|||
|
||||
PyObject* UIGrid::py_at(PyUIGridObject* self, PyObject* args, PyObject* kwds)
|
||||
{
|
||||
static const char* keywords[] = { "x", "y", "pos", nullptr };
|
||||
int x = -1, y = -1;
|
||||
PyObject* pos = nullptr;
|
||||
// Use the standardized position parser
|
||||
auto result = PyPositionHelper::parse_position_int(args, kwds);
|
||||
|
||||
// Try to parse with keywords first
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", const_cast<char**>(keywords), &x, &y, &pos)) {
|
||||
PyErr_Clear(); // Clear the error and try different parsing
|
||||
|
||||
// Check if we have a single tuple argument (x, y)
|
||||
if (PyTuple_Size(args) == 1 && kwds == nullptr) {
|
||||
PyObject* arg = PyTuple_GetItem(args, 0);
|
||||
if (PyTuple_Check(arg) && PyTuple_Size(arg) == 2) {
|
||||
// It's a tuple, extract x and y
|
||||
PyObject* x_obj = PyTuple_GetItem(arg, 0);
|
||||
PyObject* y_obj = PyTuple_GetItem(arg, 1);
|
||||
if (PyLong_Check(x_obj) && PyLong_Check(y_obj)) {
|
||||
x = PyLong_AsLong(x_obj);
|
||||
y = PyLong_AsLong(y_obj);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "Tuple elements must be integers");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "UIGrid.at accepts: (x, y), x, y, x=x, y=y, or pos=(x,y)");
|
||||
return NULL;
|
||||
}
|
||||
} else if (PyTuple_Size(args) == 2 && kwds == nullptr) {
|
||||
// Two positional arguments
|
||||
if (!PyArg_ParseTuple(args, "ii", &x, &y)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arguments must be integers");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "UIGrid.at accepts: (x, y), x, y, x=x, y=y, or pos=(x,y)");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle pos keyword argument
|
||||
if (pos != nullptr) {
|
||||
if (x != -1 || y != -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot specify both pos and x/y arguments");
|
||||
return NULL;
|
||||
}
|
||||
if (PyTuple_Check(pos) && PyTuple_Size(pos) == 2) {
|
||||
PyObject* x_obj = PyTuple_GetItem(pos, 0);
|
||||
PyObject* y_obj = PyTuple_GetItem(pos, 1);
|
||||
if (PyLong_Check(x_obj) && PyLong_Check(y_obj)) {
|
||||
x = PyLong_AsLong(x_obj);
|
||||
y = PyLong_AsLong(y_obj);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "pos tuple elements must be integers");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "pos must be a tuple of two integers");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate we have both x and y
|
||||
if (x == -1 || y == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "UIGrid.at requires both x and y coordinates");
|
||||
if (!result.has_position) {
|
||||
PyPositionHelper::set_position_int_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int x = result.x;
|
||||
int y = result.y;
|
||||
|
||||
// Range validation
|
||||
if (x < 0 || x >= self->data->grid_x) {
|
||||
PyErr_SetString(PyExc_ValueError, "x value out of range (0, Grid.grid_x)");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue