1 /****************************************************************************
2 * Copyright (c) 1998,2000 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.19 2003/10/25 14:54:48 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
;
62 getyx(menu
->win
,item_y
,item_x
);
64 /* We need a marker iff
65 - it is a onevalued menu and it is the current item
66 - or it has a selection value
68 wattron(menu
->win
,menu
->back
);
69 if (item
->value
|| (item
==menu
->curitem
))
73 /* In a multi selection menu we use the fore attribute
74 for a selected marker that is not the current one.
75 This improves visualization of the menu, because now
76 always the 'normal' marker denotes the current
78 if (!(menu
->opt
& O_ONEVALUE
) && item
->value
&& item
!=menu
->curitem
)
80 wattron(menu
->win
,menu
->fore
);
83 waddstr(menu
->win
,menu
->mark
);
86 wattron(menu
->win
,menu
->fore
);
91 else /* otherwise we have to wipe out the marker area */
92 for(ch
=' ',i
=menu
->marklen
;i
>0;i
--)
94 wattroff(menu
->win
,menu
->back
);
95 count
+= menu
->marklen
;
97 /* First we have to calculate the attribute depending on selectability
100 if (!(item
->opt
& O_SELECTABLE
))
102 wattron(menu
->win
,menu
->grey
);
107 if (item
->value
|| item
==menu
->curitem
)
109 wattron(menu
->win
,menu
->fore
);
114 wattron(menu
->win
,menu
->back
);
119 waddnstr(menu
->win
,item
->name
.str
,item
->name
.length
);
120 for(ch
=' ',i
=menu
->namelen
-item
->name
.length
;i
>0;i
--)
122 waddch(menu
->win
,ch
);
124 count
+= menu
->namelen
;
126 /* Show description if required and available */
127 if ( (menu
->opt
& O_SHOWDESC
) && menu
->desclen
>0 )
129 int m
= menu
->spc_desc
/2;
130 int cy
= -1, cx
= -1;
132 for(ch
=' ',i
=0; i
< menu
->spc_desc
; i
++)
136 waddch(menu
->win
,menu
->pad
);
137 getyx(menu
->win
,cy
,cx
);
140 waddch(menu
->win
,ch
);
142 if (item
->description
.length
)
143 waddnstr(menu
->win
,item
->description
.str
,item
->description
.length
);
144 for(ch
=' ',i
=menu
->desclen
-item
->description
.length
; i
>0; i
--)
146 waddch(menu
->win
,ch
);
148 count
+= menu
->desclen
+ menu
->spc_desc
;
150 if (menu
->spc_rows
> 1)
154 assert(cx
>=0 && cy
>=0);
155 getyx(menu
->win
,ncy
,ncx
);
156 if (isgrey
) wattroff(menu
->win
,menu
->grey
);
157 else if (isfore
) wattroff(menu
->win
,menu
->fore
);
158 wattron(menu
->win
,menu
->back
);
159 for(j
=1; j
< menu
->spc_rows
;j
++)
161 if ((item_y
+j
) < getmaxy(menu
->win
))
163 wmove (menu
->win
,item_y
+j
,item_x
);
165 waddch(menu
->win
,' ');
167 if ((cy
+j
) < getmaxy(menu
->win
))
168 mvwaddch(menu
->win
,cy
+j
,cx
-1,menu
->pad
);
170 wmove(menu
->win
,ncy
,ncx
);
172 wattroff(menu
->win
,menu
->back
);
176 /* Remove attributes */
178 wattroff(menu
->win
,menu
->fore
);
180 wattroff(menu
->win
,menu
->back
);
182 wattroff(menu
->win
,menu
->grey
);
185 /*---------------------------------------------------------------------------
186 | Facility : libnmenu
187 | Function : void _nc_Draw_Menu(const MENU *)
189 | Description : Display the menu in its windows
192 +--------------------------------------------------------------------------*/
194 _nc_Draw_Menu (const MENU
* menu
)
196 ITEM
*item
= menu
->items
[0];
197 ITEM
*lasthor
, *lastvert
;
202 assert(item
&& menu
->win
);
204 s_bkgd
= getbkgd(menu
->win
);
205 wbkgdset(menu
->win
,menu
->back
);
207 wbkgdset(menu
->win
,s_bkgd
);
209 lastvert
= (menu
->opt
& O_NONCYCLIC
) ? (ITEM
*)0 : item
;
213 wmove(menu
->win
,y
,0);
216 lasthor
= (menu
->opt
& O_NONCYCLIC
) ? (ITEM
*)0 : hitem
;
220 _nc_Post_Item( menu
, hitem
);
222 wattron(menu
->win
,menu
->back
);
223 if ( ((hitem
= hitem
->right
) != lasthor
) && hitem
)
228 getyx(menu
->win
,cy
,cx
);
229 for(j
=0;j
<menu
->spc_rows
;j
++)
231 wmove(menu
->win
,cy
+j
,cx
);
232 for(i
=0; i
< menu
->spc_cols
; i
++)
234 waddch( menu
->win
,ch
);
237 wmove(menu
->win
,cy
,cx
+menu
->spc_cols
);
239 } while (hitem
&& (hitem
!= lasthor
));
240 wattroff(menu
->win
,menu
->back
);
245 } while( item
&& (item
!= lastvert
) );
248 /*---------------------------------------------------------------------------
249 | Facility : libnmenu
250 | Function : int post_menu(MENU *)
252 | Description : Post a menu to the screen. This makes it visible.
254 | Return Values : E_OK - success
255 | E_BAD_ARGUMENT - not a valid menu pointer
256 | E_SYSTEM_ERROR - error in lower layers
257 | E_NO_ROOM - Menu to large for screen
258 | E_NOT_CONNECTED - No items connected to menu
259 | E_BAD_STATE - Menu in userexit routine
260 | E_POSTED - Menu already posted
261 +--------------------------------------------------------------------------*/
263 post_menu (MENU
* menu
)
266 RETURN(E_BAD_ARGUMENT
);
268 if ( menu
->status
& _IN_DRIVER
)
271 if ( menu
->status
& _POSTED
)
274 if (menu
->items
&& *(menu
->items
))
277 int h
= 1 + menu
->spc_rows
* (menu
->rows
- 1);
279 WINDOW
*win
= Get_Menu_Window(menu
);
280 int maxy
= getmaxy(win
);
281 int maxx
= getmaxx(win
);
283 if (maxx
< menu
->width
|| maxy
< menu
->height
)
286 if ( (menu
->win
= newpad(h
,menu
->width
)) )
288 y
= (maxy
>= h
) ? h
: maxy
;
291 if(!(menu
->sub
= subpad(menu
->win
,y
,menu
->width
,0,0)))
292 RETURN(E_SYSTEM_ERROR
);
295 RETURN(E_SYSTEM_ERROR
);
297 if (menu
->status
& _LINK_NEEDED
)
298 _nc_Link_Items(menu
);
301 RETURN(E_NOT_CONNECTED
);
303 menu
->status
|= _POSTED
;
305 if (!(menu
->opt
&O_ONEVALUE
))
309 for(items
=menu
->items
;*items
;items
++)
311 (*items
)->value
= FALSE
;
317 Call_Hook(menu
,menuinit
);
318 Call_Hook(menu
,iteminit
);
325 /*---------------------------------------------------------------------------
326 | Facility : libnmenu
327 | Function : int unpost_menu(MENU *)
329 | Description : Detach menu from screen
331 | Return Values : E_OK - success
332 | E_BAD_ARGUMENT - not a valid menu pointer
333 | E_BAD_STATE - menu in userexit routine
334 | E_NOT_POSTED - menu is not posted
335 +--------------------------------------------------------------------------*/
337 unpost_menu (MENU
* menu
)
342 RETURN(E_BAD_ARGUMENT
);
344 if ( menu
->status
& _IN_DRIVER
)
347 if ( !( menu
->status
& _POSTED
) )
348 RETURN(E_NOT_POSTED
);
350 Call_Hook(menu
,itemterm
);
351 Call_Hook(menu
,menuterm
);
353 win
= Get_Menu_Window(menu
);
359 menu
->sub
= (WINDOW
*)0;
363 menu
->win
= (WINDOW
*)0;
365 menu
->status
&= ~_POSTED
;
370 /* m_post.c ends here */