#ifndef TILING_DECL_H #define TILING_DECL_H #include "io/sysio.h" #include "utils/utils.h" struct Tile { bool hidden = false; uint32_t weight = 100; virtual void render(std::vector &buffer, Coord size, Coord pos) = 0; virtual void handle_click(KeyEvent event, Coord size) = 0; virtual ~Tile() = default; }; struct Window : Tile { virtual ~Window() = default; virtual void handle_event(KeyEvent){}; virtual void handle_command(std::string &) {}; virtual void work() {}; virtual std::array bar_info() { return {}; }; }; struct TileBlock : Tile { bool vertical; std::vector> tiles; void render(std::vector &buffer, Coord size, Coord pos) override { uint32_t total_weight = 0; for (auto &t : tiles) { if (!t->hidden) total_weight += t->weight; } if (total_weight == 0) return; for (auto &t : tiles) { if (t->hidden) continue; uint32_t proportion = t->weight * (vertical ? size.row : size.col) / total_weight; Coord tile_size = vertical ? Coord{.row = proportion, .col = size.col} : Coord{.row = size.row, .col = proportion}; t->render(buffer, tile_size, pos); if (vertical) pos.row += tile_size.row; else pos.col += tile_size.col; } } void handle_click(KeyEvent event, Coord size) override { uint32_t total_weight = 0; for (auto &t : tiles) if (!t->hidden) total_weight += t->weight; if (total_weight == 0) return; uint32_t i = 0; for (auto &t : tiles) { if (t->hidden) continue; uint32_t proportion = t->weight * (vertical ? size.row : size.col) / total_weight; Coord tile_size = vertical ? Coord{.row = proportion, .col = size.col} : Coord{.row = size.row, .col = proportion}; if (vertical) { if (event.mouse_y < i + proportion) { event.mouse_y -= i; t->handle_click(event, tile_size); return; } } else { if (event.mouse_x < i + proportion) { event.mouse_x -= i; t->handle_click(event, tile_size); return; } } i += proportion; } } }; struct TileRoot { std::unique_ptr tile; Coord pos; Coord size; void render(std::vector &buffer) { if (this->tile->hidden) return; this->tile->render(buffer, size, pos); } void handle_click(KeyEvent event) { event.mouse_x -= this->pos.col; event.mouse_y -= this->pos.row; this->tile->handle_click(event, size); } bool inside(uint32_t x, uint32_t y) { return x >= pos.col && x < pos.col + size.col && y >= pos.row && y < pos.row + size.row; } }; extern TileRoot root_tile; extern std::vector> popups; extern Window *focused_window; inline void close_popup(TileRoot *handle) { auto it = std::find_if(popups.begin(), popups.end(), [handle](const auto &p) { return p.get() == handle; }); if (it != popups.end()) popups.erase(it); } void render(); void handle_click(KeyEvent event); #endif