diff --git a/demos/meters.cpp b/demos/meters.cpp new file mode 100644 index 0000000..22a9911 --- /dev/null +++ b/demos/meters.cpp @@ -0,0 +1,100 @@ +#include "guecs/sfml/backend.hpp" +#include "guecs/sfml/components.hpp" +#include "guecs/uistack.hpp" +#include "guecs/ui.hpp" +#include +#include +#include +#include +#include + +using namespace std::chrono_literals; + +struct TestMeters { + guecs::UI $gui{}; + + void init() { + $gui.position(0, 0, 1280, 720); + $gui.layout("[meter1][=meter2][meter3][meter4]"); + + for(auto& [name, cell] : $gui.cells()) { + auto gui_id = $gui.entity(name); + + $gui.set(gui_id, {4, {0, 255, 0, 255}}); + $gui.set(gui_id, {1.0f, {255, 0, 0, 255}, 4}); + $gui.set(gui_id, {}); + $gui.set(gui_id, {guecs::to_wstring(name)}); + $gui.set(gui_id, { + [&, gui_id, name](auto) { + auto& meter = $gui.get(gui_id); + meter.percent = meter.percent - 0.1f; + if(meter.percent < 0.0f) { + meter.percent = 1.0f; + } + } + }); + } + + $gui.init(); + } + + void render(sf::RenderTarget& target) { + $gui.render(target); + } + + bool mouse(float x, float y, guecs::Modifiers mods) { + return $gui.mouse(x, y, mods); + } + + void update() { + } +}; + +int main() { + try { + sfml::Backend backend; + guecs::init(&backend); + + sf::RenderWindow window(sf::VideoMode({1280, 720}), "Meter Tester"); + window.setVerticalSyncEnabled(true); + window.setFramerateLimit(60); + window.setPosition({0,0}); + TestMeters gui; + gui.init(); + + while(window.isOpen()) { + while (const auto event = window.pollEvent()) { + if(event->is()) { + window.close(); + } + + if(const auto* mouse = event->getIf()) { + if(mouse->button == sf::Mouse::Button::Left) { + sf::Vector2f pos = window.mapPixelToCoords(mouse->position); + gui.mouse(pos.x, pos.y, false); + } + } else if(const auto* key = event->getIf()) { + using KEY = sf::Keyboard::Scan; + + switch(key->scancode) { + case KEY::Q: + return 0; + default: + break; + } + } + } + + gui.update(); + gui.render(window); + window.display(); + + std::this_thread::sleep_for(100ms); + } + } catch(const std::system_error& e) { + std::cout << "WARNING: On OSX you'll get this error on shutdown.\n"; + std::cout << "Caught system_error with code " + "[" << e.code() << "] meaning " + "[" << e.what() << "]\n"; + } +} diff --git a/include/guecs/sfml/components.hpp b/include/guecs/sfml/components.hpp index 017e7dc..234f1b4 100644 --- a/include/guecs/sfml/components.hpp +++ b/include/guecs/sfml/components.hpp @@ -69,11 +69,16 @@ namespace guecs { struct Meter { float percent = 1.0f; sf::Color color = THEME.BG_COLOR_DARK; - Rectangle bar; + int padding = THEME.PADDING; + Rectangle bar{padding, color}; + // this is set automatically if a Rectangle is configured for the cell + Rectangle backing_rect{padding, color}; + size_t $cell_w = 0; + size_t $cell_h = 0; + void init(lel::Cell& cell, guecs::Rectangle &bg); void init(lel::Cell& cell); - void init(lel::Cell& cell, Rectangle& bg); - void render(lel::Cell& cell, sf::RenderTarget& window, sf::Shader *shader_ptr); + void render(sf::RenderTarget& window, sf::Shader *shader_ptr); }; struct Effect { diff --git a/meson.build b/meson.build index 59e925e..15a920f 100644 --- a/meson.build +++ b/meson.build @@ -11,8 +11,12 @@ project('lel-guecs', 'cpp', # use this for common options only for our executables cpp_args=[ - '-Wno-deprecated-declarations', '-I../subprojects/utf8cpp-4.0.9/source', + '-Wno-unused-parameter', + '-Wno-unused-function', + '-Wno-unused-variable', + '-Wno-unused-but-set-variable', + '-Wno-deprecated-declarations', ] link_args=[] # these are passed as override_defaults @@ -156,3 +160,13 @@ executable('multiscreen', [ include_directories: lel_guecs_inc, link_with: [lel_guecs_lib, lel_guecs_sfml_lib], dependencies: dependencies) + +executable('meters', [ + 'demos/meters.cpp', + ], + cpp_args: cpp_args, + link_args: link_args, + override_options: exe_defaults, + include_directories: lel_guecs_inc, + link_with: [lel_guecs_lib, lel_guecs_sfml_lib], + dependencies: dependencies) diff --git a/src/guecs/sfml/components.cpp b/src/guecs/sfml/components.cpp index 7172ee8..6c1fadb 100644 --- a/src/guecs/sfml/components.cpp +++ b/src/guecs/sfml/components.cpp @@ -8,19 +8,18 @@ namespace guecs { using std::make_shared; // BUG: this seems to center things wrong in lel layouts - template - void sfml_center_helper(T& obj, lel::Cell& cell, int padding) { - sf::Vector2f position{float(cell.x + padding), float(cell.y + padding)}; + void sfml_center_helper(auto& obj, lel::Cell& cell, int padding) { + sf::Vector2f position{float(cell.x + padding), float(cell.y + padding)}; - if(cell.center) { - auto bounds = obj->getLocalBounds(); - position = {float(cell.mid_x), float(cell.mid_y)}; - obj->setOrigin({bounds.size.x/2, bounds.size.y/2}); - } - - obj->setPosition(position); + if(cell.center) { + auto bounds = obj->getLocalBounds(); + position = {float(cell.mid_x), float(cell.mid_y)}; + obj->setOrigin({bounds.size.x/2, bounds.size.y/2}); } + obj->setPosition(position); + } + inline SpriteTexture load_texture(const string& name, bool is_icon) { if(is_icon) { return BACKEND->get_icon(name); @@ -109,19 +108,20 @@ namespace guecs { } void Meter::init(lel::Cell& cell, Rectangle& bg) { - bg.shape->setFillColor(color); + backing_rect = bg; init(cell); } void Meter::init(lel::Cell& cell) { + $cell_w = cell.w; + $cell_h = cell.h; bar.init(cell); } - void Meter::render(lel::Cell& cell, sf::RenderTarget& window, sf::Shader *shader_ptr) { - float level = std::clamp(percent, 0.0f, 1.0f) * float(cell.w); - // ZED: this 6 is a border width, make it a thing - bar.shape->setSize({std::max(level, 0.0f), float(cell.h - 6)}); - window.draw(*bar.shape, shader_ptr); + void Meter::render(sf::RenderTarget& window, sf::Shader *shader_ptr) { + float level = std::clamp(percent, 0.0f, 1.0f) * float($cell_w); + bar.shape->setSize({std::max(level, 0.0f) - padding * 2, float($cell_h) - padding * 2}); + bar.render(window, shader_ptr); } void Sound::play(bool hover) { diff --git a/src/guecs/ui.cpp b/src/guecs/ui.cpp index 7fe3f58..84215f2 100644 --- a/src/guecs/ui.cpp +++ b/src/guecs/ui.cpp @@ -135,9 +135,9 @@ namespace guecs { rect.render(window, shader_ptr); }); - query([&](auto ent, auto& cell, auto &meter) { + query([&](auto ent, auto &meter) { auto shader_ptr = find_shader(ent, true); - meter.render(cell, window, shader_ptr); + meter.render(window, shader_ptr); }); query([&](auto ent, auto& sprite) {