diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 019ab74..e5621f0 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -56,7 +56,7 @@ PyObject* PyInit_mcrfpy() using namespace mcrfpydef; PyTypeObject* pytypes[] = { /*SFML exposed types*/ - &PyColorType, &PyLinkedColorType, &PyFontType, &PyTextureType, + &PyColorType, /*&PyLinkedColorType,*/ &PyFontType, &PyTextureType, /*UI widgets*/ &PyUICaptionType, &PyUISpriteType, &PyUIFrameType, &PyUIEntityType, &PyUIGridType, diff --git a/src/PyColor.cpp b/src/PyColor.cpp index 434a963..50eae73 100644 --- a/src/PyColor.cpp +++ b/src/PyColor.cpp @@ -14,6 +14,7 @@ PyColor::PyColor(sf::Color target) PyObject* PyColor::pyObject() { PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyColorType, 0); + Py_INCREF(obj); PyColorObject* self = (PyColorObject*)obj; self->data = data; return obj; @@ -57,7 +58,7 @@ PyObject* PyColor::repr(PyObject* obj) PyColorObject* self = (PyColorObject*)obj; std::ostringstream ss; sf::Color c = self->data; - ss << ""; + ss << ""; std::string repr_str = ss.str(); return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); @@ -66,8 +67,69 @@ PyObject* PyColor::repr(PyObject* obj) int PyColor::init(PyColorObject* self, PyObject* args, PyObject* kwds) { + using namespace mcrfpydef; static const char* keywords[] = { "r", "g", "b", "a", nullptr }; - // TODO + PyObject* leader; + int r = -1, g = -1, b = -1, a = 255; + if (!PyArg_ParseTupleAndKeywords, args, kwds, "O|iii", leader, &g, &b, &a) + { + PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + + // if the "r" arg is already a color, yoink that color value + if (PyObject_IsInstance(leader, (PyObject*)&PyColorType)) + { + self->data = ((PyColorObject*)leader)->data; + return 0; + } + // else if the "r" arg is a 3-tuple, initialize to (r, g, b, 255) + // (if the "r" arg is a 4-tuple, initialize to (r, g, b, a)) + else if (PyTuple_Check(leader)) + { + if (PyTuple_Size(leader) < 3 && PyTuple_Size(leader) > 4) + { + PyErr_SetString(PyExc_TypeError, "Invalid tuple length: mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + r = PyLong_AsLong(PyTuple_GetItem(leader, 0)); + g = PyLong_AsLong(PyTuple_GetItem(leader, 1)); + b = PyLong_AsLong(PyTuple_GetItem(leader, 2)); + //a = 255; //default value + + if (PyTuple_Size(leader) == 4) + { + a = PyLong_AsLong(PyTuple_GetItem(leader, 3)); + } + + // value validation + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) + { + PyErr_SetString(PyExc_ValueError, "Color values must be between 0 and 255."); + return -1; + } + self->data = sf::Color(r, g, b, a); + } + // else if the "r" arg is a string, initialize to {color lookup function value} + else if (PyUnicode_Check(leader)) + { + PyErr_SetString(Py_NotImplemented, "Color names aren't ready yet"); + return -1; + } + // else - + else if (!PyLong_Check(leader)) + { + PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); + return -1; + } + r = PyLong_AsLong(leader); + // assert r, g, b are present and ints in range (0, 255) - if not enough ints were provided to the args/kwds parsed by init, g and/or b will still hold -1. + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) + { + PyErr_SetString(PyExc_ValueError, "R, G, B values are required, A value is optional; Color values must be between 0 and 255."); + return -1; + } + self->data = sf::Color(r, g, b, a); return 0; } @@ -78,10 +140,12 @@ PyObject* PyColor::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds) PyObject* PyColor::get_member(PyObject* obj, void* closure) { + // TODO return Py_None; } int PyColor::set_member(PyObject* obj, PyObject* value, void* closure) { + // TODO return 0; } diff --git a/src/UI.h b/src/UI.h index 384cfda..f0f64db 100644 --- a/src/UI.h +++ b/src/UI.h @@ -11,7 +11,7 @@ #include "PyCallable.h" #include "PyTexture.h" #include "PyColor.h" -#include "PyLinkedColor.h" +//#include "PyLinkedColor.h" enum PyObjectsEnum : int { @@ -610,38 +610,38 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c */ // fetch correct member data - //sf::Color color; + sf::Color color; //sf::Color (*cgetter)(); //void (*csetter)(sf::Color); - std::function csetter; - std::function cgetter; + //std::function csetter; + //std::function cgetter; if (member_ptr == 0) { - //color = self->data->text.getFillColor(); + color = self->data->text.getFillColor(); //return Py_BuildValue("(iii)", color.r, color.g, color.b); //csetter = &self->data->text.setFillColor; //cgetter = &self->data->text.getFillColor; - csetter = [s = self->data](sf::Color c){s->text.setFillColor(c);}; - cgetter = [s = self->data](){return s->text.getFillColor();}; + //csetter = [s = self->data](sf::Color c){s->text.setFillColor(c);}; + //cgetter = [s = self->data](){return s->text.getFillColor();}; } else if (member_ptr == 1) { - //color = self->data->text.getOutlineColor(); + color = self->data->text.getOutlineColor(); //return Py_BuildValue("(iii)", color.r, color.g, color.b); //csetter = &self->data->text.setOutlineColor; //cgetter = &self->data->text.getOutlineColor; - csetter = [s = self->data](sf::Color c){s->text.setOutlineColor(c);}; - cgetter = [s = self->data](){return s->text.getOutlineColor();}; + //csetter = [s = self->data](sf::Color c){s->text.setOutlineColor(c);}; + //cgetter = [s = self->data](){return s->text.getOutlineColor();}; } // initialize new mcrfpy.Color instance //pyColorObj->data = std::make_shared(color); //PyLinkedColor::fromPy(pyColorObj).set(color); - auto linkedcolor = PyLinkedColor(csetter, cgetter, self->data, member_ptr); + //auto linkedcolor = PyLinkedColor(csetter, cgetter, self->data, member_ptr); //linkedcolor.set(color); // don't need to set a linked color! //return pyColor; - return linkedcolor.pyObject(); + return PyColor(color).pyObject(); } static int PyUICaption_set_color_member(PyUICaptionObject* self, PyObject* value, void* closure) @@ -649,7 +649,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c auto member_ptr = reinterpret_cast(closure); //TODO: this logic of (PyColor instance OR tuple -> sf::color) should be encapsulated for reuse int r, g, b, a; - if (PyObject_IsInstance(value, (PyObject*)&PyLinkedColorType)) + if (PyObject_IsInstance(value, (PyObject*)&PyColorType)) { // get value from mcrfpy.Color instance /* @@ -659,10 +659,11 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c b = color->data->b; a = color->data->a; */ - std::cout << "Build LinkedColor" << std::endl; - auto lc = PyLinkedColor::fromPy(value); - std::cout << "Fetch value" << std::endl; - auto c = lc.get(); + //std::cout << "Build LinkedColor" << std::endl; + //auto lc = PyLinkedColor::fromPy(value); + auto c = ((PyColorObject*)value)->data; + //std::cout << "Fetch value" << std::endl; + //auto c = lc.get(); r = c.r; g = c.g; b = c.b; a = c.a; std::cout << "got " << int(r) << ", " << int(g) << ", " << int(b) << ", " << int(a) << std::endl; } diff --git a/src/scripts/game.py b/src/scripts/game.py index 2975588..8e28bc3 100644 --- a/src/scripts/game.py +++ b/src/scripts/game.py @@ -1,221 +1,51 @@ -#print("Hello mcrogueface") import mcrfpy -import cos_play -# Universal stuff font = mcrfpy.Font("assets/JetbrainsMono.ttf") -texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) -texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) -texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) +texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) -# Test stuff -mcrfpy.createScene("boom") -mcrfpy.setScene("boom") -ui = mcrfpy.sceneUI("boom") -box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) -ui.append(box) +# build test widgets -#caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) -#box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) -#box.children.append(caption) +mcrfpy.createScene("pytest") +mcrfpy.setScene("pytest") +ui = mcrfpy.sceneUI("pytest") -test_sprite_number = 86 -sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) -spritecap = mcrfpy.Caption(5, 5, "60", font) -def click_sprite(x, y, btn, action): - global test_sprite_number - if action != "start": return - if btn in ("left", "wheel_up"): - test_sprite_number -= 1 - elif btn in ("right", "wheel_down"): - test_sprite_number += 1 - sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index - spritecap.text = test_sprite_number +# Frame +f = mcrfpy.Frame(25, 19, 462, 346, fill_color=(255, 92, 92)) +# fill (LinkedColor / Color): f.fill_color +# outline (LinkedColor / Color): f.outline_color +# pos (LinkedVector / Vector): f.pos +# size (LinkedVector / Vector): f.size -sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking -box.children.append(sprite) -box.children.append(spritecap) -box.click = click_sprite +# Caption +c = mcrfpy.Caption(512+25, 19, "Hi.", font) +# fill (LinkedColor / Color): c.fill_color +#color_val = c.fill_color +print(c.fill_color) +print("Set a fill color") +c.fill_color = (255, 255, 255) +print("Lol, did it segfault?") +# outline (LinkedColor / Color): c.outline_color +# font (Font): c.font +# pos (LinkedVector / Vector): c.pos -f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) -f_a_txt = mcrfpy.Caption(5, 5, "0", font) +# Sprite +s = mcrfpy.Sprite(25, 384+19, texture, 86, 9.0) +# pos (LinkedVector / Vector): s.pos +# texture (Texture): s.texture -f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) -f_b_txt = mcrfpy.Caption(5, 5, "0", font) +# Grid +g = mcrfpy.Grid(10, 10, texture, 512+25, 384+19, 462, 346) +# texture (Texture): g.texture +# pos (LinkedVector / Vector): g.pos +# size (LinkedVector / Vector): g.size -f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) -f_c_txt = mcrfpy.Caption(5, 5, "0", font) +for _x in range(10): + for _y in range(10): + g.at((_x, _y)).color = (255 - _x*25, 255 - _y*25, 255) +g.zoom = 2.0 +[ui.append(d) for d in (f, c, s, g)] -ui.append(f_a) -f_a.children.append(f_a_txt) -ui.append(f_b) -f_b.children.append(f_b_txt) -ui.append(f_c) -f_c.children.append(f_c_txt) +print("built!") -import sys -def ding(*args): - f_a_txt.text = str(sys.getrefcount(ding)) + " refs" - f_b_txt.text = sys.getrefcount(dong) - f_c_txt.text = sys.getrefcount(stress_test) +# tests -def dong(*args): - f_a_txt.text = str(sys.getrefcount(ding)) + " refs" - f_b_txt.text = sys.getrefcount(dong) - f_c_txt.text = sys.getrefcount(stress_test) - -running = False -timers = [] - -def add_ding(): - global timers - n = len(timers) - mcrfpy.setTimer(f"timer{n}", ding, 100) - print("+1 ding:", timers) - -def add_dong(): - global timers - n = len(timers) - mcrfpy.setTimer(f"timer{n}", dong, 100) - print("+1 dong:", timers) - -def remove_random(): - global timers - target = random.choice(timers) - print("-1 timer:", target) - print("remove from list") - timers.remove(target) - print("delTimer") - mcrfpy.delTimer(target) - print("done") - -import random -import time -def stress_test(*args): - global running - global timers - if not running: - print("stress test initial") - running = True - timers.append("recurse") - add_ding() - add_dong() - mcrfpy.setTimer("recurse", stress_test, 1000) - mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) - ding(); dong() - else: - #print("stress test random activity") - #random.choice([ - # add_ding, - # add_dong, - # remove_random - # ])() - #print(timers) - print("Segfaultin' time") - mcrfpy.delTimer("recurse") - print("Does this still work?") - time.sleep(0.5) - print("How about now?") - - -stress_test() - - -# Loading Screen -mcrfpy.createScene("loading") -ui = mcrfpy.sceneUI("loading") -#mcrfpy.setScene("loading") -logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) -logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) -ui.append(logo_sprite) -logo_sprite.click = lambda *args: mcrfpy.setScene("menu") -logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) -#logo_caption.fill_color =(255, 0, 0, 255) -ui.append(logo_caption) - - -# menu screen -mcrfpy.createScene("menu") - -for e in [ - mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), - mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), - mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), - mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), - #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), - ]: - mcrfpy.sceneUI("menu").append(e) - -def click_once(fn): - def wraps(*args, **kwargs): - #print(args) - action = args[3] - if action != "start": return - return fn(*args, **kwargs) - return wraps - -@click_once -def asdf(x, y, btn, action): - print(f"clicky @({x},{y}) {action}->{btn}") - -@click_once -def clicked_exit(*args): - mcrfpy.exit() - -menu_btns = [ - ("Boom", lambda *args: 1 / 0), - ("Exit", clicked_exit), - ("About", lambda *args: mcrfpy.setScene("about")), - ("Settings", lambda *args: mcrfpy.setScene("settings")), - ("Start", lambda *args: mcrfpy.setScene("play")) - ] -for i in range(len(mcrfpy.sceneUI("menu"))): - e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator - #print(e, type(e)) - if type(e) is not mcrfpy.Frame: continue - label, fn = menu_btns.pop() - #print(label) - e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) - e.click = fn - - -# settings screen -mcrfpy.createScene("settings") -window_scaling = 1.0 - -scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) -#scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors -for e in [ - mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), - mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + - mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - - mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), - scale_caption, - ]: - mcrfpy.sceneUI("settings").append(e) - -@click_once -def game_scale(x, y, btn, action, delta): - global window_scaling - print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") - window_scaling += delta - scale_caption.text = f"{window_scaling:.1f}x" - mcrfpy.setScale(window_scaling) - #mcrfpy.setScale(2) - -settings_btns = [ - ("back", lambda *args: mcrfpy.setScene("menu")), - ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), - ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) - ] - -for i in range(len(mcrfpy.sceneUI("settings"))): - e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator - #print(e, type(e)) - if type(e) is not mcrfpy.Frame: continue - label, fn = settings_btns.pop() - #print(label, fn) - e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) - e.click = fn diff --git a/src/scripts/game_old.py b/src/scripts/game_old.py new file mode 100644 index 0000000..2975588 --- /dev/null +++ b/src/scripts/game_old.py @@ -0,0 +1,221 @@ +#print("Hello mcrogueface") +import mcrfpy +import cos_play +# Universal stuff +font = mcrfpy.Font("assets/JetbrainsMono.ttf") +texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) +texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) +texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) + +# Test stuff +mcrfpy.createScene("boom") +mcrfpy.setScene("boom") +ui = mcrfpy.sceneUI("boom") +box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) +ui.append(box) + +#caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) +#box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) +#box.children.append(caption) + +test_sprite_number = 86 +sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) +spritecap = mcrfpy.Caption(5, 5, "60", font) +def click_sprite(x, y, btn, action): + global test_sprite_number + if action != "start": return + if btn in ("left", "wheel_up"): + test_sprite_number -= 1 + elif btn in ("right", "wheel_down"): + test_sprite_number += 1 + sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index + spritecap.text = test_sprite_number + +sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking +box.children.append(sprite) +box.children.append(spritecap) +box.click = click_sprite + +f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) +f_a_txt = mcrfpy.Caption(5, 5, "0", font) + +f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) +f_b_txt = mcrfpy.Caption(5, 5, "0", font) + +f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) +f_c_txt = mcrfpy.Caption(5, 5, "0", font) + + +ui.append(f_a) +f_a.children.append(f_a_txt) +ui.append(f_b) +f_b.children.append(f_b_txt) +ui.append(f_c) +f_c.children.append(f_c_txt) + +import sys +def ding(*args): + f_a_txt.text = str(sys.getrefcount(ding)) + " refs" + f_b_txt.text = sys.getrefcount(dong) + f_c_txt.text = sys.getrefcount(stress_test) + +def dong(*args): + f_a_txt.text = str(sys.getrefcount(ding)) + " refs" + f_b_txt.text = sys.getrefcount(dong) + f_c_txt.text = sys.getrefcount(stress_test) + +running = False +timers = [] + +def add_ding(): + global timers + n = len(timers) + mcrfpy.setTimer(f"timer{n}", ding, 100) + print("+1 ding:", timers) + +def add_dong(): + global timers + n = len(timers) + mcrfpy.setTimer(f"timer{n}", dong, 100) + print("+1 dong:", timers) + +def remove_random(): + global timers + target = random.choice(timers) + print("-1 timer:", target) + print("remove from list") + timers.remove(target) + print("delTimer") + mcrfpy.delTimer(target) + print("done") + +import random +import time +def stress_test(*args): + global running + global timers + if not running: + print("stress test initial") + running = True + timers.append("recurse") + add_ding() + add_dong() + mcrfpy.setTimer("recurse", stress_test, 1000) + mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) + ding(); dong() + else: + #print("stress test random activity") + #random.choice([ + # add_ding, + # add_dong, + # remove_random + # ])() + #print(timers) + print("Segfaultin' time") + mcrfpy.delTimer("recurse") + print("Does this still work?") + time.sleep(0.5) + print("How about now?") + + +stress_test() + + +# Loading Screen +mcrfpy.createScene("loading") +ui = mcrfpy.sceneUI("loading") +#mcrfpy.setScene("loading") +logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) +logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) +ui.append(logo_sprite) +logo_sprite.click = lambda *args: mcrfpy.setScene("menu") +logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) +#logo_caption.fill_color =(255, 0, 0, 255) +ui.append(logo_caption) + + +# menu screen +mcrfpy.createScene("menu") + +for e in [ + mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), + mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), + mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), + mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), + #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), + ]: + mcrfpy.sceneUI("menu").append(e) + +def click_once(fn): + def wraps(*args, **kwargs): + #print(args) + action = args[3] + if action != "start": return + return fn(*args, **kwargs) + return wraps + +@click_once +def asdf(x, y, btn, action): + print(f"clicky @({x},{y}) {action}->{btn}") + +@click_once +def clicked_exit(*args): + mcrfpy.exit() + +menu_btns = [ + ("Boom", lambda *args: 1 / 0), + ("Exit", clicked_exit), + ("About", lambda *args: mcrfpy.setScene("about")), + ("Settings", lambda *args: mcrfpy.setScene("settings")), + ("Start", lambda *args: mcrfpy.setScene("play")) + ] +for i in range(len(mcrfpy.sceneUI("menu"))): + e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator + #print(e, type(e)) + if type(e) is not mcrfpy.Frame: continue + label, fn = menu_btns.pop() + #print(label) + e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) + e.click = fn + + +# settings screen +mcrfpy.createScene("settings") +window_scaling = 1.0 + +scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) +#scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors +for e in [ + mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), + mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + + mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - + mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), + scale_caption, + ]: + mcrfpy.sceneUI("settings").append(e) + +@click_once +def game_scale(x, y, btn, action, delta): + global window_scaling + print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") + window_scaling += delta + scale_caption.text = f"{window_scaling:.1f}x" + mcrfpy.setScale(window_scaling) + #mcrfpy.setScale(2) + +settings_btns = [ + ("back", lambda *args: mcrfpy.setScene("menu")), + ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), + ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) + ] + +for i in range(len(mcrfpy.sceneUI("settings"))): + e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator + #print(e, type(e)) + if type(e) is not mcrfpy.Frame: continue + label, fn = settings_btns.pop() + #print(label, fn) + e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) + e.click = fn