From cf485ef3272751d3e474bfb8e82561194533e1c8 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Mon, 11 Sep 2023 20:26:00 -0400 Subject: [PATCH] Refactoring UISprite to play well with Python API and match existing code styles. Default constructor will have to go, which complicates the Python class slightly for mcrfpy.Sprite --- src/McRFPy_API.cpp | 1 + src/UI.cpp | 47 +++++++++++++++++++++++++++----- src/UI.h | 65 ++++++++++++++++++++++++++++++++++++++++++--- src/UITestScene.cpp | 38 ++++++++++++++++++++------ 4 files changed, 134 insertions(+), 17 deletions(-) diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 47a463d..a6a4b19 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -125,6 +125,7 @@ PyObject* PyInit_mcrfpy() PyModule_AddType(m, &mcrfpydef::PyColorType); PyModule_AddType(m, &mcrfpydef::PyFontType); PyModule_AddType(m, &mcrfpydef::PyUICaptionType); + PyModule_AddType(m, &mcrfpydef::PyTextureType); if (PyModule_AddType(m, &mcrfpydef::PyUIFrameType) < 0) { diff --git a/src/UI.cpp b/src/UI.cpp index 5fb2a38..9cca1c2 100644 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -84,16 +84,36 @@ void UICaption::render(sf::Vector2f offset) text.move(-offset); } -void UISprite::update() +UISprite::UISprite() {} + +UISprite::UISprite(IndexTexture* _itex, int _sprite_index, float x = 0.0, float y = 0.0, float s = 1.0) +: itex(_itex), sprite_index(_sprite_index) { - auto& tex = Resources::game->textures[texture_index]; - sprite.setTexture(tex.texture); - sprite.setScale(sf::Vector2f(scale, scale)); + sprite.setTexture(_itex->texture); + sprite.setTextureRect(_itex->spriteCoordinates(_sprite_index)); sprite.setPosition(sf::Vector2f(x, y)); - //std::cout << "Drawable position: " << x << ", " << y << " -> " << s.getPosition().x << ", " << s.getPosition().y << std::endl; - sprite.setTextureRect(tex.spriteCoordinates(sprite_index)); + sprite.setScale(sf::Vector2f(s, s)); } +UISprite::UISprite(IndexTexture* _itex, int _sprite_index, sf::Vector2f pos, float s = 1.0) +: itex(_itex), sprite_index(_sprite_index) +{ + sprite.setTexture(_itex->texture); + sprite.setTextureRect(_itex->spriteCoordinates(_sprite_index)); + sprite.setPosition(pos); + sprite.setScale(sf::Vector2f(s, s)); +} + +//void UISprite::update() +//{ + //auto& tex = Resources::game->textures[texture_index]; + //sprite.setTexture(tex.texture); + //sprite.setScale(sf::Vector2f(scale, scale)); + //sprite.setPosition(sf::Vector2f(x, y)); + //std::cout << "Drawable position: " << x << ", " << y << " -> " << s.getPosition().x << ", " << s.getPosition().y << std::endl; + //sprite.setTextureRect(tex.spriteCoordinates(sprite_index)); +//} + void UISprite::render(sf::Vector2f offset) { sprite.move(offset); @@ -101,6 +121,21 @@ void UISprite::render(sf::Vector2f offset) sprite.move(-offset); } +void UISprite::setPosition(float x, float y) +{ + setPosition(sf::Vector2f(x, y)); +} + +void UISprite::setPosition(sf::Vector2f pos) +{ + sprite.setPosition(pos); +} + +void UISprite::setScale(float s) +{ + sprite.setScale(sf::Vector2f(s, s)); +} + PyObjectsEnum UICaption::derived_type() { return PyObjectsEnum::UICAPTION; diff --git a/src/UI.h b/src/UI.h index 5c26e8a..6fa4632 100644 --- a/src/UI.h +++ b/src/UI.h @@ -2,6 +2,7 @@ #include "Common.h" #include "Python.h" #include "structmember.h" +#include "IndexTexture.h" enum PyObjectsEnum { @@ -81,11 +82,18 @@ public: class UISprite: public UIDrawable { public: + UISprite(); + UISprite(IndexTexture*, int, float, float, float); + UISprite(IndexTexture*, int, sf::Vector2f, float); void update(); void render(sf::Vector2f) override final; - int texture_index, sprite_index; - float x, y, scale; + int /*texture_index,*/ sprite_index; + IndexTexture* itex; + //float x, y, scale; sf::Sprite sprite; + void setPosition(float, float); + void setPosition(sf::Vector2f); + void setScale(float); PyObjectsEnum derived_type() override final; // { return PyObjectsEnum::UISprite; }; }; @@ -113,6 +121,7 @@ typedef struct { typedef struct { PyObject_HEAD std::shared_ptr data; + PyObject* texture; } PyUISpriteObject; @@ -243,7 +252,7 @@ switch (target->derived_type()) \ * */ - + static PyObject* PyColor_get_member(PyColorObject* self, void* closure) { auto member_ptr = reinterpret_cast(closure); @@ -856,6 +865,56 @@ switch (target->derived_type()) \ * */ + /* + * + * Begin PyTextureType defs + * + */ + + typedef struct { + PyObject_HEAD + std::shared_ptr data; + } PyTextureObject; + + static int PyTexture_init(PyTextureObject* self, PyObject* args, PyObject* kwds) + { + //std::cout << "Init called\n"; + static const char* keywords[] = { "filename", "grid_size", "grid_width", "grid_height", nullptr }; + char* filename; + int grid_size, grid_width, grid_height; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "siii", const_cast(keywords), &filename, &grid_size, &grid_width, &grid_height)) + { + return -1; + } + sf::Texture t = sf::Texture(); + t.loadFromFile((std::string)filename); + self->data = std::make_shared(t, grid_size, grid_width, grid_height); + return 0; + } + + static PyTypeObject PyTextureType = { + //PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "mcrfpy.Texture", + .tp_basicsize = sizeof(PyTextureObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = PyDoc_STR("SFML Texture Object"), + .tp_init = (initproc)PyTexture_init, + .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* + { + PyTextureObject* self = (PyTextureObject*)type->tp_alloc(type, 0); + return (PyObject*)self; + } + }; + + /* + * + * End PyTextureType defs + * + */ + + /* * * Begin PyUICollectionIter defs diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index 25016ca..b5904ab 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -61,18 +61,40 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) t.loadFromFile("./assets/kenney_tinydungeon.png"); t.setSmooth(false); - auto indextex = IndexTexture(t, 16, 12, 11); - Resources::game->textures.push_back(indextex); + auto* indextex = new IndexTexture(t, 16, 12, 11); + Resources::game->textures.push_back(*indextex); + + //std::cout << Resources::game->textures.size() << " textures loaded.\n"; auto e3 = std::make_shared(); - e3->x = 10; e3->y = 10; - e3->texture_index = 0; - e3->sprite_index = 84; - e3->scale = 4.0f; - e3->update(); - e1aa->children->push_back(e3); + // Make UISprite more like IndexSprite: this is bad + //e3->x = 10; e3->y = 10; + //e3->texture_index = 0; + //e3->sprite_index = 84; + //e3->scale = 4.0f; + //e3->update(); + + // This goes to show how inconvenient the default constructor is. It should be removed + e3->itex = &Resources::game->textures[0]; + e3->sprite.setTexture(e3->itex->texture); + e3->sprite_index = 84; + e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index)); + e3->setPosition(10, 10); + e3->setScale(4.0f); + + e1aa->children->push_back(e3); + + + + auto e4 = std::make_shared( + indextex, //&Resources::game->textures[0], + 85, sf::Vector2f(90, 10), 4.0); + e1aa->children->push_back(e4); + //std::cout << "UISprite built: " << e4->sprite.getPosition().x << " " << e4->sprite.getPosition().y << " " << e4->sprite.getScale().x << " " << + // e4->sprite_index << " " << std::endl; + /* // note - you can't use the pointer to UI elements in constructor. // The scene map is still being assigned to, so this object can't be looked up.