1 |
|
|
/* $OpenBSD: m_post.c,v 1.7 2010/01/12 23:22:08 nicm Exp $ */ |
2 |
|
|
|
3 |
|
|
/**************************************************************************** |
4 |
|
|
* Copyright (c) 1998-2003,2004 Free Software Foundation, Inc. * |
5 |
|
|
* * |
6 |
|
|
* Permission is hereby granted, free of charge, to any person obtaining a * |
7 |
|
|
* copy of this software and associated documentation files (the * |
8 |
|
|
* "Software"), to deal in the Software without restriction, including * |
9 |
|
|
* without limitation the rights to use, copy, modify, merge, publish, * |
10 |
|
|
* distribute, distribute with modifications, sublicense, and/or sell * |
11 |
|
|
* copies of the Software, and to permit persons to whom the Software is * |
12 |
|
|
* furnished to do so, subject to the following conditions: * |
13 |
|
|
* * |
14 |
|
|
* The above copyright notice and this permission notice shall be included * |
15 |
|
|
* in all copies or substantial portions of the Software. * |
16 |
|
|
* * |
17 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * |
18 |
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * |
19 |
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * |
20 |
|
|
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * |
21 |
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * |
22 |
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * |
23 |
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. * |
24 |
|
|
* * |
25 |
|
|
* Except as contained in this notice, the name(s) of the above copyright * |
26 |
|
|
* holders shall not be used in advertising or otherwise to promote the * |
27 |
|
|
* sale, use or other dealings in this Software without prior written * |
28 |
|
|
* authorization. * |
29 |
|
|
****************************************************************************/ |
30 |
|
|
|
31 |
|
|
/**************************************************************************** |
32 |
|
|
* Author: Juergen Pfeifer, 1995,1997 * |
33 |
|
|
****************************************************************************/ |
34 |
|
|
|
35 |
|
|
/*************************************************************************** |
36 |
|
|
* Module m_post * |
37 |
|
|
* Write or erase menus from associated subwindows * |
38 |
|
|
***************************************************************************/ |
39 |
|
|
|
40 |
|
|
#include "menu.priv.h" |
41 |
|
|
|
42 |
|
|
MODULE_ID("$Id: m_post.c,v 1.7 2010/01/12 23:22:08 nicm Exp $") |
43 |
|
|
|
44 |
|
|
/*--------------------------------------------------------------------------- |
45 |
|
|
| Facility : libnmenu |
46 |
|
|
| Function : void _nc_Post_Item(MENU *menu, ITEM *item) |
47 |
|
|
| |
48 |
|
|
| Description : Draw the item in the menus window at the current |
49 |
|
|
| window position |
50 |
|
|
| |
51 |
|
|
| Return Values : - |
52 |
|
|
+--------------------------------------------------------------------------*/ |
53 |
|
|
NCURSES_EXPORT(void) |
54 |
|
|
_nc_Post_Item(const MENU * menu, const ITEM * item) |
55 |
|
|
{ |
56 |
|
|
int i; |
57 |
|
|
chtype ch; |
58 |
|
|
int item_x, item_y; |
59 |
|
|
int count = 0; |
60 |
|
|
bool isfore = FALSE, isback = FALSE, isgrey = FALSE; |
61 |
|
|
int name_len; |
62 |
|
|
int desc_len; |
63 |
|
|
|
64 |
|
|
assert(menu->win); |
65 |
|
|
|
66 |
|
|
getyx(menu->win, item_y, item_x); |
67 |
|
|
|
68 |
|
|
/* We need a marker iff |
69 |
|
|
- it is a onevalued menu and it is the current item |
70 |
|
|
- or it has a selection value |
71 |
|
|
*/ |
72 |
|
|
wattron(menu->win, menu->back); |
73 |
|
|
if (item->value || (item == menu->curitem)) |
74 |
|
|
{ |
75 |
|
|
if (menu->marklen) |
76 |
|
|
{ |
77 |
|
|
/* In a multi selection menu we use the fore attribute |
78 |
|
|
for a selected marker that is not the current one. |
79 |
|
|
This improves visualization of the menu, because now |
80 |
|
|
always the 'normal' marker denotes the current |
81 |
|
|
item. */ |
82 |
|
|
if (!(menu->opt & O_ONEVALUE) && item->value && item != menu->curitem) |
83 |
|
|
{ |
84 |
|
|
wattron(menu->win, menu->fore); |
85 |
|
|
isfore = TRUE; |
86 |
|
|
} |
87 |
|
|
waddstr(menu->win, menu->mark); |
88 |
|
|
if (isfore) |
89 |
|
|
{ |
90 |
|
|
wattron(menu->win, menu->fore); |
91 |
|
|
isfore = FALSE; |
92 |
|
|
} |
93 |
|
|
} |
94 |
|
|
} |
95 |
|
|
else /* otherwise we have to wipe out the marker area */ |
96 |
|
|
for (ch = ' ', i = menu->marklen; i > 0; i--) |
97 |
|
|
waddch(menu->win, ch); |
98 |
|
|
wattroff(menu->win, menu->back); |
99 |
|
|
count += menu->marklen; |
100 |
|
|
|
101 |
|
|
/* First we have to calculate the attribute depending on selectability |
102 |
|
|
and selection status |
103 |
|
|
*/ |
104 |
|
|
if (!(item->opt & O_SELECTABLE)) |
105 |
|
|
{ |
106 |
|
|
wattron(menu->win, menu->grey); |
107 |
|
|
isgrey = TRUE; |
108 |
|
|
} |
109 |
|
|
else |
110 |
|
|
{ |
111 |
|
|
if (item->value || item == menu->curitem) |
112 |
|
|
{ |
113 |
|
|
wattron(menu->win, menu->fore); |
114 |
|
|
isfore = TRUE; |
115 |
|
|
} |
116 |
|
|
else |
117 |
|
|
{ |
118 |
|
|
wattron(menu->win, menu->back); |
119 |
|
|
isback = TRUE; |
120 |
|
|
} |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
waddnstr(menu->win, item->name.str, item->name.length); |
124 |
|
|
name_len = _nc_Calculate_Text_Width(&(item->name)); |
125 |
|
|
for (ch = ' ', i = menu->namelen - name_len; i > 0; i--) |
126 |
|
|
{ |
127 |
|
|
waddch(menu->win, ch); |
128 |
|
|
} |
129 |
|
|
count += menu->namelen; |
130 |
|
|
|
131 |
|
|
/* Show description if required and available */ |
132 |
|
|
if ((menu->opt & O_SHOWDESC) && menu->desclen > 0) |
133 |
|
|
{ |
134 |
|
|
int m = menu->spc_desc / 2; |
135 |
|
|
int cy = -1, cx = -1; |
136 |
|
|
|
137 |
|
|
for (ch = ' ', i = 0; i < menu->spc_desc; i++) |
138 |
|
|
{ |
139 |
|
|
if (i == m) |
140 |
|
|
{ |
141 |
|
|
waddch(menu->win, menu->pad); |
142 |
|
|
getyx(menu->win, cy, cx); |
143 |
|
|
} |
144 |
|
|
else |
145 |
|
|
waddch(menu->win, ch); |
146 |
|
|
} |
147 |
|
|
if (item->description.length) |
148 |
|
|
waddnstr(menu->win, item->description.str, item->description.length); |
149 |
|
|
desc_len = _nc_Calculate_Text_Width(&(item->description)); |
150 |
|
|
for (ch = ' ', i = menu->desclen - desc_len; i > 0; i--) |
151 |
|
|
{ |
152 |
|
|
waddch(menu->win, ch); |
153 |
|
|
} |
154 |
|
|
count += menu->desclen + menu->spc_desc; |
155 |
|
|
|
156 |
|
|
if (menu->spc_rows > 1) |
157 |
|
|
{ |
158 |
|
|
int j, k, ncy, ncx; |
159 |
|
|
|
160 |
|
|
assert(cx >= 0 && cy >= 0); |
161 |
|
|
getyx(menu->win, ncy, ncx); |
162 |
|
|
if (isgrey) |
163 |
|
|
wattroff(menu->win, menu->grey); |
164 |
|
|
else if (isfore) |
165 |
|
|
wattroff(menu->win, menu->fore); |
166 |
|
|
wattron(menu->win, menu->back); |
167 |
|
|
for (j = 1; j < menu->spc_rows; j++) |
168 |
|
|
{ |
169 |
|
|
if ((item_y + j) < getmaxy(menu->win)) |
170 |
|
|
{ |
171 |
|
|
wmove(menu->win, item_y + j, item_x); |
172 |
|
|
for (k = 0; k < count; k++) |
173 |
|
|
waddch(menu->win, ' '); |
174 |
|
|
} |
175 |
|
|
if ((cy + j) < getmaxy(menu->win)) |
176 |
|
|
mvwaddch(menu->win, cy + j, cx - 1, menu->pad); |
177 |
|
|
} |
178 |
|
|
wmove(menu->win, ncy, ncx); |
179 |
|
|
if (!isback) |
180 |
|
|
wattroff(menu->win, menu->back); |
181 |
|
|
} |
182 |
|
|
} |
183 |
|
|
|
184 |
|
|
/* Remove attributes */ |
185 |
|
|
if (isfore) |
186 |
|
|
wattroff(menu->win, menu->fore); |
187 |
|
|
if (isback) |
188 |
|
|
wattroff(menu->win, menu->back); |
189 |
|
|
if (isgrey) |
190 |
|
|
wattroff(menu->win, menu->grey); |
191 |
|
|
} |
192 |
|
|
|
193 |
|
|
/*--------------------------------------------------------------------------- |
194 |
|
|
| Facility : libnmenu |
195 |
|
|
| Function : void _nc_Draw_Menu(const MENU *) |
196 |
|
|
| |
197 |
|
|
| Description : Display the menu in its windows |
198 |
|
|
| |
199 |
|
|
| Return Values : - |
200 |
|
|
+--------------------------------------------------------------------------*/ |
201 |
|
|
NCURSES_EXPORT(void) |
202 |
|
|
_nc_Draw_Menu(const MENU * menu) |
203 |
|
|
{ |
204 |
|
|
ITEM *item = menu->items[0]; |
205 |
|
|
ITEM *lasthor, *lastvert; |
206 |
|
|
ITEM *hitem; |
207 |
|
|
int y = 0; |
208 |
|
|
chtype s_bkgd; |
209 |
|
|
|
210 |
|
|
assert(item && menu->win); |
211 |
|
|
|
212 |
|
|
s_bkgd = getbkgd(menu->win); |
213 |
|
|
wbkgdset(menu->win, menu->back); |
214 |
|
|
werase(menu->win); |
215 |
|
|
wbkgdset(menu->win, s_bkgd); |
216 |
|
|
|
217 |
|
|
lastvert = (menu->opt & O_NONCYCLIC) ? (ITEM *) 0 : item; |
218 |
|
|
|
219 |
|
|
do |
220 |
|
|
{ |
221 |
|
|
wmove(menu->win, y, 0); |
222 |
|
|
|
223 |
|
|
hitem = item; |
224 |
|
|
lasthor = (menu->opt & O_NONCYCLIC) ? (ITEM *) 0 : hitem; |
225 |
|
|
|
226 |
|
|
do |
227 |
|
|
{ |
228 |
|
|
_nc_Post_Item(menu, hitem); |
229 |
|
|
|
230 |
|
|
wattron(menu->win, menu->back); |
231 |
|
|
if (((hitem = hitem->right) != lasthor) && hitem) |
232 |
|
|
{ |
233 |
|
|
int i, j, cy, cx; |
234 |
|
|
chtype ch = ' '; |
235 |
|
|
|
236 |
|
|
getyx(menu->win, cy, cx); |
237 |
|
|
for (j = 0; j < menu->spc_rows; j++) |
238 |
|
|
{ |
239 |
|
|
wmove(menu->win, cy + j, cx); |
240 |
|
|
for (i = 0; i < menu->spc_cols; i++) |
241 |
|
|
{ |
242 |
|
|
waddch(menu->win, ch); |
243 |
|
|
} |
244 |
|
|
} |
245 |
|
|
wmove(menu->win, cy, cx + menu->spc_cols); |
246 |
|
|
} |
247 |
|
|
} |
248 |
|
|
while (hitem && (hitem != lasthor)); |
249 |
|
|
wattroff(menu->win, menu->back); |
250 |
|
|
|
251 |
|
|
item = item->down; |
252 |
|
|
y += menu->spc_rows; |
253 |
|
|
|
254 |
|
|
} |
255 |
|
|
while (item && (item != lastvert)); |
256 |
|
|
} |
257 |
|
|
|
258 |
|
|
/*--------------------------------------------------------------------------- |
259 |
|
|
| Facility : libnmenu |
260 |
|
|
| Function : int post_menu(MENU *) |
261 |
|
|
| |
262 |
|
|
| Description : Post a menu to the screen. This makes it visible. |
263 |
|
|
| |
264 |
|
|
| Return Values : E_OK - success |
265 |
|
|
| E_BAD_ARGUMENT - not a valid menu pointer |
266 |
|
|
| E_SYSTEM_ERROR - error in lower layers |
267 |
|
|
| E_NOT_CONNECTED - No items connected to menu |
268 |
|
|
| E_BAD_STATE - Menu in userexit routine |
269 |
|
|
| E_POSTED - Menu already posted |
270 |
|
|
+--------------------------------------------------------------------------*/ |
271 |
|
|
NCURSES_EXPORT(int) |
272 |
|
|
post_menu(MENU * menu) |
273 |
|
|
{ |
274 |
|
|
T((T_CALLED("post_menu(%p)"), menu)); |
275 |
|
|
|
276 |
|
|
if (!menu) |
277 |
|
|
RETURN(E_BAD_ARGUMENT); |
278 |
|
|
|
279 |
|
|
if (menu->status & _IN_DRIVER) |
280 |
|
|
RETURN(E_BAD_STATE); |
281 |
|
|
|
282 |
|
|
if (menu->status & _POSTED) |
283 |
|
|
RETURN(E_POSTED); |
284 |
|
|
|
285 |
|
|
if (menu->items && *(menu->items)) |
286 |
|
|
{ |
287 |
|
|
int y; |
288 |
|
|
int h = 1 + menu->spc_rows * (menu->rows - 1); |
289 |
|
|
|
290 |
|
|
WINDOW *win = Get_Menu_Window(menu); |
291 |
|
|
int maxy = getmaxy(win); |
292 |
|
|
|
293 |
|
|
if ((menu->win = newpad(h, menu->width))) |
294 |
|
|
{ |
295 |
|
|
y = (maxy >= h) ? h : maxy; |
296 |
|
|
if (y >= menu->height) |
297 |
|
|
y = menu->height; |
298 |
|
|
if (!(menu->sub = subpad(menu->win, y, menu->width, 0, 0))) |
299 |
|
|
RETURN(E_SYSTEM_ERROR); |
300 |
|
|
} |
301 |
|
|
else |
302 |
|
|
RETURN(E_SYSTEM_ERROR); |
303 |
|
|
|
304 |
|
|
if (menu->status & _LINK_NEEDED) |
305 |
|
|
_nc_Link_Items(menu); |
306 |
|
|
} |
307 |
|
|
else |
308 |
|
|
RETURN(E_NOT_CONNECTED); |
309 |
|
|
|
310 |
|
|
menu->status |= _POSTED; |
311 |
|
|
|
312 |
|
|
if (!(menu->opt & O_ONEVALUE)) |
313 |
|
|
{ |
314 |
|
|
ITEM **items; |
315 |
|
|
|
316 |
|
|
for (items = menu->items; *items; items++) |
317 |
|
|
{ |
318 |
|
|
(*items)->value = FALSE; |
319 |
|
|
} |
320 |
|
|
} |
321 |
|
|
|
322 |
|
|
_nc_Draw_Menu(menu); |
323 |
|
|
|
324 |
|
|
Call_Hook(menu, menuinit); |
325 |
|
|
Call_Hook(menu, iteminit); |
326 |
|
|
|
327 |
|
|
_nc_Show_Menu(menu); |
328 |
|
|
|
329 |
|
|
RETURN(E_OK); |
330 |
|
|
} |
331 |
|
|
|
332 |
|
|
/*--------------------------------------------------------------------------- |
333 |
|
|
| Facility : libnmenu |
334 |
|
|
| Function : int unpost_menu(MENU *) |
335 |
|
|
| |
336 |
|
|
| Description : Detach menu from screen |
337 |
|
|
| |
338 |
|
|
| Return Values : E_OK - success |
339 |
|
|
| E_BAD_ARGUMENT - not a valid menu pointer |
340 |
|
|
| E_BAD_STATE - menu in userexit routine |
341 |
|
|
| E_NOT_POSTED - menu is not posted |
342 |
|
|
+--------------------------------------------------------------------------*/ |
343 |
|
|
NCURSES_EXPORT(int) |
344 |
|
|
unpost_menu(MENU * menu) |
345 |
|
|
{ |
346 |
|
|
WINDOW *win; |
347 |
|
|
|
348 |
|
|
T((T_CALLED("unpost_menu(%p)"), menu)); |
349 |
|
|
|
350 |
|
|
if (!menu) |
351 |
|
|
RETURN(E_BAD_ARGUMENT); |
352 |
|
|
|
353 |
|
|
if (menu->status & _IN_DRIVER) |
354 |
|
|
RETURN(E_BAD_STATE); |
355 |
|
|
|
356 |
|
|
if (!(menu->status & _POSTED)) |
357 |
|
|
RETURN(E_NOT_POSTED); |
358 |
|
|
|
359 |
|
|
Call_Hook(menu, itemterm); |
360 |
|
|
Call_Hook(menu, menuterm); |
361 |
|
|
|
362 |
|
|
win = Get_Menu_Window(menu); |
363 |
|
|
werase(win); |
364 |
|
|
wsyncup(win); |
365 |
|
|
|
366 |
|
|
assert(menu->sub); |
367 |
|
|
delwin(menu->sub); |
368 |
|
|
menu->sub = (WINDOW *)0; |
369 |
|
|
|
370 |
|
|
assert(menu->win); |
371 |
|
|
delwin(menu->win); |
372 |
|
|
menu->win = (WINDOW *)0; |
373 |
|
|
|
374 |
|
|
menu->status &= ~_POSTED; |
375 |
|
|
|
376 |
|
|
RETURN(E_OK); |
377 |
|
|
} |
378 |
|
|
|
379 |
|
|
/* m_post.c ends here */ |