]> git.ipfire.org Git - thirdparty/newt.git/blob - windows.c
0.52.24
[thirdparty/newt.git] / windows.c
1 #include <errno.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "errno.h"
8 #include "newt.h"
9
10 static void * newtvwindow(char * title, char * button1, char * button2,
11 char * button3, char * message, va_list args) {
12 newtComponent b1, b2 = NULL, b3 = NULL, t, f, answer;
13 char * buf = NULL;
14 int size = 0;
15 int i = 0;
16 int scroll = 0;
17 int width, height;
18 char * flowedText;
19 newtGrid grid, buttonGrid;
20
21 do {
22 va_list argscopy;
23
24 va_copy(argscopy, args);
25 size += 1000;
26 if (buf) free(buf);
27 buf = malloc(size);
28 i = vsnprintf(buf, size, message, argscopy);
29 va_end(argscopy);
30 } while (i >= size || i == -1);
31
32 flowedText = newtReflowText(buf, 35, 5, 5, &width, &height);
33 if (height > 6) {
34 free(flowedText);
35 flowedText = newtReflowText(buf, 60, 5, 5, &width, &height);
36 }
37 free(buf);
38
39 if (height > 12) {
40 height = 12;
41 scroll = NEWT_FLAG_SCROLL;
42 }
43 t = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP | scroll);
44 newtTextboxSetText(t, flowedText);
45 free(flowedText);
46
47 if (button3) {
48 buttonGrid = newtButtonBar(button1, &b1, button2, &b2,
49 button3, &b3, NULL);
50 } else if (button2) {
51 buttonGrid = newtButtonBar(button1, &b1, button2, &b2, NULL);
52 } else {
53 buttonGrid = newtButtonBar(button1, &b1, NULL);
54 }
55
56 newtGridSetField(buttonGrid, 0, 0, NEWT_GRID_COMPONENT, b1,
57 0, 0, button2 ? 1 : 0, 0, 0, 0);
58
59 grid = newtCreateGrid(1, 2);
60 newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, t, 0, 0, 0, 0, 0, 0);
61 newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttonGrid,
62 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
63 newtGridWrappedWindow(grid, title);
64
65 f = newtForm(NULL, NULL, 0);
66 newtFormAddComponents(f, t, b1, NULL);
67
68 if (button2)
69 newtFormAddComponent(f, b2);
70 if (button3)
71 newtFormAddComponent(f, b3);
72
73 answer = newtRunForm(f);
74 newtGridFree(grid, 1);
75
76 newtFormDestroy(f);
77 newtPopWindow();
78
79 if (answer == f)
80 return NULL;
81 else if (answer == b1)
82 return button1;
83 else if (answer == b2)
84 return button2;
85
86 return button3;
87 }
88
89 int newtWinChoice(char * title, char * button1, char * button2,
90 char * message, ...) {
91 va_list args;
92 void * rc;
93
94 va_start(args, message);
95 rc = newtvwindow(title, button1, button2, NULL, message, args);
96 va_end(args);
97
98 if (rc == button1)
99 return 1;
100 else if (rc == button2)
101 return 2;
102
103 return 0;
104 }
105
106 void newtWinMessage(char * title, char * buttonText, char * text, ...) {
107 va_list args;
108
109 va_start(args, text);
110 newtvwindow(title, buttonText, NULL, NULL, text, args);
111 va_end(args);
112 }
113
114 void newtWinMessagev(char * title, char * buttonText, char * text,
115 va_list argv) {
116 newtvwindow(title, buttonText, NULL, NULL, text, argv);
117 }
118
119 int newtWinTernary(char * title, char * button1, char * button2,
120 char * button3, char * message, ...) {
121 va_list args;
122 void * rc;
123
124 va_start(args, message);
125 rc = newtvwindow(title, button1, button2, button3, message, args);
126 va_end(args);
127
128 if (rc == button1)
129 return 1;
130 else if (rc == button2)
131 return 2;
132 else if (rc == button3)
133 return 3;
134
135 return 0;
136 }
137
138 int newtWinMenu(char * title, char * text, int suggestedWidth, int flexDown,
139 int flexUp, int maxListHeight, char ** items, int * listItem,
140 char * button1, ...) {
141 newtComponent textbox, listbox, result, form;
142 va_list args;
143 newtComponent *buttons = NULL;
144 newtGrid grid, buttonBar;
145 size_t totalButtons = 0, numButtons = 0;
146 int i, rc;
147 int needScroll;
148 char * buttonName;
149
150 textbox = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown,
151 flexUp, 0);
152
153 for (i = 0; items[i]; i++) ;
154 if (i < maxListHeight) maxListHeight = i;
155 needScroll = i > maxListHeight;
156
157 listbox = newtListbox(-1, -1, maxListHeight,
158 (needScroll ? NEWT_FLAG_SCROLL : 0) | NEWT_FLAG_RETURNEXIT);
159 for (i = 0; items[i]; i++) {
160 newtListboxAddEntry(listbox, items[i], (void *)(long) i);
161 }
162
163 newtListboxSetCurrent(listbox, *listItem);
164
165 va_start(args, button1);
166 for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
167 ++totalButtons;
168 va_end(args);
169
170 buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons));
171 va_start(args, button1);
172 for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
173 buttons[numButtons++] = newtButton(-1, -1, buttonName);
174 va_end(args);
175
176 buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1);
177 for (i = 0; i < numButtons; i++) {
178 newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT,
179 buttons[i],
180 i ? 1 : 0, 0, 0, 0, 0, 0);
181 }
182
183 grid = newtGridSimpleWindow(textbox, listbox, buttonBar);
184 newtGridWrappedWindow(grid, title);
185
186 form = newtForm(NULL, 0, 0);
187 newtGridAddComponentsToForm(grid, form, 1);
188 newtGridFree(grid, 1);
189
190 result = newtRunForm(form);
191
192 *listItem = ((long) newtListboxGetCurrent(listbox));
193
194 for (rc = 0; rc < numButtons && result != buttons[rc]; rc++)
195 ;
196 if (rc == numButtons)
197 rc = 0; /* F12 or return-on-exit (which are the same for us) */
198 else
199 rc++;
200
201 newtFormDestroy(form);
202 newtPopWindow();
203
204 return rc;
205 }
206
207 int newtWinEntries(char * title, char * text, int suggestedWidth, int flexDown,
208 int flexUp, int dataWidth,
209 struct newtWinEntry * items, char * button1, ...) {
210 newtComponent *buttons, result, form, textw;
211 newtGrid grid, buttonBar, subgrid;
212 int numItems;
213 int rc, i;
214 size_t numButtons = 0, totalButtons = 0;
215 char * buttonName;
216 va_list args;
217
218 textw = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown,
219 flexUp, 0);
220
221 for (numItems = 0; items[numItems].text; numItems++);
222
223 va_start(args, button1);
224 for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
225 ++totalButtons;
226 va_end(args);
227
228 buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons));
229 va_start(args, button1);
230 for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
231 buttons[numButtons++] = newtButton(-1, -1, buttonName);
232 va_end(args);
233
234 buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1);
235 for (i = 0; i < numButtons; i++) {
236 newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT,
237 buttons[i],
238 i ? 1 : 0, 0, 0, 0, 0, 0);
239 }
240
241 subgrid = newtCreateGrid(2, numItems ? numItems : 1);
242 for (i = 0; i < numItems; i++) {
243 newtGridSetField(subgrid, 0, i, NEWT_GRID_COMPONENT,
244 newtLabel(-1, -1, items[i].text),
245 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
246 newtGridSetField(subgrid, 1, i, NEWT_GRID_COMPONENT,
247 newtEntry(-1, -1, items[i].value ?
248 *items[i].value : NULL, dataWidth,
249 (const char **)items[i].value, items[i].flags),
250 1, 0, 0, 0, 0, 0);
251 }
252
253 grid = newtCreateGrid(1, 3);
254 form = newtForm(NULL, 0, 0);
255 newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, textw,
256 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
257 newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, subgrid,
258 0, 1, 0, 0, 0, 0);
259 newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttonBar,
260 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
261 newtGridAddComponentsToForm(grid, form, 1);
262 newtGridWrappedWindow(grid, title);
263 newtGridFree(grid, 1);
264
265 result = newtRunForm(form);
266
267 for (rc = 0; rc < numItems; rc++)
268 *items[rc].value = strdup(*items[rc].value);
269
270 for (rc = 0; rc < numButtons && result != buttons[rc]; rc++)
271 ;
272 if (rc == numButtons)
273 rc = 0; /* F12 */
274 else
275 rc++;
276
277 newtFormDestroy(form);
278 newtPopWindow();
279
280 return rc;
281 }