mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-04-23 00:19:31 -04:00
120 lines
4.1 KiB
C++
120 lines
4.1 KiB
C++
#include "GridLayout.hpp"
|
|
#include "Style.hpp"
|
|
#include <log/log.hpp>
|
|
|
|
using namespace gui;
|
|
|
|
GridLayout::GridLayout(
|
|
Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h, GridSize grid)
|
|
: BoxLayout(parent, x, y, w, h), grid(grid)
|
|
{
|
|
setPenWidth(style::window::default_border_no_focus_w);
|
|
setPenFocusWidth(style::window::default_border_no_focus_w);
|
|
}
|
|
|
|
void GridLayout::resizeItems()
|
|
{
|
|
|
|
if (grid.x == 0 || grid.y == 0) {
|
|
LOG_ERROR("Grid == 0 - abort");
|
|
return;
|
|
}
|
|
uint32_t el_in_x = area().w / grid.x;
|
|
uint32_t el_in_y = area().h / grid.y;
|
|
uint32_t strech_x = 0;
|
|
uint32_t strech_y = 0;
|
|
uint32_t max_elements = el_in_x * el_in_y;
|
|
/// cant show elements when size is not set
|
|
if (area().w == 0 || area().h == 0) {
|
|
return;
|
|
}
|
|
|
|
if (children.size() > max_elements) {
|
|
LOG_ERROR("More children than possible to show: %u > %" PRIu32 "",
|
|
static_cast<unsigned int>(children.size()),
|
|
max_elements);
|
|
return;
|
|
}
|
|
if (el_in_x > 2)
|
|
strech_x = (area().w - grid.x * el_in_x) / (el_in_x - 1);
|
|
if (el_in_y > 2)
|
|
strech_y = (area().h - grid.y * el_in_y) / (el_in_y - 1);
|
|
|
|
int row = 0;
|
|
unsigned int col = 0;
|
|
for (auto it : children) {
|
|
// check if element will fit in
|
|
if (it->area().w > grid.x || it->area().h > grid.y) {
|
|
continue;
|
|
}
|
|
it->setPosition(col * (grid.x + strech_x) + (grid.x - it->area().w) / 2,
|
|
row * (grid.y + strech_y) + (grid.y - it->area().h) / 2);
|
|
// shift row/col
|
|
++col;
|
|
if (col == el_in_x) {
|
|
col = 0;
|
|
++row;
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO commomize - move loop to lambda
|
|
void GridLayout::setNavigation()
|
|
{
|
|
uint32_t el_in_x = widgetArea.w / grid.x;
|
|
uint32_t el_in_y = widgetArea.h / grid.y;
|
|
uint32_t max_elements = el_in_x * el_in_y;
|
|
unsigned int i = 0;
|
|
int row = 0;
|
|
unsigned int col = 0;
|
|
if (children.size() == 0) {
|
|
LOG_ERROR("No children to set navigation");
|
|
}
|
|
for (auto it = children.begin(); it != children.end() && i < max_elements; ++it, ++i) {
|
|
// first column left rotation
|
|
if (navigationRotate && col == 0) {
|
|
auto val = el_in_x - 1;
|
|
if (val + i >= children.size()) {
|
|
val = children.size() % el_in_x - 1;
|
|
}
|
|
(*it)->setNavigationItem(NavigationDirection::LEFT, *std::next(it, val));
|
|
}
|
|
else if (i != 0) {
|
|
(*it)->setNavigationItem(NavigationDirection::LEFT, *std::prev(it));
|
|
}
|
|
// last column - right rotation
|
|
if (navigationRotate && col + 1 == el_in_x) {
|
|
auto val = el_in_x - 1;
|
|
(*it)->setNavigationItem(NavigationDirection::RIGHT, *std::prev(it, val));
|
|
}
|
|
else if (col + 1 % el_in_x != 0 && i + 1 < children.size()) {
|
|
(*it)->setNavigationItem(NavigationDirection::RIGHT, *std::next(it));
|
|
}
|
|
if (row != 0) {
|
|
(*it)->setNavigationItem(NavigationDirection::UP, *std::prev(it, el_in_x));
|
|
}
|
|
// first row - rotate UP
|
|
else if (navigationRotate && (children.size() >= el_in_x * 2)) {
|
|
auto maxrow = children.size() / el_in_x + children.size();
|
|
auto val = maxrow * el_in_x + col;
|
|
if (val + el_in_x < children.size()) {
|
|
val += el_in_x;
|
|
}
|
|
(*it)->setNavigationItem(NavigationDirection::UP, *std::next(children.begin(), val));
|
|
}
|
|
if (row + 1 % el_in_y != 0 && i + el_in_x < children.size()) {
|
|
(*it)->setNavigationItem(NavigationDirection::DOWN, *std::next(it, el_in_x));
|
|
}
|
|
// last row - rotate, DOWN assign to first col
|
|
else if (navigationRotate && (i + el_in_x >= children.size())) {
|
|
(*it)->setNavigationItem(NavigationDirection::DOWN, *std::next(children.begin(), col));
|
|
}
|
|
|
|
++col;
|
|
if (col == el_in_x) {
|
|
col = 0;
|
|
++row;
|
|
}
|
|
}
|
|
}
|