#include "guecs/lel.hpp" #include #include #include #include "./lel_parser.cpp" namespace lel { Parser::Parser(int x, int y, int width, int height) : grid_x(x), grid_y(y), grid_w(width), grid_h(height) { } void Parser::position(int x, int y, int width, int height) { grid_x = x; grid_y = y; grid_w = width; grid_h = height; // used in GUIs for setting backgrounds main = { .x=grid_x, .y=grid_y, .w=grid_w, .h=grid_h, .mid_x=std::midpoint(grid_x, grid_x + grid_w), .mid_y=std::midpoint(grid_y, grid_y + grid_h), .max_w=grid_w, .max_h=grid_h }; } void Parser::id(const std::string& name) { if(name != "_") { assert(!cells.contains(name) && "duplicate cell name"); cells.insert_or_assign(name, cur); } cur = {.col=cur.col + 1, .row=cur.row}; auto& row = grid.back(); row.push_back(name); } void Parser::finalize() { size_t rows = grid.size(); int cell_height = grid_h / rows; for(auto& row : grid) { // BUG: see issue #16 size_t columns = row.size(); int cell_width = grid_w / columns; assert(cell_width > 0 && "invalid cell width calc"); assert(cell_height > 0 && "invalid cell height calc"); for(auto& name : row) { if(name == "_") continue; auto& cell = cells.at(name); // ZED: getting a bit hairy but this should work if(cell.percent) { // when percent mode we have to take unset to 100% if(cell.max_w == 0) cell.max_w = 100; if(cell.max_h == 0) cell.max_h = 100; cell.max_w *= cell_width * 0.01; cell.max_h *= cell_height * 0.01; } else { if(cell.max_w == 0) cell.max_w = cell_width; if(cell.max_h == 0) cell.max_h = cell_height; } cell.w = cell.expand ? std::min(cell.max_w, grid_w) : std::min(cell_width, cell.max_w); cell.h = cell.expand ? std::min(cell.max_h, grid_h) : std::min(cell_height, cell.max_h); assert(cell.h > 0 && "invalid height cell is <= 0"); assert(cell.w > 0 && "invalid width cell is <= 0"); cell.x = grid_x + (cell.col * cell_width); cell.y = grid_y + (cell.row * cell_height); // keep the midpoint since it is used a lot cell.mid_x = std::midpoint(cell.x, cell.x + cell.w); cell.mid_y = std::midpoint(cell.y, cell.y + cell.h); // perform alignments if(cell.right) cell.x += cell_width - cell.w; if(cell.bottom) cell.y += cell_height - cell.h; if(cell.center) { cell.x = cell.mid_x - cell.w / 2; cell.y = cell.mid_y - cell.h / 2; } } } } void Parser::reset() { cur = {.col=0, .row=0}; main = {.col=0, .row=0}; grid.clear(); cells.clear(); } std::optional Parser::hit(int x, int y) { for(auto& [name, cell] : cells) { if(name != "_MAIN" && (x >= cell.x && x <= cell.x + cell.w) && (y >= cell.y && y <= cell.y + cell.h)) { return name; } } return std::nullopt; } Cell center(int width, int height, Cell &parent) { Cell copy = parent; // BUG: could I use std::midpoint here or am I even using this? copy.x = parent.mid_x - width / 2; copy.y = parent.mid_y - height / 2; copy.w = width; copy.h = height; return copy; } }