First checkin, AXE release 0.2
[AXE.git] / src / menu.cpp
1 /**************************************************************************
2 **  (c) Copyright 1998, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : menu.cpp
7 **      SYSTEM NAME    : AXE - Andromeda X-windows Encapsulation
8 **      VERSION NUMBER : $Revision: 1.1 $
9 **
10 **  DESCRIPTION      : Implementation of menu classes 
11 **
12 **  EXPORTED OBJECTS : menu_container
13 **  LOCAL    OBJECTS : 
14 **  MODULES  USED    :
15 ***************************************************************************
16 **  ADMINISTRATIVE INFORMATION *
17 ********************************
18 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 **      CREATION DATE   : Feb 13, 1998
20 **      LAST UPDATE     : Mar 07, 1998
21 **      MODIFICATIONS   : 
22 **************************************************************************/
23
24 /*****************************
25    $Log: menu.cpp,v $
26    Revision 1.1  2002-07-25 08:01:27  arjen
27    First checkin, AXE release 0.2
28
29 *****************************/
30
31 static const char *RCSID = "$Id: menu.cpp,v 1.1 2002-07-25 08:01:27 arjen Exp $";
32
33 #include "menu.h"
34
35 #include <stdio.h>
36
37
38 /*=========================================================================
39 **  NAME           : RearrangeItems
40 **  SYNOPSIS       :
41 **  PARAMETERS     :
42 **  RETURN VALUE   :
43 **
44 **  DESCRIPTION    : 
45 **
46 **  VARS USED      :
47 **  VARS CHANGED   :
48 **  FUNCTIONS USED :
49 **  SEE ALSO       :
50 **  LAST MODIFIED  : 
51 **=========================================================================
52 */
53
54 void menu_container::RearrangeItems(unsigned &ov_width, unsigned &ov_height)
55 {
56    win_list *l;
57    unsigned width, height;
58
59    ov_width = 0;
60    ov_height = 0;
61
62    if (mode == Horizontal)
63    {
64       for(l = children; l; l = l->next)
65       {
66          l->child->Move(ov_width, 0);
67          l->child->Size(width, height);
68          ov_width += width;
69          ov_height = height > ov_height ? height : ov_height;
70       }
71
72       for(l = children; l; l = l->next)
73       {
74          l->child->Size(width, height);
75          l->child->Resize(width, ov_height);
76       }
77    }
78    else   /*  mode is Vertical */
79    {
80       for(l = children; l; l = l->next)
81       {
82          l->child->Move(0, ov_height);
83          l->child->Size(width, height);
84          ov_height += height;
85          ov_width = width > ov_width ? width : ov_width;
86       }
87
88       for(l = children; l; l = l->next)
89       {
90          l->child->Size(width, height);
91          l->child->Resize(ov_width, height);
92       }
93    }
94
95 }
96
97 /*=========================================================================
98 **  NAME           : HideSubmenus
99 **  SYNOPSIS       :
100 **  PARAMETERS     :
101 **  RETURN VALUE   :
102 **
103 **  DESCRIPTION    : 
104 **
105 **  VARS USED      :
106 **  VARS CHANGED   :
107 **  FUNCTIONS USED :
108 **  SEE ALSO       :
109 **  LAST MODIFIED  : 
110 **=========================================================================
111 */
112
113 void menu_container::HideSubmenus(void)
114 {
115    //printf("HideSubmenus(0x%x)\n",this);
116
117    win_list *l = children;
118
119    while (l)
120    {
121       menu_item *mi;
122
123       mi = (menu_item *)l->child;
124       mi->HideSubmenu();
125
126       l = l->next;
127    }
128
129 }
130
131 /*=========================================================================
132 **  NAME           : Show
133 **  SYNOPSIS       :
134 **  PARAMETERS     :
135 **  RETURN VALUE   :
136 **
137 **  DESCRIPTION    : 
138 **
139 **  VARS USED      :
140 **  VARS CHANGED   :
141 **  FUNCTIONS USED :
142 **  SEE ALSO       :
143 **  LAST MODIFIED  : 
144 **=========================================================================
145 */
146
147 void menu_container::Show(menu_item *by, int x, int y)
148 {
149    shown_by = by;
150    Move(x, y);
151    Realize();
152 }
153
154
155 void menu_item::redraw(void)
156 {
157 }
158
159 /*=========================================================================
160 **  NAME           : EV_EnterNotify
161 **  SYNOPSIS       :
162 **  PARAMETERS     :
163 **  RETURN VALUE   :
164 **
165 **  DESCRIPTION    : 
166 **
167 **  VARS USED      :
168 **  VARS CHANGED   :
169 **  FUNCTIONS USED :
170 **  SEE ALSO       :
171 **  LAST MODIFIED  : 
172 **=========================================================================
173 */
174
175 int menu_item::EV_EnterNotify(XCrossingEvent ev)
176 {
177    highlighted = 1;
178    Background(menu_highlight);
179    Clear();
180
181    redraw();
182
183    GrabPointer(hand_cursor);
184
185    //  Make sure all sibling popup menus are disappeared.
186
187    win_list *l = parent->children;
188
189    while (l)
190    {
191       menu_item *mi;
192
193       mi = (menu_item *)l->child;
194       if (mi != this)
195          mi->HideSubmenu();
196
197       l = l->next;
198    }
199
200    ShowSubmenu(ev.x_root - ev.x, ev.y_root - ev.y);
201
202    return 1;
203 }
204
205 /*=========================================================================
206 **  NAME           : EV_LeaveNotify
207 **  SYNOPSIS       :
208 **  PARAMETERS     :
209 **  RETURN VALUE   :
210 **
211 **  DESCRIPTION    : 
212 **
213 **  VARS USED      :
214 **  VARS CHANGED   :
215 **  FUNCTIONS USED :
216 **  SEE ALSO       :
217 **  LAST MODIFIED  : 
218 **=========================================================================
219 */
220
221 int menu_item::EV_LeaveNotify(XCrossingEvent ev)
222 {
223    highlighted = 0;
224    Background(menu_normal);
225    Clear();
226    redraw();
227
228    return 1;
229 }
230
231 /*=========================================================================
232 **  NAME           : EV_ButtonRelease
233 **  SYNOPSIS       :
234 **  PARAMETERS     :
235 **  RETURN VALUE   :
236 **
237 **  DESCRIPTION    : 
238 **
239 **  VARS USED      :
240 **  VARS CHANGED   :
241 **  FUNCTIONS USED :
242 **  SEE ALSO       :
243 **  LAST MODIFIED  : 
244 **=========================================================================
245 */
246
247 int menu_item::EV_ButtonRelease(XButtonEvent ev)
248 {
249       menu_container   *contain;
250
251       UngrabPointer();
252
253       contain = (menu_container *)parent;
254       while (contain->shown_by)
255       {
256          menu_item *mi = (menu_item *)contain->shown_by;
257          contain = (menu_container *)mi->parent;
258       }
259       //printf("contain->HideSubmenus(0x%x)\n", contain);
260       contain->HideSubmenus();
261
262       if (highlighted && !popup)
263       {
264          return XApp->SendCommand(command_code);
265       }
266
267       return 1;
268
269 }
270
271 /*=========================================================================
272 **  NAME           : HideSubmenu
273 **  SYNOPSIS       :
274 **  PARAMETERS     :
275 **  RETURN VALUE   :
276 **
277 **  DESCRIPTION    : 
278 **
279 **  VARS USED      :
280 **  VARS CHANGED   :
281 **  FUNCTIONS USED :
282 **  SEE ALSO       :
283 **  LAST MODIFIED  : 
284 **=========================================================================
285 */
286
287 void menu_item::HideSubmenu(void)
288 {
289    if (popup)
290    {
291       //printf("popup->HideSubmenus(0x%x)\n", popup);
292       popup->HideSubmenus();
293       popup->Unmap();
294       popup->shown_by = 0;
295    }
296 }
297
298 /*=========================================================================
299 **  NAME           : ShowSubmenu
300 **  SYNOPSIS       :
301 **  PARAMETERS     :
302 **  RETURN VALUE   :
303 **
304 **  DESCRIPTION    : 
305 **
306 **  VARS USED      :
307 **  VARS CHANGED   :
308 **  FUNCTIONS USED :
309 **  SEE ALSO       :
310 **  LAST MODIFIED  : 
311 **=========================================================================
312 */
313
314 void menu_item::ShowSubmenu(int x, int y)
315 {
316    if (popup)
317    {
318       unsigned w, h;
319
320       menu_container *contain;
321
322       Size(w, h);
323
324       contain = (menu_container *)parent;
325       contain->PositionSubmenu(x, y, w, h);
326
327       popup->Show(this, x, y);
328    }
329
330 }
331
332
333 /*=========================================================================
334 **  NAME           : redraw - Draw a label in a menu item
335 **  SYNOPSIS       :
336 **  PARAMETERS     :
337 **  RETURN VALUE   :
338 **
339 **  DESCRIPTION    : 
340 **
341 **  VARS USED      :
342 **  VARS CHANGED   :
343 **  FUNCTIONS USED :
344 **  SEE ALSO       :
345 **  LAST MODIFIED  : Mar 07, 1998
346 **=========================================================================
347 */
348
349 void menu_label::redraw(void)
350 {
351    XDrawString(stddpy, ID(), enabled ? menu_normal_gc : menu_dimmed_gc,
352                  5, default_font.ascent() + 3, label, strlen(label));
353
354 }
355
356 /*=========================================================================
357 **  NAME           : redraw -- Draw a separator in a menu item
358 **  SYNOPSIS       :
359 **  PARAMETERS     :
360 **  RETURN VALUE   :
361 **
362 **  DESCRIPTION    : 
363 **
364 **  VARS USED      :
365 **  VARS CHANGED   :
366 **  FUNCTIONS USED :
367 **  SEE ALSO       :
368 **  LAST MODIFIED  : 
369 **=========================================================================
370 */
371
372 void menu_separator::redraw(void)
373 {
374    unsigned int  w, h;
375
376    Size(w, h);
377    XDrawLine(stddpy, ID(), menu_normal_gc, 0, 3, w, 3);
378 }