McRogueFace/src/UILine.h

150 lines
5.9 KiB
C
Raw Normal View History

#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 UILine;
// Python object structure
typedef struct {
PyObject_HEAD
std::shared_ptr<UILine> data;
PyObject* weakreflist;
} PyUILineObject;
class UILine : public UIDrawable
{
private:
sf::Vector2f start_pos; // Starting point
sf::Vector2f end_pos; // Ending point
sf::Color color; // Line color
float thickness; // Line thickness in pixels
// Cached vertex array for rendering
mutable sf::VertexArray vertices;
mutable bool vertices_dirty;
void updateVertices() const;
public:
UILine();
UILine(sf::Vector2f start, sf::Vector2f end, float thickness = 1.0f, sf::Color color = sf::Color::White);
// Copy constructor and assignment
UILine(const UILine& other);
UILine& operator=(const UILine& other);
// Move constructor and assignment
UILine(UILine&& other) noexcept;
UILine& operator=(UILine&& 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 getStart() const { return start_pos; }
void setStart(sf::Vector2f pos) { start_pos = pos; vertices_dirty = true; }
sf::Vector2f getEnd() const { return end_pos; }
void setEnd(sf::Vector2f pos) { end_pos = pos; 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_start(PyUILineObject* self, void* closure);
static int set_start(PyUILineObject* self, PyObject* value, void* closure);
static PyObject* get_end(PyUILineObject* self, void* closure);
static int set_end(PyUILineObject* self, PyObject* value, void* closure);
static PyObject* get_color(PyUILineObject* self, void* closure);
static int set_color(PyUILineObject* self, PyObject* value, void* closure);
static PyObject* get_thickness(PyUILineObject* self, void* closure);
static int set_thickness(PyUILineObject* self, PyObject* value, void* closure);
static PyGetSetDef getsetters[];
static PyObject* repr(PyUILineObject* self);
static int init(PyUILineObject* self, PyObject* args, PyObject* kwds);
};
// Method definitions (extern to be defined in .cpp)
extern PyMethodDef UILine_methods[];
namespace mcrfpydef {
static PyTypeObject PyUILineType = {
.ob_base = {.ob_base = {.ob_refcnt = 1, .ob_type = NULL}, .ob_size = 0},
.tp_name = "mcrfpy.Line",
.tp_basicsize = sizeof(PyUILineObject),
.tp_itemsize = 0,
.tp_dealloc = (destructor)[](PyObject* self) {
PyUILineObject* obj = (PyUILineObject*)self;
if (obj->weakreflist != NULL) {
PyObject_ClearWeakRefs(self);
}
obj->data.reset();
Py_TYPE(self)->tp_free(self);
},
.tp_repr = (reprfunc)UILine::repr,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_doc = PyDoc_STR(
"Line(start=None, end=None, thickness=1.0, color=None, **kwargs)\n\n"
"A line UI element for drawing straight lines between two points.\n\n"
"Args:\n"
" start (tuple, optional): Starting point as (x, y). Default: (0, 0)\n"
" end (tuple, optional): Ending point as (x, y). Default: (0, 0)\n"
" thickness (float, optional): Line thickness in pixels. Default: 1.0\n"
" color (Color, optional): Line color. Default: White\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"
" start (Vector): Starting point\n"
" end (Vector): Ending point\n"
" thickness (float): Line thickness\n"
" color (Color): Line color\n"
" visible (bool): Visibility state\n"
" opacity (float): Opacity value\n"
" z_index (int): Rendering order\n"
" name (str): Element name\n"
),
.tp_methods = UILine_methods,
.tp_getset = UILine::getsetters,
.tp_base = &mcrfpydef::PyDrawableType,
.tp_init = (initproc)UILine::init,
.tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* {
PyUILineObject* self = (PyUILineObject*)type->tp_alloc(type, 0);
if (self) {
self->data = std::make_shared<UILine>();
self->weakreflist = nullptr;
}
return (PyObject*)self;
}
};
}