diff --git a/src/PyAnimation.cpp b/src/PyAnimation.cpp index c81a2ea..265646d 100644 --- a/src/PyAnimation.cpp +++ b/src/PyAnimation.cpp @@ -1,5 +1,6 @@ #include "PyAnimation.h" #include "McRFPy_API.h" +#include "McRFPy_Doc.h" #include "UIDrawable.h" #include "UIFrame.h" #include "UICaption.h" @@ -261,33 +262,58 @@ PyObject* PyAnimation::has_valid_target(PyAnimationObject* self, PyObject* args) } PyGetSetDef PyAnimation::getsetters[] = { - {"property", (getter)get_property, NULL, "Target property name", NULL}, - {"duration", (getter)get_duration, NULL, "Animation duration in seconds", NULL}, - {"elapsed", (getter)get_elapsed, NULL, "Elapsed time in seconds", NULL}, - {"is_complete", (getter)get_is_complete, NULL, "Whether animation is complete", NULL}, - {"is_delta", (getter)get_is_delta, NULL, "Whether animation uses delta mode", NULL}, + {"property", (getter)get_property, NULL, + MCRF_PROPERTY(property, "Target property name (str, read-only). The property being animated (e.g., 'pos', 'opacity', 'sprite_index')."), NULL}, + {"duration", (getter)get_duration, NULL, + MCRF_PROPERTY(duration, "Animation duration in seconds (float, read-only). Total time for the animation to complete."), NULL}, + {"elapsed", (getter)get_elapsed, NULL, + MCRF_PROPERTY(elapsed, "Elapsed time in seconds (float, read-only). Time since the animation started."), NULL}, + {"is_complete", (getter)get_is_complete, NULL, + MCRF_PROPERTY(is_complete, "Whether animation is complete (bool, read-only). True when elapsed >= duration or complete() was called."), NULL}, + {"is_delta", (getter)get_is_delta, NULL, + MCRF_PROPERTY(is_delta, "Whether animation uses delta mode (bool, read-only). In delta mode, the target value is added to the starting value."), NULL}, {NULL} }; PyMethodDef PyAnimation::methods[] = { {"start", (PyCFunction)start, METH_VARARGS, - "start(target) -> None\n\n" - "Start the animation on a target UI element.\n\n" - "Args:\n" - " target: The UI element to animate (Frame, Caption, Sprite, Grid, or Entity)\n\n" - "Note:\n" - " The animation will automatically stop if the target is destroyed."}, + MCRF_METHOD(Animation, start, + MCRF_SIG("(target: UIDrawable)", "None"), + MCRF_DESC("Start the animation on a target UI element."), + MCRF_ARGS_START + MCRF_ARG("target", "The UI element to animate (Frame, Caption, Sprite, Grid, or Entity)") + MCRF_RETURNS("None") + MCRF_NOTE("The animation will automatically stop if the target is destroyed. Call AnimationManager.update(delta_time) each frame to progress animations.") + )}, {"update", (PyCFunction)update, METH_VARARGS, - "Update the animation by deltaTime (returns True if still running)"}, + MCRF_METHOD(Animation, update, + MCRF_SIG("(delta_time: float)", "bool"), + MCRF_DESC("Update the animation by the given time delta."), + MCRF_ARGS_START + MCRF_ARG("delta_time", "Time elapsed since last update in seconds") + MCRF_RETURNS("bool: True if animation is still running, False if complete") + MCRF_NOTE("Typically called by AnimationManager automatically. Manual calls only needed for custom animation control.") + )}, {"get_current_value", (PyCFunction)get_current_value, METH_NOARGS, - "Get the current interpolated value"}, + MCRF_METHOD(Animation, get_current_value, + MCRF_SIG("()", "Any"), + MCRF_DESC("Get the current interpolated value of the animation."), + MCRF_RETURNS("Any: Current value (type depends on property: float, int, Color tuple, Vector tuple, or str)") + MCRF_NOTE("Return type matches the target property type. For sprite_index returns int, for pos returns (x, y), for fill_color returns (r, g, b, a).") + )}, {"complete", (PyCFunction)complete, METH_NOARGS, - "complete() -> None\n\n" - "Complete the animation immediately by jumping to the final value."}, + MCRF_METHOD(Animation, complete, + MCRF_SIG("()", "None"), + MCRF_DESC("Complete the animation immediately by jumping to the final value."), + MCRF_RETURNS("None") + MCRF_NOTE("Sets elapsed = duration and applies target value immediately. Completion callback will be called if set.") + )}, {"hasValidTarget", (PyCFunction)has_valid_target, METH_NOARGS, - "hasValidTarget() -> bool\n\n" - "Check if the animation still has a valid target.\n\n" - "Returns:\n" - " True if the target still exists, False if it was destroyed."}, + MCRF_METHOD(Animation, hasValidTarget, + MCRF_SIG("()", "bool"), + MCRF_DESC("Check if the animation still has a valid target."), + MCRF_RETURNS("bool: True if the target still exists, False if it was destroyed") + MCRF_NOTE("Animations automatically clean up when targets are destroyed. Use this to check if manual cleanup is needed.") + )}, {NULL} }; \ No newline at end of file diff --git a/src/PySceneObject.cpp b/src/PySceneObject.cpp index 491024e..43489a8 100644 --- a/src/PySceneObject.cpp +++ b/src/PySceneObject.cpp @@ -2,6 +2,7 @@ #include "PyScene.h" #include "GameEngine.h" #include "McRFPy_API.h" +#include "McRFPy_Doc.h" #include // Static map to store Python scene objects by name @@ -213,19 +214,38 @@ void PySceneClass::call_on_resize(PySceneObject* self, int width, int height) // Properties PyGetSetDef PySceneClass::getsetters[] = { - {"name", (getter)get_name, NULL, "Scene name", NULL}, - {"active", (getter)get_active, NULL, "Whether this scene is currently active", NULL}, + {"name", (getter)get_name, NULL, + MCRF_PROPERTY(name, "Scene name (str, read-only). Unique identifier for this scene."), NULL}, + {"active", (getter)get_active, NULL, + MCRF_PROPERTY(active, "Whether this scene is currently active (bool, read-only). Only one scene can be active at a time."), NULL}, {NULL} }; // Methods PyMethodDef PySceneClass::methods[] = { {"activate", (PyCFunction)activate, METH_NOARGS, - "Make this the active scene"}, + MCRF_METHOD(SceneClass, activate, + MCRF_SIG("()", "None"), + MCRF_DESC("Make this the active scene."), + MCRF_RETURNS("None") + MCRF_NOTE("Deactivates the current scene and activates this one. Scene transitions and lifecycle callbacks are triggered.") + )}, {"get_ui", (PyCFunction)get_ui, METH_NOARGS, - "Get the UI element collection for this scene"}, + MCRF_METHOD(SceneClass, get_ui, + MCRF_SIG("()", "UICollection"), + MCRF_DESC("Get the UI element collection for this scene."), + MCRF_RETURNS("UICollection: Collection of UI elements (Frames, Captions, Sprites, Grids) in this scene") + MCRF_NOTE("Use to add, remove, or iterate over UI elements. Changes are reflected immediately.") + )}, {"register_keyboard", (PyCFunction)register_keyboard, METH_VARARGS, - "Register a keyboard handler function (alternative to overriding on_keypress)"}, + MCRF_METHOD(SceneClass, register_keyboard, + MCRF_SIG("(callback: callable)", "None"), + MCRF_DESC("Register a keyboard event handler function."), + MCRF_ARGS_START + MCRF_ARG("callback", "Function that receives (key: str, pressed: bool) when keyboard events occur") + MCRF_RETURNS("None") + MCRF_NOTE("Alternative to overriding on_keypress() method. Handler is called for both key press and release events.") + )}, {NULL} }; diff --git a/src/PyWindow.cpp b/src/PyWindow.cpp index c35f5c2..17fb1ba 100644 --- a/src/PyWindow.cpp +++ b/src/PyWindow.cpp @@ -1,6 +1,7 @@ #include "PyWindow.h" #include "GameEngine.h" #include "McRFPy_API.h" +#include "McRFPy_Doc.h" #include #include @@ -483,32 +484,49 @@ int PyWindow::set_scaling_mode(PyWindowObject* self, PyObject* value, void* clos // Property definitions PyGetSetDef PyWindow::getsetters[] = { - {"resolution", (getter)get_resolution, (setter)set_resolution, - "Window resolution as (width, height) tuple", NULL}, + {"resolution", (getter)get_resolution, (setter)set_resolution, + MCRF_PROPERTY(resolution, "Window resolution as (width, height) tuple. Setting this recreates the window."), NULL}, {"fullscreen", (getter)get_fullscreen, (setter)set_fullscreen, - "Window fullscreen state", NULL}, + MCRF_PROPERTY(fullscreen, "Window fullscreen state (bool). Setting this recreates the window."), NULL}, {"vsync", (getter)get_vsync, (setter)set_vsync, - "Vertical sync enabled state", NULL}, + MCRF_PROPERTY(vsync, "Vertical sync enabled state (bool). Prevents screen tearing but may limit framerate."), NULL}, {"title", (getter)get_title, (setter)set_title, - "Window title string", NULL}, + MCRF_PROPERTY(title, "Window title string (str). Displayed in the window title bar."), NULL}, {"visible", (getter)get_visible, (setter)set_visible, - "Window visibility state", NULL}, + MCRF_PROPERTY(visible, "Window visibility state (bool). Hidden windows still process events."), NULL}, {"framerate_limit", (getter)get_framerate_limit, (setter)set_framerate_limit, - "Frame rate limit (0 for unlimited)", NULL}, + MCRF_PROPERTY(framerate_limit, "Frame rate limit in FPS (int, 0 for unlimited). Caps maximum frame rate."), NULL}, {"game_resolution", (getter)get_game_resolution, (setter)set_game_resolution, - "Fixed game resolution as (width, height) tuple", NULL}, + MCRF_PROPERTY(game_resolution, "Fixed game resolution as (width, height) tuple. Enables resolution-independent rendering with scaling."), NULL}, {"scaling_mode", (getter)get_scaling_mode, (setter)set_scaling_mode, - "Viewport scaling mode: 'center', 'stretch', or 'fit'", NULL}, + MCRF_PROPERTY(scaling_mode, "Viewport scaling mode (str): 'center' (no scaling), 'stretch' (fill window), or 'fit' (maintain aspect ratio)."), NULL}, {NULL} }; // Method definitions PyMethodDef PyWindow::methods[] = { {"get", (PyCFunction)PyWindow::get, METH_VARARGS | METH_CLASS, - "Get the Window singleton instance"}, + MCRF_METHOD(Window, get, + MCRF_SIG("()", "Window"), + MCRF_DESC("Get the Window singleton instance."), + MCRF_RETURNS("Window: The global window object") + MCRF_NOTE("This is a class method. Call as Window.get(). There is only one window instance per application.") + )}, {"center", (PyCFunction)PyWindow::center, METH_NOARGS, - "Center the window on the screen"}, + MCRF_METHOD(Window, center, + MCRF_SIG("()", "None"), + MCRF_DESC("Center the window on the screen."), + MCRF_RETURNS("None") + MCRF_NOTE("Only works in windowed mode. Has no effect when fullscreen or in headless mode.") + )}, {"screenshot", (PyCFunction)PyWindow::screenshot, METH_VARARGS | METH_KEYWORDS, - "Take a screenshot. Pass filename to save to file, or get raw bytes if no filename."}, + MCRF_METHOD(Window, screenshot, + MCRF_SIG("(filename: str = None)", "bytes | None"), + MCRF_DESC("Take a screenshot of the current window contents."), + MCRF_ARGS_START + MCRF_ARG("filename", "Optional path to save screenshot. If omitted, returns raw RGBA bytes.") + MCRF_RETURNS("bytes | None: Raw RGBA pixel data if no filename given, otherwise None after saving") + MCRF_NOTE("Screenshot is taken at the actual window resolution. Use after render loop update for current frame.") + )}, {NULL} }; \ No newline at end of file