/** * Copyright (c) 2021 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "grid.h" void gridInit(grid_t *grid) { uint8_t i; grid->columns = 1; grid->rows = 1; grid->gutterX = 0; grid->gutterY = 0; grid->borderX = 0; grid->borderY = 0; grid->width = 1; grid->height = 1; for(i = 0; i < GRID_COLUMN_COUNT_MAX; i++) { grid->columnDefinitions[i] = GRID_CEL_SIZE_AUTO; } for(i = 0; i < GRID_ROW_COUNT_MAX; i++) { grid->rowDefinitions[i] = GRID_CEL_SIZE_AUTO; } } void gridRecalculate(grid_t *grid) { uint8_t i, countFlexiColumns, countFlexiRows; float flexiWidth, flexiHeight, s, p, totalFlexiWidth, totalFlexiHeight; // Pass 1, determine the "flexible width size" countFlexiColumns = 0; countFlexiRows = 0; totalFlexiWidth = ( grid->width - (grid->gutterX * mathMax(grid->columns-1, 0)) - (grid->borderX * 2.0f) ); totalFlexiHeight = ( grid->height - (grid->gutterY * mathMax(grid->rows-1, 0)) - (grid->borderY * 2.0f) ); for(i = 0; i < grid->columns; i++) { if(grid->columnDefinitions[i] == GRID_CEL_SIZE_AUTO) { countFlexiColumns++; } else { totalFlexiWidth -= grid->columnDefinitions[i]; } } for(i = 0; i < grid->rows; i++) { if(grid->rowDefinitions[i] == GRID_CEL_SIZE_AUTO) { countFlexiRows++; } else { totalFlexiHeight -= grid->rowDefinitions[i]; } } // Determine the "flexi size for each flexi cell" flexiWidth = totalFlexiWidth / countFlexiColumns; flexiHeight = totalFlexiHeight / countFlexiRows; // Now set up the positions and sizes for each cell. p = grid->borderX; for(i = 0; i < grid->columns; i++) { s = grid->columnDefinitions[i]; if(s == GRID_CEL_SIZE_AUTO) s = flexiWidth; grid->columnPositions[i] = p; grid->columnSizes[i] = s; p += s + grid->gutterX; } p = grid->borderY; for(i = 0; i < grid->rows; i++) { s = grid->rowDefinitions[i]; if(s == GRID_CEL_SIZE_AUTO) s = flexiHeight; grid->rowPositions[i] = p; grid->rowSizes[i] = s; p += s + grid->gutterY; } } void gridResize(grid_t *grid, float width, float height) { if(grid->width == width && grid->height == height) return; grid->width = width; grid->height = height; gridRecalculate(grid); } void gridGetChild( grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows, float *x, float *y, float *width, float *height ) { uint8_t i; float s; // Set positions *x = grid->columnPositions[col]; *y = grid->rowPositions[row]; // Calculate width. s = 0; for(i = col; i < col+columns; i++) { s += grid->columnSizes[i]; } *width = s; // Calculate height s = 0; for(i = row; i < row+rows; i++) { s += grid->rowSizes[i]; } *height = s; } align_t gridGetAndAlignChild( grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows, uint8_t alignX, uint8_t alignY, float width, float height ) { float gx, gy, gw, gh; // Get the size of the child first gridGetChild(grid, col, row, columns, rows, &gx, &gy, &gw, &gh); // Now align align_t align = alignmentGet(alignX, alignY, gw, gh, width, height, -1,-1); align.x += gx; align.y += gy; return align; }