#pragma once #include "Common.h" #include "Python.h" #include "structmember.h" #include "UIDrawable.h" #include "UIBase.h" #include "PyDrawable.h" #include "PyColor.h" #include "PyVector.h" #include "McRFPy_Doc.h" // Forward declaration class UIArc; // Python object structure typedef struct { PyObject_HEAD std::shared_ptr data; PyObject* weakreflist; } PyUIArcObject; class UIArc : public UIDrawable { private: sf::Vector2f center; float radius; float start_angle; // in degrees float end_angle; // in degrees sf::Color color; float thickness; // Cached vertex array for rendering sf::VertexArray vertices; bool vertices_dirty; void rebuildVertices(); public: UIArc(); UIArc(sf::Vector2f center, float radius, float startAngle, float endAngle, sf::Color color = sf::Color::White, float thickness = 1.0f); // Copy constructor and assignment UIArc(const UIArc& other); UIArc& operator=(const UIArc& other); // Move constructor and assignment UIArc(UIArc&& other) noexcept; UIArc& operator=(UIArc&& other) noexcept; // UIDrawable interface void render(sf::Vector2f offset, sf::RenderTarget& target) override; UIDrawable* click_at(sf::Vector2f point) override; PyObjectsEnum derived_type() override; // Getters and setters sf::Vector2f getCenter() const { return center; } void setCenter(sf::Vector2f c) { center = c; position = c; vertices_dirty = true; } float getRadius() const { return radius; } void setRadius(float r) { radius = r; vertices_dirty = true; } float getStartAngle() const { return start_angle; } void setStartAngle(float a) { start_angle = a; vertices_dirty = true; } float getEndAngle() const { return end_angle; } void setEndAngle(float a) { end_angle = a; vertices_dirty = true; } sf::Color getColor() const { return color; } void setColor(sf::Color c) { color = c; vertices_dirty = true; } float getThickness() const { return thickness; } void setThickness(float t) { thickness = t; vertices_dirty = true; } // Phase 1 virtual method implementations sf::FloatRect get_bounds() const override; void move(float dx, float dy) override; void resize(float w, float h) override; // Property system for animations bool setProperty(const std::string& name, float value) override; bool setProperty(const std::string& name, const sf::Color& value) override; bool setProperty(const std::string& name, const sf::Vector2f& value) override; bool getProperty(const std::string& name, float& value) const override; bool getProperty(const std::string& name, sf::Color& value) const override; bool getProperty(const std::string& name, sf::Vector2f& value) const override; // Python API static PyObject* get_center(PyUIArcObject* self, void* closure); static int set_center(PyUIArcObject* self, PyObject* value, void* closure); static PyObject* get_radius(PyUIArcObject* self, void* closure); static int set_radius(PyUIArcObject* self, PyObject* value, void* closure); static PyObject* get_start_angle(PyUIArcObject* self, void* closure); static int set_start_angle(PyUIArcObject* self, PyObject* value, void* closure); static PyObject* get_end_angle(PyUIArcObject* self, void* closure); static int set_end_angle(PyUIArcObject* self, PyObject* value, void* closure); static PyObject* get_color(PyUIArcObject* self, void* closure); static int set_color(PyUIArcObject* self, PyObject* value, void* closure); static PyObject* get_thickness(PyUIArcObject* self, void* closure); static int set_thickness(PyUIArcObject* self, PyObject* value, void* closure); static PyGetSetDef getsetters[]; static PyObject* repr(PyUIArcObject* self); static int init(PyUIArcObject* self, PyObject* args, PyObject* kwds); }; // Method definitions extern PyMethodDef UIArc_methods[]; namespace mcrfpydef { static PyTypeObject PyUIArcType = { .ob_base = {.ob_base = {.ob_refcnt = 1, .ob_type = NULL}, .ob_size = 0}, .tp_name = "mcrfpy.Arc", .tp_basicsize = sizeof(PyUIArcObject), .tp_itemsize = 0, .tp_dealloc = (destructor)[](PyObject* self) { PyUIArcObject* obj = (PyUIArcObject*)self; if (obj->weakreflist != NULL) { PyObject_ClearWeakRefs(self); } obj->data.reset(); Py_TYPE(self)->tp_free(self); }, .tp_repr = (reprfunc)UIArc::repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = PyDoc_STR( "Arc(center=None, radius=0, start_angle=0, end_angle=90, color=None, thickness=1, **kwargs)\n\n" "An arc UI element for drawing curved line segments.\n\n" "Args:\n" " center (tuple, optional): Center position as (x, y). Default: (0, 0)\n" " radius (float, optional): Arc radius in pixels. Default: 0\n" " start_angle (float, optional): Starting angle in degrees. Default: 0\n" " end_angle (float, optional): Ending angle in degrees. Default: 90\n" " color (Color, optional): Arc color. Default: White\n" " thickness (float, optional): Line thickness. Default: 1.0\n\n" "Keyword Args:\n" " click (callable): Click handler. Default: None\n" " visible (bool): Visibility state. Default: True\n" " opacity (float): Opacity (0.0-1.0). Default: 1.0\n" " z_index (int): Rendering order. Default: 0\n" " name (str): Element name for finding. Default: None\n\n" "Attributes:\n" " center (Vector): Center position\n" " radius (float): Arc radius\n" " start_angle (float): Starting angle in degrees\n" " end_angle (float): Ending angle in degrees\n" " color (Color): Arc color\n" " thickness (float): Line thickness\n" " visible (bool): Visibility state\n" " opacity (float): Opacity value\n" " z_index (int): Rendering order\n" " name (str): Element name\n" ), .tp_methods = UIArc_methods, .tp_getset = UIArc::getsetters, .tp_base = &mcrfpydef::PyDrawableType, .tp_init = (initproc)UIArc::init, .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* { PyUIArcObject* self = (PyUIArcObject*)type->tp_alloc(type, 0); if (self) { self->data = std::make_shared(); self->weakreflist = nullptr; } return (PyObject*)self; } }; }