From de753713d576d843cadf492a17a19dfed60a0908 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Thu, 2 Mar 2023 18:57:09 -0500 Subject: [PATCH] UI from Python now working fairly comprehensively --- assets/test_portraits.ase | Bin 0 -> 1514 bytes assets/test_portraits.png | Bin 0 -> 1437 bytes src/IndexSprite.cpp | 4 ++ src/IndexSprite.h | 2 + src/IndexTexture.cpp | 5 +++ src/IndexTexture.h | 1 + src/McRFPy_API.cpp | 89 +++++++++++++++++++++++++++++++++++++- src/McRFPy_API.h | 18 +++++--- src/UITestScene.cpp | 6 +++ src/scripts/test_ui.py | 37 ++++++++++++++++ 10 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 assets/test_portraits.ase create mode 100644 assets/test_portraits.png create mode 100644 src/scripts/test_ui.py diff --git a/assets/test_portraits.ase b/assets/test_portraits.ase new file mode 100644 index 0000000000000000000000000000000000000000..e807031110203e621b6b7f340206e4722961e024 GIT binary patch literal 1514 zcmcJLYfO_@7=TZw#d{E^o2Uz&RidD@R)KY;#mj6r%f(9&3OcGt85IEmK@e%wDPC}u zAY+KJ661Lo0!+)OSJUPkv@jUOVAtKas zmw*rf5l8@pj=+6?NbjE?5O?qdw`M(oKXf4x{2i zm}U0NhG&L@Az%W?hjs{uYDk7&h=o$fghmL2I!J>qh=L->nQ6gssDK3UgB;AD1t$o> z1}d8w6KNLk-GKx&2e}=J4U8bsKK#A;!{3{hzyw4RLKbK~!asQ@h(^oM$(y4oRg21~ z3uhlZrrG6puOhbpQ^Vr*4vDsFo=6TbT3g6Gpo%3gwDJgg>m}dEaUbtJvA)q_EcL<}U3TSN z#r{fs(_(e@&A6gbP3llliAJ$RVRup%E~OP!YQKqWm`>f$So+;$et1-5Hpcm@U?9c8 zYdTf#D`$0%c2Ko+xLuHjjdZ5zS3JF4pBdMPr>BS5pR*g(p7y#G z!R4A?2GOjS()W~()OklH^)+Th(N&D-aXoRt*=zO!SOSqmK#S1w|7=8nh_I0WKA&$8 z&!ILD8q~^6G+sWB`AkS^F55~tTo!-7FU^t7=DT#fvS21PPBYs~KWSNUYWK16C!bN? z6r5Uj=FGQJL$xisXt2Dv4R%c={j>1*dlw;_nZ2j^MV$L`?)gGlXpz0$6OL9-)5h%mvyC~At{AEEEOS^sAz!LnJ75wymu8wZv1;Cwmr~xM ztjHO-bHa0A$DpidhvxBuKf0g!Uk!ZC%ug{5jw>z|>Vr*NO~LVNTDN0AAO_k(2mV5g6MVao{$PKsMuVmIuR`$2*$WA<* zBBF?jB;~&OjuHovrE9kL)0QZ!m9-ts#-#YT(VU9Kot`(u?Qe#7uk9oK>4IUluD*@` z;)`L{o+>O$v8CSd>o9wg)cl+r`v5y%tWRK7XZMm{)iP(lgy}n9%kqC~50dm}b;+2m zvwRZXlyHnvB}Fcj9M22T?ox8F<=>m{jWL{JHb~MVyY-Hb4-Rf5Yo{V6)d_l{u|%6C z;f<}#3q9{XTFZ&38<(wO>v_=_IVRIh>HRfk7m~*b?DIK#e{)($p4gDA8nI@mP6X9A z<+1`5M<1~Em2={JiQQ#YJ=|Ikda_vG9-@@K2-3y0^ypr+%}SOJ^xIV6#HF^TroREW C6oL={ literal 0 HcmV?d00001 diff --git a/assets/test_portraits.png b/assets/test_portraits.png new file mode 100644 index 0000000000000000000000000000000000000000..c595de3ce4ad88b4154e052c4a94703a4b976537 GIT binary patch literal 1437 zcmds%>syis0L5S2G%t@nWu~cMd7;cSD!ZuQEH4?DWL}mgW|@~{0|UH}7#K?nHOb}5 zt$@tD&6$~bDIAztR;FkY=ujzMx|%Mu2F5F__Gj#TIp@poJkR-ZI8pd;YfC3f006A9 zyF;S^0QM!q0CTf1MxZvN1Au8NHgsn!{qoGj07VgC2SjZI4-yL7u&Y{tz4jX(mzFv2 zMvSN4%-dQ}dd4Ocj9^pUc)m5Q?jzk-*bErEvhKzpJh)1>*8t6t4l<1pI9;hA7s?h7 zdK;+k>p@XGv}d9Qq#--9%Twy_>{#ZfNQR?Iew}1yL$PR^4JPB@e~hPj36LNN=nQf` zeqpEsGRzNj`up0Rjh=Zj%|4b2=>pGi^*!4>lt!z*m$*;%g?TvMhmZQrRx90}Y1WgR zoPwSe;}|v^W$WMv9f3P&`uur?==U~rI5|-7?+I0g~}Bv>IH@SC{JPqn~ z3ZYzjOi2Y%EFmV?oJLF@nT{mA=Lo3PMh9}wti?xY-EX6HYGbD z|EsIknxd(I%A|1s5y8mrU)9mZ%eNY6a9b)~(yZ@h6)+i<|15DO(9MRg%CI!f@Xyy0 zZCAG|Wonm%r6HaUCy{Tz)K0lX#drhl_k9fUYhUfdR(Y9FR3Y3H*vi1PiI^xAUhwXX zhUQ+cY#cGVFDD_4HHv#;pG1KCsemHQ>|GX3x!|}H{9NdW$e6X2_{ghcE(%M~>nAM6 zpyn;%Yhofyq^hjUM2SYwffm*r!_E@kzg&>!j%-qXZdADxwo9d2_o34?&h`{#^C)A?4gJl-v%P^l z%HGYgbeNVaIm~B?F_ELQbXJp$2K|7^Etlsw9(#Lg9^OV literal 0 HcmV?d00001 diff --git a/src/IndexSprite.cpp b/src/IndexSprite.cpp index f2dbaf0..16d78db 100644 --- a/src/IndexSprite.cpp +++ b/src/IndexSprite.cpp @@ -10,7 +10,11 @@ sf::Sprite IndexSprite::drawable() sf::Sprite s; auto& tex = IndexSprite::game->textures[texture_index]; s.setTexture(tex.texture); + s.setScale(sf::Vector2f(scale, scale)); s.setPosition(sf::Vector2f(x, y)); s.setTextureRect(tex.spriteCoordinates(sprite_index)); return s; } + +IndexSprite::IndexSprite(int _ti, int _si, int _x, int _y, float _s): + texture_index(_ti), sprite_index(_si), x(_x), y(_y), scale(_s) {} diff --git a/src/IndexSprite.h b/src/IndexSprite.h index 60d205b..bad9fd9 100644 --- a/src/IndexSprite.h +++ b/src/IndexSprite.h @@ -5,6 +5,8 @@ class GameEngine; // forward declare class IndexSprite { public: int texture_index, sprite_index, x, y; + float scale; static GameEngine* game; sf::Sprite drawable(); + IndexSprite(int, int, int, int, float); }; diff --git a/src/IndexTexture.cpp b/src/IndexTexture.cpp index 9d82b9a..8dfd220 100644 --- a/src/IndexTexture.cpp +++ b/src/IndexTexture.cpp @@ -4,3 +4,8 @@ sf::IntRect IndexTexture::spriteCoordinates(int index) { int tx = index % grid_width, ty = index / grid_width; return sf::IntRect(tx * grid_size, ty * grid_size, grid_size, grid_size); } + +IndexTexture::IndexTexture (sf::Texture t, int gs, int gw, int gh): + grid_size(gs), grid_width(gw), grid_height(gh) { + texture = t; +} diff --git a/src/IndexTexture.h b/src/IndexTexture.h index 7e39d5b..5de545c 100644 --- a/src/IndexTexture.h +++ b/src/IndexTexture.h @@ -8,4 +8,5 @@ public: int grid_size, grid_width, grid_height; static GameEngine* game; sf::IntRect spriteCoordinates(int); + IndexTexture(sf::Texture, int, int, int); }; diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index e028a4c..4b80664 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -12,11 +12,23 @@ static PyMethodDef mcrfpyMethods[] = { "Draw a sprite (index, x, y)"}, {"createMenu", McRFPy_API::_createMenu, METH_VARARGS, - "Create a new uimenu (x, y, w, h)"}, + "Create a new uimenu (name_str, x, y, w, h)"}, {"listMenus", McRFPy_API::_listMenus, METH_VARARGS, "return a list of existing menus"}, + {"createCaption", McRFPy_API::_createCaption, METH_VARARGS, + "Create a new text caption (menu_str, text_str, fontsize, r, g, b)"}, + + {"createButton", McRFPy_API::_createButton, METH_VARARGS, + "Create a new button (menu_str, x, y, w, h, (bg r, g, b), (text r, g, b), caption, action_code)"}, + + {"createSprite", McRFPy_API::_createSprite, METH_VARARGS, + "Create a new sprite (menu_str, texture_index, sprite_index, x, y, scale)"}, + + {"createTexture", McRFPy_API::_createTexture, METH_VARARGS, + "Create a new texture (filename_str, grid_size, width, height) - grid_size is in pixels (only square sprites for now), width and height are in tiles"}, + {NULL, NULL, 0, NULL} }; @@ -263,9 +275,84 @@ PyObject* McRFPy_API::_listMenus(PyObject*, PyObject*) { return menulist; } +PyObject* McRFPy_API::_createCaption(PyObject* self, PyObject* args) { + const char* menukey_cstr, *text_cstr; + int fontsize, cr, cg, cb; + if (!PyArg_ParseTuple(args, "ssi(iii)", + &menukey_cstr, &text_cstr, + &fontsize, &cr, &cg, &cb)) return NULL; + createCaption(std::string(menukey_cstr), std::string(text_cstr), fontsize, sf::Color(cr, cg, cb)); + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* McRFPy_API::_createButton(PyObject* self, PyObject* args) { + const char *menukey_cstr, *caption_cstr, *action_cstr; + int x, y, w, h, bgr, bgg, bgb, fgr, fgg, fgb; + if (!PyArg_ParseTuple(args, "siiii(iii)(iii)ss", + &menukey_cstr, &x, &y, &w, &h, + &bgr, &bgg, &bgb, &fgr, &fgg, &fgb, + &caption_cstr, &action_cstr + )) return NULL; + createButton(std::string(menukey_cstr), x, y, w, h, sf::Color(bgr, bgg, bgb), sf::Color(fgr, fgg, fgb), std::string(caption_cstr), std::string(action_cstr)); + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* McRFPy_API::_createTexture(PyObject* self, PyObject* args) { + const char *fn_cstr; + int gs, gw, gh; + if (!PyArg_ParseTuple(args, "siii", &fn_cstr, &gs, &gw, &gh)) return NULL; + createTexture(std::string(fn_cstr), gs, gw, gh); + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* McRFPy_API::_listTextures(PyObject*, PyObject*) { + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* McRFPy_API::_createSprite(PyObject* self, PyObject* args) { + const char * menu_cstr; + int ti, si, x, y; + float s; + if (!PyArg_ParseTuple(args, "siiiif", &menu_cstr, &ti, &si, &x, &y, &s)) return NULL; + createSprite(std::string(menu_cstr), ti, si, x, y, s); + Py_INCREF(Py_None); + return Py_None; +} + UIMenu *McRFPy_API::createMenu(int posx, int posy, int sizex, int sizey) { auto m = new UIMenu(game->getFont()); m->box.setPosition(sf::Vector2f(posx, posy)); m->box.setSize(sf::Vector2f(sizex, sizey)); return m; } + +void McRFPy_API::createCaption(std::string menukey, std::string text, int fontsize, sf::Color textcolor) { + auto menu = menus[menukey]; + menu->add_caption(text.c_str(), fontsize, textcolor); +} + +void McRFPy_API::createButton(std::string menukey, int x, int y, int w, int h, sf::Color bgcolor, sf::Color textcolor, std::string caption, std::string action) { + auto menu = menus[menukey]; + auto b = Button(x, y, w, h, bgcolor, textcolor, caption.c_str(), game->getFont(), action.c_str()); + menu->add_button(b); +} + +void McRFPy_API::createSprite(std::string menukey, int ti, int si, int x, int y, float scale) { + auto menu = menus[menukey]; + auto s = IndexSprite(ti, si, x, y, scale); + menu->add_sprite(s); +} + +int McRFPy_API::createTexture(std::string filename, int grid_size, int grid_width, int grid_height) { + sf::Texture t; + t.loadFromFile(filename.c_str()); + t.setSmooth(false); + auto indextex = IndexTexture(t, grid_size, grid_width, grid_height); + game->textures.push_back(indextex); + + return game->textures.size() - 1; +} diff --git a/src/McRFPy_API.h b/src/McRFPy_API.h index 8c7f139..ecff7b3 100644 --- a/src/McRFPy_API.h +++ b/src/McRFPy_API.h @@ -48,20 +48,28 @@ public: // Jank Python Method Exposures static PyObject* _createMenu(PyObject*, PyObject*); // creates a new menu object in McRFPy_API::menus static PyObject* _listMenus(PyObject*, PyObject*); - //static PyObject* _createCaption(PyObject*, PyObject*); // calls menu.add_caption + static PyObject* _createCaption(PyObject*, PyObject*); // calls menu.add_caption + static PyObject* _createButton(PyObject*, PyObject*); + static PyObject* _createTexture(PyObject*, PyObject*); + static PyObject* _listTextures(PyObject*, PyObject*); + static PyObject* _createSprite(PyObject*, PyObject*); + + // use _listMenus, probably will not implement //static PyObject* _listCaptions(PyObject*, PyObject*); - //static PyObject* _createButton(PyObject*, PyObject*); //static PyObject* _listButtons(PyObject*, PyObject*); + //static PyObject* _createEntity(PyObject*, PyObject*); //static PyObject* _listEntities(PyObject*, PyObject*); + //static PyObject* _createGrid(PyObject*, PyObject*); //static PyObject* _listGrids(PyObject*, PyObject*); - //static PyObject* _createSprite(PyObject*, PyObject*); // Jank Functionality static UIMenu* createMenu(int posx, int posy, int sizex, int sizey); - //static Button createButton(UIMenu & menu, int x, int y, int w, int h); - //static sf::Sprite createSprite(int tex_index, int x, int y); + static void createCaption(std::string menukey, std::string text, int fontsize, sf::Color textcolor); + static void createButton(std::string menukey, int x, int y, int w, int h, sf::Color bgcolor, sf::Color textcolor, std::string caption, std::string action); + static void createSprite(std::string menukey, int ti, int si, int x, int y, float scale); + static int createTexture(std::string filename, int grid_size, int grid_width, int grid_height); //static void playSound(const char * filename); //static void playMusic(const char * filename); diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index 0a1438e..6f9cea4 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -274,6 +274,12 @@ void UITestScene::sRender() } + // Python API menus + for (auto pair: McRFPy_API::menus) + { + pair.second->render(game->getWindow()); + } + // test Python sprite code //McRFPy_API::executePyString("mcrfpy.drawSprite(123, 36, 10)"); diff --git a/src/scripts/test_ui.py b/src/scripts/test_ui.py new file mode 100644 index 0000000..5d8b5f1 --- /dev/null +++ b/src/scripts/test_ui.py @@ -0,0 +1,37 @@ +import mcrfpy +mcrfpy.createTexture("./assets/test_portraits.png", 32, 8, 8) +from random import choice, randint + +box_colors = [ + (0, 0, 192), + (0, 192, 0), + (192, 0, 0), + (192, 192, 0), + (0, 192, 192), + (192, 0, 192) + ] + +text_colors = [ + (0, 0, 255), + (0, 255, 0), + (255, 0, 0), + (255, 255, 0), + (0, 255, 255), + (255, 0, 255) + ] + +test_x = 500 +test_y = 10 +for i in range(40): + ui_name = f"test{i}" + mcrfpy.createMenu(ui_name, test_x, test_y, 400, 200) + mcrfpy.createCaption(ui_name, "Hello There", 18, choice(text_colors)) + mcrfpy.createButton(ui_name, 250, 20, 100, 50, choice(box_colors), (0, 0, 0), "asdf", "testaction") + + mcrfpy.createSprite(ui_name, 0, randint(0, 3), 650, 60, 5.0) + + test_x -= 50 + test_y += 50 + if (test_x <= 50): + test_x = 500 + #print(test_x)