1 /****************************************************************************
2 * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /****************************************************************************
30 * Author: Juergen Pfeifer, 1995,1997 *
31 ****************************************************************************/
33 /***************************************************************************
35 * Write or erase menus from associated subwindows *
36 ***************************************************************************/
38 #include "menu.priv.h"
40 MODULE_ID("$Id: m_post.c,v 1.29 2010/05/01 19:18:27 tom Exp $")
42 /*---------------------------------------------------------------------------
44 | Function : void _nc_Post_Item(MENU *menu, ITEM *item)
46 | Description : Draw the item in the menus window at the current
50 +--------------------------------------------------------------------------*/
52 _nc_Post_Item(const MENU
* menu
, const ITEM
* item
)
58 bool isfore
= FALSE
, isback
= FALSE
, isgrey
= FALSE
;
64 getyx(menu
->win
, item_y
, item_x
);
66 /* We need a marker iff
67 - it is a onevalued menu and it is the current item
68 - or it has a selection value
70 wattron(menu
->win
, menu
->back
);
71 if (item
->value
|| (item
== menu
->curitem
))
75 /* In a multi selection menu we use the fore attribute
76 for a selected marker that is not the current one.
77 This improves visualization of the menu, because now
78 always the 'normal' marker denotes the current
80 if (!(menu
->opt
& O_ONEVALUE
) && item
->value
&& item
!= menu
->curitem
)
82 wattron(menu
->win
, menu
->fore
);
85 waddstr(menu
->win
, menu
->mark
);
88 wattron(menu
->win
, menu
->fore
);
93 else /* otherwise we have to wipe out the marker area */
94 for (ch
= ' ', i
= menu
->marklen
; i
> 0; i
--)
95 waddch(menu
->win
, ch
);
96 wattroff(menu
->win
, menu
->back
);
97 count
+= menu
->marklen
;
99 /* First we have to calculate the attribute depending on selectability
102 if (!(item
->opt
& O_SELECTABLE
))
104 wattron(menu
->win
, menu
->grey
);
109 if (item
->value
|| item
== menu
->curitem
)
111 wattron(menu
->win
, menu
->fore
);
116 wattron(menu
->win
, menu
->back
);
121 waddnstr(menu
->win
, item
->name
.str
, item
->name
.length
);
122 name_len
= _nc_Calculate_Text_Width(&(item
->name
));
123 for (ch
= ' ', i
= menu
->namelen
- name_len
; i
> 0; i
--)
125 waddch(menu
->win
, ch
);
127 count
+= menu
->namelen
;
129 /* Show description if required and available */
130 if ((menu
->opt
& O_SHOWDESC
) && menu
->desclen
> 0)
132 int m
= menu
->spc_desc
/ 2;
133 int cy
= -1, cx
= -1;
135 for (ch
= ' ', i
= 0; i
< menu
->spc_desc
; i
++)
139 waddch(menu
->win
, menu
->pad
);
140 getyx(menu
->win
, cy
, cx
);
143 waddch(menu
->win
, ch
);
145 if (item
->description
.length
)
146 waddnstr(menu
->win
, item
->description
.str
, item
->description
.length
);
147 desc_len
= _nc_Calculate_Text_Width(&(item
->description
));
148 for (ch
= ' ', i
= menu
->desclen
- desc_len
; i
> 0; i
--)
150 waddch(menu
->win
, ch
);
152 count
+= menu
->desclen
+ menu
->spc_desc
;
154 if (menu
->spc_rows
> 1)
158 assert(cx
>= 0 && cy
>= 0);
159 getyx(menu
->win
, ncy
, ncx
);
161 wattroff(menu
->win
, menu
->grey
);
163 wattroff(menu
->win
, menu
->fore
);
164 wattron(menu
->win
, menu
->back
);
165 for (j
= 1; j
< menu
->spc_rows
; j
++)
167 if ((item_y
+ j
) < getmaxy(menu
->win
))
169 wmove(menu
->win
, item_y
+ j
, item_x
);
170 for (k
= 0; k
< count
; k
++)
171 waddch(menu
->win
, ' ');
173 if ((cy
+ j
) < getmaxy(menu
->win
))
174 (void)mvwaddch(menu
->win
, cy
+ j
, cx
- 1, menu
->pad
);
176 wmove(menu
->win
, ncy
, ncx
);
178 wattroff(menu
->win
, menu
->back
);
182 /* Remove attributes */
184 wattroff(menu
->win
, menu
->fore
);
186 wattroff(menu
->win
, menu
->back
);
188 wattroff(menu
->win
, menu
->grey
);
191 /*---------------------------------------------------------------------------
192 | Facility : libnmenu
193 | Function : void _nc_Draw_Menu(const MENU *)
195 | Description : Display the menu in its windows
198 +--------------------------------------------------------------------------*/
200 _nc_Draw_Menu(const MENU
* menu
)
202 ITEM
*item
= menu
->items
[0];
203 ITEM
*lasthor
, *lastvert
;
208 assert(item
&& menu
->win
);
210 s_bkgd
= getbkgd(menu
->win
);
211 wbkgdset(menu
->win
, menu
->back
);
213 wbkgdset(menu
->win
, s_bkgd
);
215 lastvert
= (menu
->opt
& O_NONCYCLIC
) ? (ITEM
*) 0 : item
;
219 wmove(menu
->win
, y
, 0);
222 lasthor
= (menu
->opt
& O_NONCYCLIC
) ? (ITEM
*) 0 : hitem
;
226 _nc_Post_Item(menu
, hitem
);
228 wattron(menu
->win
, menu
->back
);
229 if (((hitem
= hitem
->right
) != lasthor
) && hitem
)
234 getyx(menu
->win
, cy
, cx
);
235 for (j
= 0; j
< menu
->spc_rows
; j
++)
237 wmove(menu
->win
, cy
+ j
, cx
);
238 for (i
= 0; i
< menu
->spc_cols
; i
++)
240 waddch(menu
->win
, ch
);
243 wmove(menu
->win
, cy
, cx
+ menu
->spc_cols
);
246 while (hitem
&& (hitem
!= lasthor
));
247 wattroff(menu
->win
, menu
->back
);
253 while (item
&& (item
!= lastvert
));
256 /*---------------------------------------------------------------------------
257 | Facility : libnmenu
258 | Function : int post_menu(MENU* menu)
260 | Description : Post a menu to the screen. This makes it visible.
262 | Return Values : E_OK - success
263 | E_BAD_ARGUMENT - not a valid menu pointer
264 | E_SYSTEM_ERROR - error in lower layers
265 | E_NOT_CONNECTED - No items connected to menu
266 | E_BAD_STATE - Menu in userexit routine
267 | E_POSTED - Menu already posted
268 +--------------------------------------------------------------------------*/
270 post_menu(MENU
* menu
)
272 T((T_CALLED("post_menu(%p)"), (void *)menu
));
275 RETURN(E_BAD_ARGUMENT
);
277 if (menu
->status
& _IN_DRIVER
)
280 if (menu
->status
& _POSTED
)
283 if (menu
->items
&& *(menu
->items
))
286 int h
= 1 + menu
->spc_rows
* (menu
->rows
- 1);
288 WINDOW
*win
= Get_Menu_Window(menu
);
289 int maxy
= getmaxy(win
);
291 if ((menu
->win
= newpad(h
+2, menu
->width
+2)))
293 y
= (maxy
>= h
) ? h
: maxy
;
294 if (y
>= menu
->height
)
296 if (!(menu
->sub
= subpad(menu
->win
, y
, menu
->width
, 0, 0)))
297 RETURN(E_SYSTEM_ERROR
);
300 RETURN(E_SYSTEM_ERROR
);
302 if (menu
->status
& _LINK_NEEDED
)
303 _nc_Link_Items(menu
);
306 RETURN(E_NOT_CONNECTED
);
308 menu
->status
|= _POSTED
;
310 if (!(menu
->opt
& O_ONEVALUE
))
314 for (items
= menu
->items
; *items
; items
++)
316 (*items
)->value
= FALSE
;
322 Call_Hook(menu
, menuinit
);
323 Call_Hook(menu
, iteminit
);
330 /*---------------------------------------------------------------------------
331 | Facility : libnmenu
332 | Function : int unpost_menu(MENU*)
334 | Description : Detach menu from screen
336 | Return Values : E_OK - success
337 | E_BAD_ARGUMENT - not a valid menu pointer
338 | E_BAD_STATE - menu in userexit routine
339 | E_NOT_POSTED - menu is not posted
340 +--------------------------------------------------------------------------*/
342 unpost_menu(MENU
* menu
)
346 T((T_CALLED("unpost_menu(%p)"), (void *)menu
));
349 RETURN(E_BAD_ARGUMENT
);
351 if (menu
->status
& _IN_DRIVER
)
354 if (!(menu
->status
& _POSTED
))
355 RETURN(E_NOT_POSTED
);
357 Call_Hook(menu
, itemterm
);
358 Call_Hook(menu
, menuterm
);
360 win
= Get_Menu_Window(menu
);
366 menu
->sub
= (WINDOW
*)0;
370 menu
->win
= (WINDOW
*)0;
372 menu
->status
&= ~_POSTED
;
377 /* m_post.c ends here */