remove empty dir
[reactos.git] / rosapps / lib / dflat32 / menubar.c
1 /* ---------------- menubar.c ------------------ */
2
3 #include "dflat32/dflat.h"
4
5 static void reset_menubar(DFWINDOW);
6
7 static struct {
8 int x1, x2; /* position in menu bar */
9 char sc; /* shortcut key value */
10 } menu[10];
11 static int mctr;
12
13 MBAR *ActiveMenuBar;
14 static MENU *ActiveMenu;
15
16 static DFWINDOW mwnd;
17 static BOOL Selecting;
18
19 static DFWINDOW Cascaders[MAXCASCADES];
20 static int casc;
21 static DFWINDOW GetDocFocus(void);
22
23 /* ----------- SETFOCUS Message ----------- */
24 static int SetFocusMsg(DFWINDOW wnd, PARAM p1)
25 {
26 int rtn;
27 rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0);
28 if (!(int)p1)
29 DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
30 return rtn;
31 }
32
33 /* --------- BUILDMENU Message --------- */
34 static void BuildMenuMsg(DFWINDOW wnd, PARAM p1)
35 {
36 int offset = 3;
37 reset_menubar(wnd);
38 mctr = 0;
39 ActiveMenuBar = (MBAR *) p1;
40 ActiveMenu = ActiveMenuBar->PullDown;
41 while (ActiveMenu->Title != NULL &&
42 ActiveMenu->Title != (void*)-1)
43 {
44 char *cp;
45 if (strlen(GetText(wnd)+offset) <
46 strlen(ActiveMenu->Title)+3)
47 break;
48 GetText(wnd) = DFrealloc(GetText(wnd),
49 strlen(GetText(wnd))+5);
50 memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
51 strlen(GetText(wnd))-offset+1);
52 CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE,
53 wnd->WindowColors [STD_COLOR] [BG]);
54 menu[mctr].x1 = offset;
55 offset += strlen(ActiveMenu->Title) + (3+MSPACE);
56 menu[mctr].x2 = offset-MSPACE;
57 cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
58 if (cp)
59 menu[mctr].sc = tolower(*(cp+1));
60 mctr++;
61 ActiveMenu++;
62 }
63 ActiveMenu = ActiveMenuBar->PullDown;
64 }
65
66 /* ---------- PAINT Message ---------- */
67 static void PaintMsg(DFWINDOW wnd)
68 {
69 if (Selecting)
70 return;
71 if (wnd == inFocus)
72 DfSendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
73 SetStandardColor(wnd);
74 wputs(wnd, GetText(wnd), 0, 0);
75 if (ActiveMenuBar == NULL)
76 return;
77 if (ActiveMenuBar->ActiveSelection != -1 &&
78 (wnd == inFocus || mwnd != NULL)) {
79 char *sel, *cp;
80 int offset, offset1;
81
82 sel = DFmalloc(200);
83 offset=menu[ActiveMenuBar->ActiveSelection].x1;
84 offset1=menu[ActiveMenuBar->ActiveSelection].x2;
85 GetText(wnd)[offset1] = '\0';
86 SetReverseColor(wnd);
87 memset(sel, '\0', 200);
88 strcpy(sel, GetText(wnd)+offset);
89 cp = strchr(sel, CHANGECOLOR);
90 if (cp != NULL)
91 *(cp + 2) = background | 0x80;
92 wputs(wnd, sel,
93 offset-ActiveMenuBar->ActiveSelection*4, 0);
94 GetText(wnd)[offset1] = ' ';
95 if (mwnd == NULL && wnd == inFocus) {
96 char *st = ActiveMenu
97 [ActiveMenuBar->ActiveSelection].StatusText;
98 if (st != NULL)
99 DfSendMessage(GetParent(wnd), ADDSTATUS,
100 (PARAM)st, 0);
101 }
102 free(sel);
103 }
104 }
105
106 /* ------------ KEYBOARD Message ------------- */
107 static void KeyboardMsg(DFWINDOW wnd, PARAM p1)
108 {
109 MENU *mnu;
110 int sel;
111 if (mwnd == NULL)
112 {
113 /* ----- search for menu bar shortcut keys ---- */
114 int c = tolower((int)p1);
115 int a = AltConvert((int)p1);
116 int j;
117 for (j = 0; j < mctr; j++) {
118 if ((inFocus == wnd && menu[j].sc == c) ||
119 (a && menu[j].sc == a)) {
120 DfSendMessage(wnd, SETFOCUS, TRUE, 0);
121 DfSendMessage(wnd, MB_SELECTION, j, 0);
122 return;
123 }
124 }
125 }
126 /* -------- search for accelerator keys -------- */
127 mnu = ActiveMenu;
128 while (mnu->Title != (void *)-1) {
129 struct PopDown *pd = mnu->Selections;
130 if (mnu->PrepMenu)
131 (*(mnu->PrepMenu))(GetDocFocus(), mnu);
132 while (pd->SelectionTitle != NULL) {
133 if (pd->Accelerator == (int) p1) {
134 if (pd->Attrib & INACTIVE)
135 beep();
136 else {
137 if (pd->Attrib & TOGGLE)
138 pd->Attrib ^= CHECKED;
139 DfSendMessage(GetDocFocus(),
140 SETFOCUS, TRUE, 0);
141 DfPostMessage(GetParent(wnd),
142 DFM_COMMAND, pd->ActionId, 0);
143 }
144 return;
145 }
146 pd++;
147 }
148 mnu++;
149 }
150 switch ((int)p1)
151 {
152 case F1:
153 if (ActiveMenu == NULL || ActiveMenuBar == NULL)
154 break;
155 sel = ActiveMenuBar->ActiveSelection;
156 if (sel == -1)
157 {
158 BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0);
159 return;
160 }
161 mnu = ActiveMenu+sel;
162 if (mwnd == NULL ||
163 mnu->Selections[0].SelectionTitle == NULL)
164 {
165 DisplayHelp(wnd,mnu->Title+1);
166 return;
167 }
168 break;
169
170 case '\r':
171 if (mwnd == NULL &&
172 ActiveMenuBar->ActiveSelection != -1)
173 DfSendMessage(wnd, MB_SELECTION,
174 ActiveMenuBar->ActiveSelection, 0);
175 break;
176 case F10:
177 if (wnd != inFocus && mwnd == NULL) {
178 DfSendMessage(wnd, SETFOCUS, TRUE, 0);
179 if ( ActiveMenuBar->ActiveSelection == -1)
180 ActiveMenuBar->ActiveSelection = 0;
181 DfSendMessage(wnd, PAINT, 0, 0);
182 break;
183 }
184 /* ------- fall through ------- */
185 case ESC:
186 if (inFocus == wnd && mwnd == NULL) {
187 ActiveMenuBar->ActiveSelection = -1;
188 DfSendMessage(GetDocFocus(),SETFOCUS,TRUE,0);
189 DfSendMessage(wnd, PAINT, 0, 0);
190 }
191 break;
192 case FWD:
193 ActiveMenuBar->ActiveSelection++;
194 if (ActiveMenuBar->ActiveSelection == mctr)
195 ActiveMenuBar->ActiveSelection = 0;
196 if (mwnd != NULL)
197 DfSendMessage(wnd, MB_SELECTION,
198 ActiveMenuBar->ActiveSelection, 0);
199 else
200 DfSendMessage(wnd, PAINT, 0, 0);
201 break;
202 case BS:
203 if (ActiveMenuBar->ActiveSelection == 0 ||
204 ActiveMenuBar->ActiveSelection == -1)
205 ActiveMenuBar->ActiveSelection = mctr;
206 --ActiveMenuBar->ActiveSelection;
207 if (mwnd != NULL)
208 DfSendMessage(wnd, MB_SELECTION,
209 ActiveMenuBar->ActiveSelection, 0);
210 else
211 DfSendMessage(wnd, PAINT, 0, 0);
212 break;
213 default:
214 break;
215 }
216 }
217
218 /* --------------- LEFT_BUTTON Message ---------- */
219 static void LeftButtonMsg(DFWINDOW wnd, PARAM p1)
220 {
221 int i;
222 int mx = (int) p1 - GetLeft(wnd);
223 /* --- compute the selection that the left button hit --- */
224 for (i = 0; i < mctr; i++)
225 if (mx >= menu[i].x1-4*i &&
226 mx <= menu[i].x2-4*i-5)
227 break;
228 if (i < mctr)
229 if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
230 DfSendMessage(wnd, MB_SELECTION, i, 0);
231 }
232
233 /* -------------- MB_SELECTION Message -------------- */
234 static void SelectionMsg(DFWINDOW wnd, PARAM p1, PARAM p2)
235 {
236 int wd, mx, my;
237 MENU *mnu;
238
239 if (!p2)
240 {
241 ActiveMenuBar->ActiveSelection = -1;
242 DfSendMessage(wnd, PAINT, 0, 0);
243 }
244 Selecting = TRUE;
245 mnu = ActiveMenu+(int)p1;
246 if (mnu->PrepMenu != NULL)
247 (*(mnu->PrepMenu))(GetDocFocus(), mnu);
248 wd = MenuWidth(mnu->Selections);
249 if (p2)
250 {
251 int brd = GetRight(wnd);
252 mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1;
253 if (mx + wd > brd)
254 mx = brd - wd;
255 my = GetTop(mwnd) + mwnd->selection;
256 }
257 else
258 {
259 int offset = menu[(int)p1].x1 - 4 * (int)p1;
260 if (mwnd != NULL)
261 DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0);
262 ActiveMenuBar->ActiveSelection = (int) p1;
263 if (offset > WindowWidth(wnd)-wd)
264 offset = WindowWidth(wnd)-wd;
265 mx = GetLeft(wnd)+offset;
266 my = GetTop(wnd)+1;
267 }
268 mwnd = DfCreateWindow(POPDOWNMENU, NULL,
269 mx, my,
270 MenuHeight(mnu->Selections),
271 wd,
272 NULL,
273 wnd,
274 NULL,
275 SHADOW);
276 if (!p2)
277 {
278 Selecting = FALSE;
279 DfSendMessage(wnd, PAINT, 0, 0);
280 Selecting = TRUE;
281 }
282 if (mnu->Selections[0].SelectionTitle != NULL)
283 {
284 DfSendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
285 DfSendMessage(mwnd, SETFOCUS, TRUE, 0);
286 DfSendMessage(mwnd, SHOW_WINDOW, 0, 0);
287 }
288 Selecting = FALSE;
289 }
290
291 /* --------- COMMAND Message ---------- */
292 static void CommandMsg(DFWINDOW wnd, PARAM p1, PARAM p2)
293 {
294 if (p1 == ID_HELP)
295 {
296 BaseWndProc(MENUBAR, wnd, DFM_COMMAND, p1, p2);
297 return;
298 }
299
300 if (isCascadedCommand(ActiveMenuBar, (int)p1))
301 {
302 /* find the cascaded menu based on command id in p1 */
303 MENU *mnu = ActiveMenu+mctr;
304 while (mnu->Title != (void *)-1) {
305 if (mnu->CascadeId == (int) p1) {
306 if (casc < MAXCASCADES) {
307 Cascaders[casc++] = mwnd;
308 DfSendMessage(wnd, MB_SELECTION,
309 (PARAM)(mnu-ActiveMenu), TRUE);
310 }
311 break;
312 }
313 mnu++;
314 }
315 }
316 else {
317 if (mwnd != NULL)
318 DfSendMessage(mwnd, CLOSE_WINDOW, 0, 0);
319 DfSendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
320 DfPostMessage(GetParent(wnd), DFM_COMMAND, p1, p2);
321 }
322 }
323
324 /* --------------- CLOSE_POPDOWN Message --------------- */
325 static void ClosePopdownMsg(DFWINDOW wnd)
326 {
327 if (casc > 0)
328 DfSendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0);
329 else
330 {
331 mwnd = NULL;
332 ActiveMenuBar->ActiveSelection = -1;
333 if (!Selecting)
334 {
335 DfSendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
336 DfSendMessage(wnd, PAINT, 0, 0);
337 }
338 }
339 }
340
341 /* ---------------- CLOSE_WINDOW Message --------------- */
342 static void CloseWindowMsg(DFWINDOW wnd)
343 {
344 if (GetText(wnd) != NULL)
345 {
346 free(GetText(wnd));
347 GetText(wnd) = NULL;
348 }
349 mctr = 0;
350 ActiveMenuBar->ActiveSelection = -1;
351 ActiveMenu = NULL;
352 ActiveMenuBar = NULL;
353 }
354
355 /* --- Window processing module for MENUBAR window class --- */
356 int MenuBarProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2)
357 {
358 int rtn;
359
360 switch (msg) {
361 case CREATE_WINDOW:
362 reset_menubar(wnd);
363 break;
364 case SETFOCUS:
365 return SetFocusMsg(wnd, p1);
366 case BUILDMENU:
367 BuildMenuMsg(wnd, p1);
368 break;
369 case PAINT:
370 if (!isVisible(wnd) || GetText(wnd) == NULL)
371 break;
372 PaintMsg(wnd);
373 return FALSE;
374 case BORDER:
375 if (mwnd == NULL)
376 DfSendMessage(wnd, PAINT, 0, 0);
377 return TRUE;
378 case KEYBOARD:
379 KeyboardMsg(wnd, p1);
380 return TRUE;
381 case LEFT_BUTTON:
382 LeftButtonMsg(wnd, p1);
383 return TRUE;
384 case MB_SELECTION:
385 SelectionMsg(wnd, p1, p2);
386 break;
387 case DFM_COMMAND:
388 CommandMsg(wnd, p1, p2);
389 return TRUE;
390 case INSIDE_WINDOW:
391 return InsideRect(p1, p2, WindowRect(wnd));
392 case CLOSE_POPDOWN:
393 ClosePopdownMsg(wnd);
394 return TRUE;
395 case CLOSE_WINDOW:
396 CloseWindowMsg(wnd);
397 rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
398 return rtn;
399 default:
400 break;
401 }
402 return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
403 }
404
405 /* ------------- reset the MENUBAR -------------- */
406 static void reset_menubar(DFWINDOW wnd)
407 {
408 GetText(wnd) = DFrealloc(GetText(wnd), DfGetScreenWidth()+5);
409 memset(GetText(wnd), ' ', DfGetScreenWidth());
410 *(GetText(wnd)+WindowWidth(wnd)) = '\0';
411 }
412
413 static DFWINDOW GetDocFocus(void)
414 {
415 DFWINDOW wnd = ApplicationWindow;
416 if (wnd != NULL)
417 {
418 wnd = LastWindow(wnd);
419 while (wnd != NULL &&
420 (GetClass(wnd) == MENUBAR ||
421 GetClass(wnd) == STATUSBAR))
422 wnd = PrevWindow(wnd);
423 if (wnd != NULL)
424 {
425 while (wnd->childfocus != NULL)
426 wnd = wnd->childfocus;
427 }
428 }
429 return wnd ? wnd : ApplicationWindow;
430 }
431
432 /* EOF */