]>
git.ipfire.org Git - thirdparty/newt.git/blob - grid.c
13 enum newtGridElement type
;
18 int padLeft
, padTop
, padRight
, padBottom
;
25 int width
, height
; /* totals, -1 means unknown */
26 struct gridField
** fields
;
29 /* this is a bit of a hack */
30 extern struct componentOps formOps
[];
32 newtGrid
newtCreateGrid(int cols
, int rows
) {
35 grid
= malloc(sizeof(*grid
));
39 grid
->fields
= malloc(sizeof(*grid
->fields
) * cols
);
41 grid
->fields
[cols
] = malloc(sizeof(**(grid
->fields
)) * rows
);
42 memset(grid
->fields
[cols
], 0, sizeof(**(grid
->fields
)) * rows
);
45 grid
->width
= grid
->height
= -1;
50 void newtGridSetField(newtGrid grid
, int col
, int row
,
51 enum newtGridElement type
, void * val
, int padLeft
,
52 int padTop
, int padRight
, int padBottom
, int anchor
,
54 struct gridField
* field
= &grid
->fields
[col
][row
];
56 if (field
->type
== NEWT_GRID_SUBGRID
)
57 newtGridFree(field
->u
.grid
, 1);
60 field
->u
.co
= (void *) val
;
62 field
->padLeft
= padLeft
;
63 field
->padRight
= padRight
;
64 field
->padTop
= padTop
;
65 field
->padBottom
= padBottom
;
66 field
->anchor
= anchor
;
69 grid
->width
= grid
->height
= -1;
72 static void distSpace(int extra
, int items
, int * list
) {
77 for (i
= 0; i
< items
; i
++) {
86 static void shuffleGrid(newtGrid grid
, int left
, int top
, int set
) {
87 struct gridField
* field
;
90 int minWidth
, minHeight
;
91 int * widths
, * heights
;
92 int thisLeft
, thisTop
;
95 widths
= alloca(sizeof(*widths
) * grid
->cols
);
96 memset(widths
, 0, sizeof(*widths
) * grid
->cols
);
97 heights
= alloca(sizeof(*heights
) * grid
->rows
);
98 memset(heights
, 0, sizeof(*heights
) * grid
->rows
);
101 for (row
= 0; row
< grid
->rows
; row
++) {
103 for (col
= 0; col
< grid
->cols
; col
++) {
104 field
= &grid
->fields
[col
][row
];
105 if (field
->type
== NEWT_GRID_SUBGRID
) {
106 /* we'll have to redo this later */
107 if (field
->u
.grid
->width
== -1)
108 shuffleGrid(field
->u
.grid
, left
, top
, 0);
109 j
= field
->u
.grid
->width
;
110 } else if (field
->type
== NEWT_GRID_COMPONENT
) {
111 if (field
->u
.co
->ops
== formOps
)
112 newtFormSetSize(field
->u
.co
);
113 j
= field
->u
.co
->width
;
117 j
+= field
->padLeft
+ field
->padRight
;
119 if (j
> widths
[col
]) widths
[col
] = j
;
123 if (i
> minWidth
) minWidth
= i
;
127 for (col
= 0; col
< grid
->cols
; col
++) {
129 for (row
= 0; row
< grid
->rows
; row
++) {
130 field
= &grid
->fields
[col
][row
];
131 if (field
->type
== NEWT_GRID_SUBGRID
) {
132 /* we'll have to redo this later */
133 if (field
->u
.grid
->height
== -1)
134 shuffleGrid(field
->u
.grid
, 0, 0, 0);
135 j
= field
->u
.grid
->height
;
136 } else if (field
->type
== NEWT_GRID_COMPONENT
){
137 j
= field
->u
.co
->height
;
141 j
+= field
->padTop
+ field
->padBottom
;
143 if (j
> heights
[row
]) heights
[row
] = j
;
147 if (i
> minHeight
) minHeight
= i
;
150 /* this catches the -1 case */
151 if (grid
->width
< minWidth
) grid
->width
= minWidth
; /* ack! */
152 if (grid
->height
< minHeight
) grid
->height
= minHeight
; /* ditto! */
156 distSpace(grid
->width
- minWidth
, grid
->cols
, widths
);
157 distSpace(grid
->height
- minHeight
, grid
->rows
, heights
);
160 for (row
= 0; row
< grid
->rows
; row
++) {
162 for (col
= 0; col
< grid
->cols
; col
++) {
163 field
= &grid
->fields
[col
][row
];
165 if (field
->type
== NEWT_GRID_EMPTY
) continue;
167 x
= thisLeft
+ field
->padLeft
;
168 remx
= widths
[col
] - field
->padLeft
- field
->padRight
;
169 y
= thisTop
+ field
->padTop
;
170 remy
= heights
[row
] - field
->padTop
- field
->padBottom
;
172 if (field
->type
== NEWT_GRID_SUBGRID
) {
173 remx
-= field
->u
.grid
->width
;
174 remy
-= field
->u
.grid
->height
;
175 } else if (field
->type
== NEWT_GRID_COMPONENT
) {
176 remx
-= field
->u
.co
->width
;
177 remy
-= field
->u
.co
->height
;
180 if (!(field
->flags
& NEWT_GRID_FLAG_GROWX
)) {
181 if (field
->anchor
& NEWT_ANCHOR_RIGHT
)
183 else if (!(field
->anchor
& NEWT_ANCHOR_LEFT
))
187 if (!(field
->flags
& NEWT_GRID_FLAG_GROWY
)) {
188 if (field
->anchor
& NEWT_ANCHOR_BOTTOM
)
190 else if (!(field
->anchor
& NEWT_ANCHOR_TOP
))
194 if (field
->type
== NEWT_GRID_SUBGRID
) {
195 if (field
->flags
& NEWT_GRID_FLAG_GROWX
)
196 field
->u
.grid
->width
= widths
[col
] - field
->padLeft
198 if (field
->flags
& NEWT_GRID_FLAG_GROWY
)
199 field
->u
.grid
->height
= heights
[col
] - field
->padTop
202 shuffleGrid(field
->u
.grid
, x
, y
, 1);
203 } else if (field
->type
== NEWT_GRID_COMPONENT
) {
204 field
->u
.co
->ops
->place(field
->u
.co
, x
, y
);
207 thisLeft
+= widths
[col
];
210 thisTop
+= heights
[row
];
214 void newtGridPlace(newtGrid grid
, int left
, int top
) {
215 shuffleGrid(grid
, left
, top
, 1);
218 void newtGridFree(newtGrid grid
, int recurse
) {
221 for (col
= 0; col
< grid
->cols
; col
++) {
223 for (row
= 0; row
< grid
->rows
; row
++) {
224 if (grid
->fields
[col
][row
].type
== NEWT_GRID_SUBGRID
)
225 newtGridFree(grid
->fields
[col
][row
].u
.grid
, 1);
229 free(grid
->fields
[col
]);
236 void newtGridGetSize(newtGrid grid
, int * width
, int * height
) {
237 if (grid
->width
== -1 || grid
->height
== -1) {
238 grid
->width
= grid
->height
= -1;
239 shuffleGrid(grid
, 0, 0, 1);
242 *width
= grid
->width
;
243 *height
= grid
->height
;
246 void newtGridWrappedWindow(newtGrid grid
, char * title
) {
247 int w
, width
, height
, offset
= 0;
249 newtGridGetSize(grid
, &width
, &height
);
250 w
= wstrlen(title
,-1);
252 offset
= ((w
+ 2) - width
) / 2;
255 newtCenteredWindow(width
+ 2, height
+ 2, title
);
256 newtGridPlace(grid
, 1 + offset
, 1);
259 void newtGridWrappedWindowAt(newtGrid grid
, char * title
, int left
, int top
) {
262 newtGridGetSize(grid
, &width
, &height
);
263 newtOpenWindow(left
, top
, width
+ 2, height
+ 2, title
);
264 newtGridPlace(grid
, 1, 1);
267 void newtGridAddComponentsToForm(newtGrid grid
, newtComponent form
,
271 for (col
= 0; col
< grid
->cols
; col
++) {
272 for (row
= 0; row
< grid
->rows
; row
++) {
273 if (grid
->fields
[col
][row
].type
== NEWT_GRID_SUBGRID
&& recurse
)
274 newtGridAddComponentsToForm(grid
->fields
[col
][row
].u
.grid
,
276 else if (grid
->fields
[col
][row
].type
== NEWT_GRID_COMPONENT
)
277 newtFormAddComponent(form
, grid
->fields
[col
][row
].u
.co
);
282 /* this handles up to 50 items */
283 static newtGrid
stackem(int isVert
, enum newtGridElement type1
, void * what1
,
284 va_list args
, int close
) {
286 enum newtGridElement type
;
292 items
[0].type
= type1
, items
[0].what
= what1
, num
= 1;
294 items
[num
].type
= va_arg(args
, enum newtGridElement
);
295 if (items
[num
].type
== NEWT_GRID_EMPTY
) break;
297 items
[num
].what
= va_arg(args
, void *);
301 grid
= newtCreateGrid(isVert
? 1 : num
, isVert
? num
: 1);
303 for (i
= 0; i
< num
; i
++) {
304 newtGridSetField(grid
, isVert
? 0 : i
, isVert
? i
: 0,
305 items
[i
].type
, items
[i
].what
,
306 close
? 0 : (i
? (isVert
? 0 : 1) : 0),
307 close
? 0 : (i
? (isVert
? 1 : 0) : 0), 0, 0, 0, 0);
313 newtGrid
newtGridHCloseStacked(enum newtGridElement type1
, void * what1
, ...) {
317 va_start(args
, what1
);
319 grid
= stackem(0, type1
, what1
, args
, 1);
326 newtGrid
newtGridVCloseStacked(enum newtGridElement type1
, void * what1
, ...) {
330 va_start(args
, what1
);
332 grid
= stackem(1, type1
, what1
, args
, 1);
339 newtGrid
newtGridVStacked(enum newtGridElement type1
, void * what1
, ...) {
343 va_start(args
, what1
);
345 grid
= stackem(1, type1
, what1
, args
, 0);
352 newtGrid
newtGridHStacked(enum newtGridElement type1
, void * what1
, ...) {
356 va_start(args
, what1
);
358 grid
= stackem(0, type1
, what1
, args
, 0);
365 newtGrid
newtGridBasicWindow(newtComponent text
, newtGrid middle
,
369 grid
= newtCreateGrid(1, 3);
370 newtGridSetField(grid
, 0, 0, NEWT_GRID_COMPONENT
, text
,
371 0, 0, 0, 0, NEWT_ANCHOR_LEFT
, 0);
372 newtGridSetField(grid
, 0, 1, NEWT_GRID_SUBGRID
, middle
,
374 newtGridSetField(grid
, 0, 2, NEWT_GRID_SUBGRID
, buttons
,
375 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX
);
380 newtGrid
newtGridSimpleWindow(newtComponent text
, newtComponent middle
,
384 grid
= newtCreateGrid(1, 3);
385 newtGridSetField(grid
, 0, 0, NEWT_GRID_COMPONENT
, text
,
386 0, 0, 0, 0, NEWT_ANCHOR_LEFT
, 0);
387 newtGridSetField(grid
, 0, 1, NEWT_GRID_COMPONENT
, middle
,
389 newtGridSetField(grid
, 0, 2, NEWT_GRID_SUBGRID
, buttons
,
390 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX
);