120 lines
3.0 KiB
C++
120 lines
3.0 KiB
C++
#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<ScreenCell> &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<std::string, 5> bar_info() { return {}; };
|
|
};
|
|
|
|
struct Popup : Window {
|
|
Coord pos;
|
|
Coord size;
|
|
virtual ~Popup() = default;
|
|
};
|
|
|
|
struct TileBlock : Tile {
|
|
bool vertical;
|
|
std::vector<std::unique_ptr<Tile>> tiles;
|
|
|
|
void render(std::vector<ScreenCell> &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 TileBase {
|
|
std::unique_ptr<Tile> tile;
|
|
Coord pos;
|
|
Coord size;
|
|
|
|
inline bool hidden() { return this->tile->hidden; }
|
|
void render(std::vector<ScreenCell> &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);
|
|
}
|
|
};
|
|
|
|
namespace layout {
|
|
extern TileBase root_tile;
|
|
extern Window *focused_window;
|
|
extern std::vector<std::unique_ptr<Popup>> popups;
|
|
extern std::vector<std::unique_ptr<TileBase>> floating_tiles;
|
|
} // namespace layout
|
|
|
|
void render();
|
|
void handle_click(KeyEvent event);
|
|
|
|
#endif
|