Pre-1.0 constructor surface freeze for UI shapes and Grid layers
Group A: parent= auto-attach kwarg
- Added parent= to Frame, Caption, Sprite, Line, Circle, Arc.
Validates against Frame/Scene/Grid/GridView and appends self
to parent.children. Mirrors the existing Entity(grid=...) pattern.
Implemented as a UIDRAWABLE_ATTACH_TO_PARENT macro in UIBase.h
so all six call sites stay one-liners.
- Added grid= to ColorLayer and TileLayer. Validates against Grid /
GridView and routes through grid.add_layer(self).
Sub-changes (also pre-1.0 breakage, no shims):
- Circle: positional order swapped from (radius, center, ...) to
(center, radius, ...). Old positional callers will now fail at
PyArg_ParseTupleAndKeywords with a TypeError.
- Caption: font is now keyword-only. kwlist reordered to put pos
and text first; the '$' separator in the format string makes
everything that follows (font, fill_color, ...) keyword-only.
- ColorLayer / TileLayer: kwlist reordered so that name comes
before z_index. Format strings updated to match.
UIBase.h gains a UIDRAWABLE_ATTACH_TO_PARENT macro that mirrors
the existing UIDRAWABLE_PROCESS_ALIGNMENT pattern: type-check,
fetch .children, call append, propagate any error as -1.
Old positional callers across the codebase (Caption with positional
font, Circle with positional radius-first) will need to be updated
separately. No backward-compat shims have been added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3030ac488b
commit
e1b167530c
8 changed files with 151 additions and 28 deletions
|
|
@ -814,14 +814,24 @@ PyGetSetDef PyGridLayerAPI::ColorLayer_getsetters[] = {
|
|||
};
|
||||
|
||||
int PyGridLayerAPI::ColorLayer_init(PyColorLayerObject* self, PyObject* args, PyObject* kwds) {
|
||||
static const char* kwlist[] = {"z_index", "name", "grid_size", NULL};
|
||||
// 1.0 API freeze: positional order is now (name, z_index, ...).
|
||||
static const char* kwlist[] = {"name", "z_index", "grid_size", "grid", NULL};
|
||||
int z_index = -1;
|
||||
const char* name_str = nullptr;
|
||||
PyObject* grid_size_obj = nullptr;
|
||||
PyObject* grid_obj = nullptr;
|
||||
int grid_x = 0, grid_y = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|izO", const_cast<char**>(kwlist),
|
||||
&z_index, &name_str, &grid_size_obj)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ziOO", const_cast<char**>(kwlist),
|
||||
&name_str, &z_index, &grid_size_obj, &grid_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate grid kwarg type up-front (before allocating data).
|
||||
if (grid_obj && grid_obj != Py_None &&
|
||||
!PyObject_IsInstance(grid_obj, (PyObject*)&mcrfpydef::PyUIGridType) &&
|
||||
!PyObject_IsInstance(grid_obj, (PyObject*)&mcrfpydef::PyUIGridViewType)) {
|
||||
PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -851,6 +861,15 @@ int PyGridLayerAPI::ColorLayer_init(PyColorLayerObject* self, PyObject* args, Py
|
|||
}
|
||||
self->grid.reset();
|
||||
|
||||
// Auto-attach to grid via grid.add_layer(self) if grid= was supplied.
|
||||
if (grid_obj && grid_obj != Py_None) {
|
||||
PyObject* result = PyObject_CallMethod(grid_obj, "add_layer", "O", (PyObject*)self);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1844,15 +1863,25 @@ PyGetSetDef PyGridLayerAPI::TileLayer_getsetters[] = {
|
|||
};
|
||||
|
||||
int PyGridLayerAPI::TileLayer_init(PyTileLayerObject* self, PyObject* args, PyObject* kwds) {
|
||||
static const char* kwlist[] = {"z_index", "name", "texture", "grid_size", NULL};
|
||||
// 1.0 API freeze: positional order is now (name, z_index, ...).
|
||||
static const char* kwlist[] = {"name", "z_index", "texture", "grid_size", "grid", NULL};
|
||||
int z_index = -1;
|
||||
const char* name_str = nullptr;
|
||||
PyObject* texture_obj = nullptr;
|
||||
PyObject* grid_size_obj = nullptr;
|
||||
PyObject* grid_obj = nullptr;
|
||||
int grid_x = 0, grid_y = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|izOO", const_cast<char**>(kwlist),
|
||||
&z_index, &name_str, &texture_obj, &grid_size_obj)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ziOOO", const_cast<char**>(kwlist),
|
||||
&name_str, &z_index, &texture_obj, &grid_size_obj, &grid_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate grid kwarg type up-front (before allocating data).
|
||||
if (grid_obj && grid_obj != Py_None &&
|
||||
!PyObject_IsInstance(grid_obj, (PyObject*)&mcrfpydef::PyUIGridType) &&
|
||||
!PyObject_IsInstance(grid_obj, (PyObject*)&mcrfpydef::PyUIGridViewType)) {
|
||||
PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1903,6 +1932,15 @@ int PyGridLayerAPI::TileLayer_init(PyTileLayerObject* self, PyObject* args, PyOb
|
|||
}
|
||||
self->grid.reset();
|
||||
|
||||
// Auto-attach to grid via grid.add_layer(self) if grid= was supplied.
|
||||
if (grid_obj && grid_obj != Py_None) {
|
||||
PyObject* result = PyObject_CallMethod(grid_obj, "add_layer", "O", (PyObject*)self);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
#include "McRFPy_API.h"
|
||||
#include "PythonObjectCache.h"
|
||||
#include "PyAlignment.h"
|
||||
#include "UIFrame.h" // parent= kwarg: Frame parent type
|
||||
#include "UICaption.h" // parent= kwarg: needed for ATTACH macro instantiation
|
||||
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
|
|
@ -556,19 +560,22 @@ int UIArc::init(PyUIArcObject* self, PyObject* args, PyObject* kwds) {
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = nullptr; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
static const char* kwlist[] = {
|
||||
"center", "radius", "start_angle", "end_angle", "color", "thickness",
|
||||
"on_click", "visible", "opacity", "z_index", "name",
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent",
|
||||
nullptr
|
||||
};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OfffOfOifizOfff", const_cast<char**>(kwlist),
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OfffOfOifizOfffO", const_cast<char**>(kwlist),
|
||||
¢er_obj, &radius, &start_angle, &end_angle,
|
||||
&color_obj, &thickness,
|
||||
&click_handler, &visible, &opacity, &z_index, &name,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -639,5 +646,8 @@ int UIArc::init(PyUIArcObject* self, PyObject* args, PyObject* kwds) {
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUIArcType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
27
src/UIBase.h
27
src/UIBase.h
|
|
@ -158,6 +158,33 @@ static PyObject* UIDrawable_animate(T* self, PyObject* args, PyObject* kwds)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
// Macro for auto-attaching a newly constructed UI drawable to a parent's children.
|
||||
// Usage: UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
// parent_obj must be a Frame, Scene, or Grid (anything with a .children UICollection).
|
||||
// Returns -1 on error (suitable for use in tp_init functions). No-op when parent_obj is null/None.
|
||||
#define UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self) \
|
||||
do { \
|
||||
if ((parent_obj) && (parent_obj) != Py_None) { \
|
||||
if (!PyObject_IsInstance((parent_obj), (PyObject*)&mcrfpydef::PyUIFrameType) && \
|
||||
!PyObject_IsInstance((parent_obj), (PyObject*)&mcrfpydef::PySceneType) && \
|
||||
!PyObject_IsInstance((parent_obj), (PyObject*)&mcrfpydef::PyUIGridType) && \
|
||||
!PyObject_IsInstance((parent_obj), (PyObject*)&mcrfpydef::PyUIGridViewType)) { \
|
||||
PyErr_SetString(PyExc_TypeError, "parent must be a Frame, Scene, or Grid"); \
|
||||
return -1; \
|
||||
} \
|
||||
PyObject* _children = PyObject_GetAttrString((parent_obj), "children"); \
|
||||
if (!_children) { \
|
||||
return -1; \
|
||||
} \
|
||||
PyObject* _result = PyObject_CallMethod(_children, "append", "O", (PyObject*)(self)); \
|
||||
Py_DECREF(_children); \
|
||||
if (!_result) { \
|
||||
return -1; \
|
||||
} \
|
||||
Py_DECREF(_result); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Property getters/setters for visible and opacity
|
||||
template<typename T>
|
||||
static PyObject* UIDrawable_get_visible(T* self, void* closure)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
#include "PyAlignment.h"
|
||||
#include "PyShader.h" // #106: Shader support
|
||||
#include "PyUniformCollection.h" // #106: Uniform collection support
|
||||
#include "UIFrame.h" // parent= kwarg: Frame parent type
|
||||
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
// UIDrawable methods now in UIBase.h
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -448,23 +451,27 @@ int UICaption::init(PyUICaptionObject* self, PyObject* args, PyObject* kwds)
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = nullptr; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
// Keywords list matches the new spec: positional args first, then all keyword args
|
||||
// Keywords list: pos and text are positional-or-keyword. Everything after
|
||||
// the '$' separator (font and friends) is keyword-only.
|
||||
static const char* kwlist[] = {
|
||||
"pos", "font", "text", // Positional args (as per spec)
|
||||
// Keyword-only args
|
||||
"fill_color", "outline_color", "outline", "font_size", "on_click",
|
||||
"pos", "text",
|
||||
// Keyword-only args follow:
|
||||
"font", "fill_color", "outline_color", "outline", "font_size", "on_click",
|
||||
"visible", "opacity", "z_index", "name", "x", "y",
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent",
|
||||
nullptr
|
||||
};
|
||||
|
||||
// Parse arguments with | for optional positional args
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOzOOffOifizffOfff", const_cast<char**>(kwlist),
|
||||
&pos_obj, &font, &text, // Positional
|
||||
&fill_color, &outline_color, &outline, &font_size, &click_handler,
|
||||
// '$' marker makes all following args keyword-only (Python 3.3+ format extension).
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz$OOOffOifizffOfffO", const_cast<char**>(kwlist),
|
||||
&pos_obj, &text, // pos+text are positional-or-keyword
|
||||
&font, &fill_color, &outline_color, &outline, &font_size, &click_handler,
|
||||
&visible, &opacity, &z_index, &name, &x, &y,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -597,6 +604,9 @@ int UICaption::init(PyUICaptionObject* self, PyObject* args, PyObject* kwds)
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUICaptionType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#include "PyColor.h"
|
||||
#include "PythonObjectCache.h"
|
||||
#include "PyAlignment.h"
|
||||
#include "UIFrame.h" // parent= kwarg: Frame parent type
|
||||
#include "UICaption.h" // parent= kwarg: needed for ATTACH macro instantiation
|
||||
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
#include <cmath>
|
||||
|
||||
UICircle::UICircle()
|
||||
|
|
@ -479,10 +483,13 @@ PyObject* UICircle::repr(PyUICircleObject* self) {
|
|||
}
|
||||
|
||||
int UICircle::init(PyUICircleObject* self, PyObject* args, PyObject* kwds) {
|
||||
// 1.0 API freeze: positional order is now (center, radius, ...). The old
|
||||
// (radius, center) ordering is no longer supported.
|
||||
static const char* kwlist[] = {
|
||||
"radius", "center", "fill_color", "outline_color", "outline",
|
||||
"center", "radius", "fill_color", "outline_color", "outline",
|
||||
"on_click", "visible", "opacity", "z_index", "name",
|
||||
"align", "margin", "horiz_margin", "vert_margin", NULL
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent", NULL
|
||||
};
|
||||
|
||||
float radius = 10.0f;
|
||||
|
|
@ -501,11 +508,13 @@ int UICircle::init(PyUICircleObject* self, PyObject* args, PyObject* kwds) {
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = NULL; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|fOOOfOpfisOfff", (char**)kwlist,
|
||||
&radius, ¢er_obj, &fill_color_obj, &outline_color_obj, &outline,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OfOOfOpfisOfffO", (char**)kwlist,
|
||||
¢er_obj, &radius, &fill_color_obj, &outline_color_obj, &outline,
|
||||
&click_obj, &visible, &opacity_val, &z_index, &name,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -597,5 +606,8 @@ int UICircle::init(PyUICircleObject* self, PyObject* args, PyObject* kwds) {
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUICircleType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "UICaption.h"
|
||||
#include "UISprite.h"
|
||||
#include "UIGrid.h"
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
#include "McRFPy_API.h"
|
||||
#include "PythonObjectCache.h"
|
||||
#include "PyAlignment.h"
|
||||
|
|
@ -601,6 +602,7 @@ int UIFrame::init(PyUIFrameObject* self, PyObject* args, PyObject* kwds)
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = nullptr; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
// Keywords list matches the new spec: positional args first, then all keyword args
|
||||
static const char* kwlist[] = {
|
||||
|
|
@ -609,15 +611,17 @@ int UIFrame::init(PyUIFrameObject* self, PyObject* args, PyObject* kwds)
|
|||
"fill_color", "outline_color", "outline", "children", "on_click",
|
||||
"visible", "opacity", "z_index", "name", "x", "y", "w", "h", "clip_children", "cache_subtree",
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent",
|
||||
nullptr
|
||||
};
|
||||
|
||||
// Parse arguments with | for optional positional args
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOfOOifizffffiiOfff", const_cast<char**>(kwlist),
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOfOOifizffffiiOfffO", const_cast<char**>(kwlist),
|
||||
&pos_obj, &size_obj, // Positional
|
||||
&fill_color, &outline_color, &outline, &children_arg, &click_handler,
|
||||
&visible, &opacity, &z_index, &name, &x, &y, &w, &h, &clip_children, &cache_subtree,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -798,6 +802,9 @@ int UIFrame::init(PyUIFrameObject* self, PyObject* args, PyObject* kwds)
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUIFrameType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#include "PyColor.h"
|
||||
#include "PythonObjectCache.h"
|
||||
#include "PyAlignment.h"
|
||||
#include "UIFrame.h" // parent= kwarg: Frame parent type
|
||||
#include "UICaption.h" // parent= kwarg: needed for ATTACH macro instantiation
|
||||
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
#include <cmath>
|
||||
|
||||
UILine::UILine()
|
||||
|
|
@ -565,18 +569,21 @@ int UILine::init(PyUILineObject* self, PyObject* args, PyObject* kwds) {
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = nullptr; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
static const char* kwlist[] = {
|
||||
"start", "end", "thickness", "color",
|
||||
"on_click", "visible", "opacity", "z_index", "name",
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent",
|
||||
nullptr
|
||||
};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOfOOifizOfff", const_cast<char**>(kwlist),
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOfOOifizOfffO", const_cast<char**>(kwlist),
|
||||
&start_obj, &end_obj, &thickness, &color_obj,
|
||||
&click_handler, &visible, &opacity, &z_index, &name,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -663,5 +670,8 @@ int UILine::init(PyUILineObject* self, PyObject* args, PyObject* kwds) {
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUILineType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
#include "PyVector.h"
|
||||
#include "PythonObjectCache.h"
|
||||
#include "UIFrame.h" // #144: For snapshot= parameter
|
||||
#include "UICaption.h" // parent= kwarg: needed for ATTACH macro instantiation
|
||||
#include "UIGrid.h" // parent= kwarg: Grid/GridView parent type
|
||||
#include "PySceneObject.h" // parent= kwarg: Scene parent type
|
||||
#include "PyAlignment.h"
|
||||
#include "PyShader.h" // #106: Shader support
|
||||
#include "PyUniformCollection.h" // #106: Uniform collection support
|
||||
|
|
@ -476,6 +479,7 @@ int UISprite::init(PyUISpriteObject* self, PyObject* args, PyObject* kwds)
|
|||
float margin = 0.0f;
|
||||
float horiz_margin = -1.0f;
|
||||
float vert_margin = -1.0f;
|
||||
PyObject* parent_obj = nullptr; // Auto-attach parent (Frame, Scene, or Grid)
|
||||
|
||||
// Keywords list matches the new spec: positional args first, then all keyword args
|
||||
static const char* kwlist[] = {
|
||||
|
|
@ -484,15 +488,17 @@ int UISprite::init(PyUISpriteObject* self, PyObject* args, PyObject* kwds)
|
|||
"scale", "scale_x", "scale_y", "on_click",
|
||||
"visible", "opacity", "z_index", "name", "x", "y", "snapshot",
|
||||
"align", "margin", "horiz_margin", "vert_margin",
|
||||
"parent",
|
||||
nullptr
|
||||
};
|
||||
|
||||
// Parse arguments with | for optional positional args
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOifffOifizffOOfff", const_cast<char**>(kwlist),
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOifffOifizffOOfffO", const_cast<char**>(kwlist),
|
||||
&pos_obj, &texture, &sprite_index, // Positional
|
||||
&scale, &scale_x, &scale_y, &click_handler,
|
||||
&visible, &opacity, &z_index, &name, &x, &y, &snapshot,
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin)) {
|
||||
&align_obj, &margin, &horiz_margin, &vert_margin,
|
||||
&parent_obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -627,6 +633,9 @@ int UISprite::init(PyUISpriteObject* self, PyObject* args, PyObject* kwds)
|
|||
// #184: Check if this is a Python subclass (for callback method support)
|
||||
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != (PyObject*)&mcrfpydef::PyUISpriteType;
|
||||
|
||||
// Auto-attach to parent's children collection if parent= was supplied
|
||||
UIDRAWABLE_ATTACH_TO_PARENT(parent_obj, self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue