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

This commit is contained in:
John McCardle 2023-09-11 20:26:00 -04:00
parent 3a1432212f
commit cf485ef327
4 changed files with 134 additions and 17 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -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<UISprite> 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<long>(closure);
@ -856,6 +865,56 @@ switch (target->derived_type()) \
*
*/
/*
*
* Begin PyTextureType defs
*
*/
typedef struct {
PyObject_HEAD
std::shared_ptr<IndexTexture> 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<char**>(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<IndexTexture>(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

View File

@ -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<UISprite>();
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<UISprite>(
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.