/** * 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) { grid->breakpointCount = 0x00; grid->breakpointCurrent = 0x00; grid->childCount = 0x00; grid->width = 0; grid->height = 0; grid->onResize = NULL; } uint8_t gridAddBreakpoint( grid_t *grid, float width, uint8_t rows, uint8_t columns, float gutterX, float gutterY ) { uint8_t i = grid->breakpointCount++; grid->breakpoints[i].rows = rows; grid->breakpoints[i].columns = columns; grid->breakpoints[i].gutterX = gutterX; grid->breakpoints[i].gutterY = gutterY; grid->breakpointSizes[i].width = width; return i; } gridchild_t * gridAddChild(grid_t *grid) { gridchild_t *child = grid->children + grid->childCount++; child->breakpointCount = 0; return child; } uint8_t gridChildAddBreakpoint(gridchild_t *child, uint8_t x, uint8_t y, uint8_t columns, uint8_t rows ) { uint8_t i; gridchildbreakpoint_t *bp; i = child->breakpointCount++; bp = child->breakpoints + i; bp->x = x; bp->y = y; bp->rows = rows; bp->columns = columns; return i; } gridchildbreakpoint_t * gridChildGetBreakpoint(gridchild_t *child, uint8_t bp) { return child->breakpoints + ( bp >= child->breakpointCount ? child->breakpointCount - 1 : bp ); } void gridSetSize(grid_t *grid, float screenWidth, float screenHeight, float width, float height, float x, float y ) { uint8_t i, breakpoint; gridchild_t *child; gridchildbreakpoint_t *childbp; gridbreakpoint_t *gridbp; float sizeCol, sizeRow, gx, gy, gw, gh; // Need to resize? if(grid->width == width && grid->height == height) { return; } // Update properties grid->width = width; grid->height = height; // Determine breakpoint breakpoint = 0xFF; for(i = 0; i < grid->breakpointCount; i++) { if(grid->breakpointSizes[i].width < screenWidth) continue; breakpoint = i; } if(breakpoint == 0xFF) breakpoint = grid->breakpointCount - 1; gridbp = grid->breakpoints + breakpoint; grid->breakpointCurrent = breakpoint; // Determine the size of a single column/row sizeCol = (width - (gridbp->gutterX * (gridbp->columns-1))) / gridbp->columns; sizeRow = (height - (gridbp->gutterY * (gridbp->rows - 1))) / gridbp->rows; if(grid->onResize == NULL) return; // Resize children for(i = 0; i < grid->childCount; i++) { // Get the item and the definition. child = grid->children + i; childbp = gridChildGetBreakpoint(child, breakpoint); // Get the local X/Y gx = (sizeCol * childbp->x) + (gridbp->gutterX * childbp->x); gy = (sizeRow * childbp->y) + (gridbp->gutterY * childbp->y); // Get the width/height gw = ( (childbp->columns * sizeCol) + (mathMax(childbp->columns - 1, 0) * gridbp->gutterX) ); gh = ( (childbp->rows * sizeRow) + (mathMax(childbp->rows - 1, 0) * gridbp->gutterY) ); // Fire the resize event. grid->onResize( grid->user, i, screenWidth, screenHeight, x + gx, y + gy, gw, gh ); } }