From 530a16ec071db0e24e6e949e265a96848864967c Mon Sep 17 00:00:00 2001 From: Antoine Ginies Date: Wed, 19 Jan 2011 10:44:49 +0000 Subject: add mes5-2.6.33 branch --- mdk-stage1/newt/grid.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 mdk-stage1/newt/grid.c (limited to 'mdk-stage1/newt/grid.c') diff --git a/mdk-stage1/newt/grid.c b/mdk-stage1/newt/grid.c new file mode 100644 index 000000000..37d2b2e74 --- /dev/null +++ b/mdk-stage1/newt/grid.c @@ -0,0 +1,389 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct gridField { + enum newtGridElement type; + union { + newtGrid grid; + newtComponent co; + } u; + int padLeft, padTop, padRight, padBottom; + int anchor; + int flags; +}; + +struct grid_s { + int rows, cols; + int width, height; /* totals, -1 means unknown */ + struct gridField ** fields; +}; + +/* this is a bit of a hack */ +extern struct componentOps formOps[]; + +newtGrid newtCreateGrid(int cols, int rows) { + newtGrid grid; + + grid = malloc(sizeof(*grid)); + grid->rows = rows; + grid->cols = cols; + + grid->fields = malloc(sizeof(*grid->fields) * cols); + while (cols--) { + grid->fields[cols] = malloc(sizeof(**(grid->fields)) * rows); + memset(grid->fields[cols], 0, sizeof(**(grid->fields)) * rows); + } + + grid->width = grid->height = -1; + + return grid; +} + +void newtGridSetField(newtGrid grid, int col, int row, + enum newtGridElement type, void * val, int padLeft, + int padTop, int padRight, int padBottom, int anchor, + int flags) { + struct gridField * field = &grid->fields[col][row]; + + if (field->type == NEWT_GRID_SUBGRID) + newtGridFree(field->u.grid, 1); + + field->type = type; + field->u.co = (void *) val; + + field->padLeft = padLeft; + field->padRight = padRight; + field->padTop = padTop; + field->padBottom = padBottom; + field->anchor = anchor; + field->flags = flags; + + grid->width = grid->height = -1; +} + +static void distSpace(int extra, int items, int * list) { + int all, some, i; + + all = extra / items; + some = extra % items; + for (i = 0; i < items; i++) { + list[i] += all; + if (some) { + list[i]++; + some--; + } + } +} + +static void shuffleGrid(newtGrid grid, int left, int top, int set) { + struct gridField * field; + int row, col; + int i, j; + int minWidth, minHeight; + int * widths, * heights; + int thisLeft, thisTop; + int x, y, remx, remy; + + widths = alloca(sizeof(*widths) * grid->cols); + memset(widths, 0, sizeof(*widths) * grid->cols); + heights = alloca(sizeof(*heights) * grid->rows); + memset(heights, 0, sizeof(*heights) * grid->rows); + + minWidth = 0; + for (row = 0; row < grid->rows; row++) { + i = 0; + for (col = 0; col < grid->cols; col++) { + field = &grid->fields[col][row]; + if (field->type == NEWT_GRID_SUBGRID) { + /* we'll have to redo this later */ + if (field->u.grid->width == -1) + shuffleGrid(field->u.grid, left, top, 0); + j = field->u.grid->width; + } else if (field->type == NEWT_GRID_COMPONENT) { + if (field->u.co->ops == formOps) + newtFormSetSize(field->u.co); + j = field->u.co->width; + } else + j = 0; + + j += field->padLeft + field->padRight; + + if (j > widths[col]) widths[col] = j; + i += widths[col]; + } + + if (i > minWidth) minWidth = i; + } + + minHeight = 0; + for (col = 0; col < grid->cols; col++) { + i = 0; + for (row = 0; row < grid->rows; row++) { + field = &grid->fields[col][row]; + if (field->type == NEWT_GRID_SUBGRID) { + /* we'll have to redo this later */ + if (field->u.grid->height == -1) + shuffleGrid(field->u.grid, 0, 0, 0); + j = field->u.grid->height; + } else if (field->type == NEWT_GRID_COMPONENT){ + j = field->u.co->height; + } else + j = 0; + + j += field->padTop + field->padBottom; + + if (j > heights[row]) heights[row] = j; + i += heights[row]; + } + + if (i > minHeight) minHeight = i; + } + + /* this catches the -1 case */ + if (grid->width < minWidth) grid->width = minWidth; /* ack! */ + if (grid->height < minHeight) grid->height = minHeight; /* ditto! */ + + if (!set) return; + + distSpace(grid->width - minWidth, grid->cols, widths); + distSpace(grid->height - minHeight, grid->rows, heights); + + thisTop = top; + for (row = 0; row < grid->rows; row++) { + i = 0; + thisLeft = left; + for (col = 0; col < grid->cols; col++) { + field = &grid->fields[col][row]; + + if (field->type == NEWT_GRID_EMPTY) continue; + + x = thisLeft + field->padLeft; + remx = widths[col] - field->padLeft - field->padRight; + y = thisTop + field->padTop; + remy = heights[row] - field->padTop - field->padBottom; + + if (field->type == NEWT_GRID_SUBGRID) { + remx -= field->u.grid->width; + remy -= field->u.grid->height; + } else if (field->type == NEWT_GRID_COMPONENT) { + remx -= field->u.co->width; + remy -= field->u.co->height; + } + + if (!(field->flags & NEWT_GRID_FLAG_GROWX)) { + if (field->anchor & NEWT_ANCHOR_RIGHT) + x += remx; + else if (!(field->anchor & NEWT_ANCHOR_LEFT)) + x += (remx / 2); + } + + if (!(field->flags & NEWT_GRID_FLAG_GROWY)) { + if (field->anchor & NEWT_ANCHOR_BOTTOM) + y += remx; + else if (!(field->anchor & NEWT_ANCHOR_TOP)) + y += (remy / 2); + } + + if (field->type == NEWT_GRID_SUBGRID) { + if (field->flags & NEWT_GRID_FLAG_GROWX) + field->u.grid->width = widths[col] - field->padLeft + - field->padRight; + if (field->flags & NEWT_GRID_FLAG_GROWY) + field->u.grid->height = heights[col] - field->padTop + - field->padBottom; + + shuffleGrid(field->u.grid, x, y, 1); + } else if (field->type == NEWT_GRID_COMPONENT) { + field->u.co->ops->place(field->u.co, x, y); + } + + thisLeft += widths[col]; + } + + thisTop += heights[row]; + } +} + +void newtGridPlace(newtGrid grid, int left, int top) { + shuffleGrid(grid, left, top, 1); +} + +void newtGridFree(newtGrid grid, int recurse) { + int row, col; + + for (col = 0; col < grid->cols; col++) { + if (recurse) { + for (row = 0; row < grid->rows; row++) { + if (grid->fields[col][row].type == NEWT_GRID_SUBGRID) + newtGridFree(grid->fields[col][row].u.grid, 1); + } + } + + free(grid->fields[col]); + } + + free(grid->fields); + free(grid); +} + +void newtGridGetSize(newtGrid grid, int * width, int * height) { + if (grid->width == -1 || grid->height == -1) { + grid->width = grid->height = -1; + shuffleGrid(grid, 0, 0, 1); + } + + *width = grid->width; + *height = grid->height; +} + +void newtGridWrappedWindow(newtGrid grid, char * title) { + int width, height, offset = 0; + + newtGridGetSize(grid, &width, &height); + if ((size_t)width < strlen(title) + 2) { + offset = ((strlen(title) + 2) - width) / 2; + width = strlen(title) + 2; + } + newtCenteredWindow(width + 2, height + 2, title); + newtGridPlace(grid, 1 + offset, 1); +} + +void newtGridWrappedWindowAt(newtGrid grid, char * title, int left, int top) { + int width, height; + + newtGridGetSize(grid, &width, &height); + newtOpenWindow(left, top, width + 2, height + 2, title); + newtGridPlace(grid, 1, 1); +} + +void newtGridAddComponentsToForm(newtGrid grid, newtComponent form, + int recurse) { + int row, col; + + for (col = 0; col < grid->cols; col++) { + for (row = 0; row < grid->rows; row++) { + if (grid->fields[col][row].type == NEWT_GRID_SUBGRID && recurse) + newtGridAddComponentsToForm(grid->fields[col][row].u.grid, + form, 1); + else if (grid->fields[col][row].type == NEWT_GRID_COMPONENT) + newtFormAddComponent(form, grid->fields[col][row].u.co); + } + } +} + +/* this handles up to 50 items */ +static newtGrid stackem(int isVert, enum newtGridElement type1, void * what1, + va_list args, int close) { + struct item { + enum newtGridElement type; + void * what; + } items[50]; + int i, num; + newtGrid grid; + + items[0].type = type1, items[0].what = what1, num = 1; + while (1) { + items[num].type = va_arg(args, enum newtGridElement); + if (items[num].type == NEWT_GRID_EMPTY) break; + + items[num].what = va_arg(args, void *); + num++; + } + + grid = newtCreateGrid(isVert ? 1 : num, isVert ? num : 1); + + for (i = 0; i < num; i++) { + newtGridSetField(grid, isVert ? 0 : i, isVert ? i : 0, + items[i].type, items[i].what, + close ? 0 : (i ? (isVert ? 0 : 1) : 0), + close ? 0 : (i ? (isVert ? 1 : 0) : 0), 0, 0, 0, 0); + } + + return grid; +} + +newtGrid newtGridHCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(0, type1, what1, args, 1); + + va_start(args, what1); + + return grid; +} + +newtGrid newtGridVCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(1, type1, what1, args, 1); + + va_start(args, what1); + + return grid; +} + +newtGrid newtGridVStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(1, type1, what1, args, 0); + + va_start(args, what1); + + return grid; +} + +newtGrid newtGridHStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(0, type1, what1, args, 0); + + va_start(args, what1); + + return grid; +} + +newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} + +newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} -- cgit v1.2.1