]> git.decadent.org.uk Git - ion3.git/blob - mod_menu/mkmenu.c
0c27f73168f9ba87244cecf40cefdbd8800f20b1
[ion3.git] / mod_menu / mkmenu.c
1 /*
2  * ion/mod_menu/mkmenu.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <limits.h>
13 #include <ioncore/common.h>
14 #include <ioncore/pointer.h>
15 #include <ioncore/grab.h>
16 #include <libextl/extl.h>
17 #include "menu.h"
18 #include "mkmenu.h"
19
20
21 /*--lowlevel routine not to be called by the user--EXTL_DOC
22  * Display a menu inside multiplexer. The \var{handler} parameter
23  * is a function that gets the selected menu entry as argument and
24  * should call it with proper parameters. The table \var{tab} is a
25  * list of menu entries of the form \code{\{name = ???, [ submenu_fn = ??? ]\}}.
26  * The function \var{submenu_fn} return a similar submenu definition 
27  * when called.
28  * 
29  * Do not use this function directly. Use  \fnref{mod_menu.menu} and
30  * \fnref{mod_menu.bigmenu}.
31  */
32 EXTL_EXPORT
33 WMenu *mod_menu_do_menu(WMPlex *mplex, ExtlFn handler, ExtlTab tab, 
34                         ExtlTab param)
35 {
36     WMenuCreateParams fnp;
37     WMPlexAttachParams par;
38
39     fnp.handler=handler;
40     fnp.tab=tab;
41     fnp.pmenu_mode=FALSE;
42     fnp.submenu_mode=FALSE;
43     fnp.big_mode=extl_table_is_bool_set(param, "big");
44     fnp.initial=0;
45     extl_table_gets_i(param, "initial", &(fnp.initial));
46     fnp.refg.x=0;
47     fnp.refg.y=0;
48     fnp.refg.w=0;
49     fnp.refg.h=0;
50     
51     par.flags=(MPLEX_ATTACH_SWITCHTO|
52                MPLEX_ATTACH_MODAL|
53                MPLEX_ATTACH_UNNUMBERED|
54                MPLEX_ATTACH_SIZEPOLICY);
55     par.szplcy=SIZEPOLICY_FULL_BOUNDS;
56         
57     return (WMenu*)mplex_do_attach_new(mplex, &par,
58                                        (WRegionCreateFn*)create_menu,
59                                        (void*)&fnp); 
60 }
61
62
63 /*--lowlevel routine not to be called by the user--EXTL_DOC
64  * Display a pop-up menu inside window \var{where}. This function
65  * can only be called from a mouse/pointing device button press handler
66  * and the menu will be placed below the point where the press occured.
67  * The \var{handler} and \var{tab} parameters are similar to those of
68  * \fnref{menu_menu}.
69  * 
70  * Do not use this function directly. Use \fnref{mod_menu.pmenu}.
71  */
72 EXTL_EXPORT
73 WMenu *mod_menu_do_pmenu(WWindow *where, ExtlFn handler, ExtlTab tab)
74 {
75     WScreen *scr;
76     WMenuCreateParams fnp;
77     XEvent *ev=ioncore_current_pointer_event();
78     WMenu *menu;
79     WFitParams fp;
80     
81     if(ev==NULL || ev->type!=ButtonPress)
82         return NULL;
83
84     scr=region_screen_of((WRegion*)where);
85
86     if(scr==NULL)
87         return NULL;
88     
89     fnp.handler=handler;
90     fnp.tab=tab;
91     fnp.pmenu_mode=TRUE;
92     fnp.big_mode=FALSE;
93     fnp.submenu_mode=FALSE;
94     fnp.initial=0;
95     fnp.refg.x=ev->xbutton.x_root-REGION_GEOM(scr).x;
96     fnp.refg.y=ev->xbutton.y_root-REGION_GEOM(scr).y;
97     fnp.refg.w=0;
98     fnp.refg.h=0;
99     
100     fp.mode=REGION_FIT_BOUNDS;
101     fp.g.x=REGION_GEOM(where).x;
102     fp.g.y=REGION_GEOM(where).y;
103     fp.g.w=REGION_GEOM(where).w;
104     fp.g.h=REGION_GEOM(where).h;
105     
106     menu=create_menu((WWindow*)scr, &fp, &fnp);
107     
108     if(menu==NULL)
109         return NULL;
110
111     region_restack((WRegion*)menu, None, Above);
112     
113     if(!ioncore_set_drag_handlers((WRegion*)menu,
114                             NULL,
115                             (WMotionHandler*)menu_motion,
116                             (WButtonHandler*)menu_release,
117                             NULL, 
118                             (GrabKilledHandler*)menu_cancel)){
119         destroy_obj((Obj*)menu);
120         return NULL;
121     }
122     
123     region_map((WRegion*)menu);
124     
125     return menu;
126 }
127