remove empty dir
[reactos.git] / rosapps / dflat32 / menubar.c
1 /* ---------------- menubar.c ------------------ */
2
3 #include "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 DF_MBAR *DfActiveMenuBar;
14 static DF_MENU *ActiveMenu;
15
16 static DFWINDOW mwnd;
17 static BOOL Selecting;
18
19 static DFWINDOW Cascaders[DF_MAXCASCADES];
20 static int casc;
21 static DFWINDOW GetDocFocus(void);
22
23 /* ----------- DFM_SETFOCUS Message ----------- */
24 static int SetFocusMsg(DFWINDOW wnd, DF_PARAM p1)
25 {
26 int rtn;
27 rtn = DfBaseWndProc(DF_MENUBAR, wnd, DFM_SETFOCUS, p1, 0);
28 if (!(int)p1)
29 DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS, 0, 0);
30 return rtn;
31 }
32
33 /* --------- DFM_BUILDMENU Message --------- */
34 static void BuildMenuMsg(DFWINDOW wnd, DF_PARAM p1)
35 {
36 int offset = 3;
37 reset_menubar(wnd);
38 mctr = 0;
39 DfActiveMenuBar = (DF_MBAR *) p1;
40 ActiveMenu = DfActiveMenuBar->PullDown;
41 while (ActiveMenu->Title != NULL &&
42 ActiveMenu->Title != (void*)-1)
43 {
44 char *cp;
45 if (strlen(DfGetText(wnd)+offset) <
46 strlen(ActiveMenu->Title)+3)
47 break;
48 DfGetText(wnd) = DfRealloc(DfGetText(wnd),
49 strlen(DfGetText(wnd))+5);
50 memmove(DfGetText(wnd) + offset+4, DfGetText(wnd) + offset,
51 strlen(DfGetText(wnd))-offset+1);
52 DfCopyCommand(DfGetText(wnd)+offset,ActiveMenu->Title,FALSE,
53 wnd->WindowColors [DF_STD_COLOR] [DF_BG]);
54 menu[mctr].x1 = offset;
55 offset += strlen(ActiveMenu->Title) + (3+DF_MSPACE);
56 menu[mctr].x2 = offset-DF_MSPACE;
57 cp = strchr(ActiveMenu->Title, DF_SHORTCUTCHAR);
58 if (cp)
59 menu[mctr].sc = tolower(*(cp+1));
60 mctr++;
61 ActiveMenu++;
62 }
63 ActiveMenu = DfActiveMenuBar->PullDown;
64 }
65
66 /* ---------- DFM_PAINT Message ---------- */
67 static void PaintMsg(DFWINDOW wnd)
68 {
69 if (Selecting)
70 return;
71 if (wnd == DfInFocus)
72 DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS, 0, 0);
73 DfSetStandardColor(wnd);
74 DfWPuts(wnd, DfGetText(wnd), 0, 0);
75 if (DfActiveMenuBar == NULL)
76 return;
77 if (DfActiveMenuBar->ActiveSelection != -1 &&
78 (wnd == DfInFocus || mwnd != NULL)) {
79 char *sel, *cp;
80 int offset, offset1;
81
82 sel = DfMalloc(200);
83 offset=menu[DfActiveMenuBar->ActiveSelection].x1;
84 offset1=menu[DfActiveMenuBar->ActiveSelection].x2;
85 DfGetText(wnd)[offset1] = '\0';
86 DfSetReverseColor(wnd);
87 memset(sel, '\0', 200);
88 strcpy(sel, DfGetText(wnd)+offset);
89 cp = strchr(sel, DF_CHANGECOLOR);
90 if (cp != NULL)
91 *(cp + 2) = DfBackground | 0x80;
92 DfWPuts(wnd, sel,
93 offset-DfActiveMenuBar->ActiveSelection*4, 0);
94 DfGetText(wnd)[offset1] = ' ';
95 if (mwnd == NULL && wnd == DfInFocus) {
96 char *st = ActiveMenu
97 [DfActiveMenuBar->ActiveSelection].StatusText;
98 if (st != NULL)
99 DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS,
100 (DF_PARAM)st, 0);
101 }
102 free(sel);
103 }
104 }
105
106 /* ------------ DFM_KEYBOARD Message ------------- */
107 static void KeyboardMsg(DFWINDOW wnd, DF_PARAM p1)
108 {
109 DF_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 = DfAltConvert((int)p1);
116 int j;
117 for (j = 0; j < mctr; j++) {
118 if ((DfInFocus == wnd && menu[j].sc == c) ||
119 (a && menu[j].sc == a)) {
120 DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
121 DfSendMessage(wnd, DFM_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 DfPopDown *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 & DF_INACTIVE)
135 DfBeep();
136 else {
137 if (pd->Attrib & DF_TOGGLE)
138 pd->Attrib ^= DF_CHECKED;
139 DfSendMessage(GetDocFocus(),
140 DFM_SETFOCUS, TRUE, 0);
141 DfPostMessage(DfGetParent(wnd),
142 DFM_COMMAND, pd->ActionId, 0);
143 }
144 return;
145 }
146 pd++;
147 }
148 mnu++;
149 }
150 switch ((int)p1)
151 {
152 case DF_F1:
153 if (ActiveMenu == NULL || DfActiveMenuBar == NULL)
154 break;
155 sel = DfActiveMenuBar->ActiveSelection;
156 if (sel == -1)
157 {
158 DfBaseWndProc(DF_MENUBAR, wnd, DFM_KEYBOARD, DF_F1, 0);
159 return;
160 }
161 mnu = ActiveMenu+sel;
162 if (mwnd == NULL ||
163 mnu->Selections[0].SelectionTitle == NULL)
164 {
165 DfDisplayHelp(wnd,mnu->Title+1);
166 return;
167 }
168 break;
169
170 case '\r':
171 if (mwnd == NULL &&
172 DfActiveMenuBar->ActiveSelection != -1)
173 DfSendMessage(wnd, DFM_MB_SELECTION,
174 DfActiveMenuBar->ActiveSelection, 0);
175 break;
176 case DF_F10:
177 if (wnd != DfInFocus && mwnd == NULL) {
178 DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
179 if ( DfActiveMenuBar->ActiveSelection == -1)
180 DfActiveMenuBar->ActiveSelection = 0;
181 DfSendMessage(wnd, DFM_PAINT, 0, 0);
182 break;
183 }
184 /* ------- fall through ------- */
185 case DF_ESC:
186 if (DfInFocus == wnd && mwnd == NULL) {
187 DfActiveMenuBar->ActiveSelection = -1;
188 DfSendMessage(GetDocFocus(),DFM_SETFOCUS,TRUE,0);
189 DfSendMessage(wnd, DFM_PAINT, 0, 0);
190 }
191 break;
192 case DF_FWD:
193 DfActiveMenuBar->ActiveSelection++;
194 if (DfActiveMenuBar->ActiveSelection == mctr)
195 DfActiveMenuBar->ActiveSelection = 0;
196 if (mwnd != NULL)
197 DfSendMessage(wnd, DFM_MB_SELECTION,
198 DfActiveMenuBar->ActiveSelection, 0);
199 else
200 DfSendMessage(wnd, DFM_PAINT, 0, 0);
201 break;
202 case DF_BS:
203 if (DfActiveMenuBar->ActiveSelection == 0 ||
204 DfActiveMenuBar->ActiveSelection == -1)
205 DfActiveMenuBar->ActiveSelection = mctr;
206 --DfActiveMenuBar->ActiveSelection;
207 if (mwnd != NULL)
208 DfSendMessage(wnd, DFM_MB_SELECTION,
209 DfActiveMenuBar->ActiveSelection, 0);
210 else
211 DfSendMessage(wnd, DFM_PAINT, 0, 0);
212 break;
213 default:
214 break;
215 }
216 }
217
218 /* --------------- DFM_LEFT_BUTTON Message ---------- */
219 static void LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1)
220 {
221 int i;
222 int mx = (int) p1 - DfGetLeft(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 != DfActiveMenuBar->ActiveSelection || mwnd == NULL)
230 DfSendMessage(wnd, DFM_MB_SELECTION, i, 0);
231 }
232
233 /* -------------- DFM_MB_SELECTION Message -------------- */
234 static void SelectionMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
235 {
236 int wd, mx, my;
237 DF_MENU *mnu;
238
239 if (!p2)
240 {
241 DfActiveMenuBar->ActiveSelection = -1;
242 DfSendMessage(wnd, DFM_PAINT, 0, 0);
243 }
244 Selecting = TRUE;
245 mnu = ActiveMenu+(int)p1;
246 if (mnu->PrepMenu != NULL)
247 (*(mnu->PrepMenu))(GetDocFocus(), mnu);
248 wd = DfMenuWidth(mnu->Selections);
249 if (p2)
250 {
251 int brd = DfGetRight(wnd);
252 mx = DfGetLeft(mwnd) + DfWindowWidth(mwnd) - 1;
253 if (mx + wd > brd)
254 mx = brd - wd;
255 my = DfGetTop(mwnd) + mwnd->selection;
256 }
257 else
258 {
259 int offset = menu[(int)p1].x1 - 4 * (int)p1;
260 if (mwnd != NULL)
261 DfSendMessage(mwnd, DFM_CLOSE_WINDOW, 0, 0);
262 DfActiveMenuBar->ActiveSelection = (int) p1;
263 if (offset > DfWindowWidth(wnd)-wd)
264 offset = DfWindowWidth(wnd)-wd;
265 mx = DfGetLeft(wnd)+offset;
266 my = DfGetTop(wnd)+1;
267 }
268 mwnd = DfDfCreateWindow(DF_POPDOWNMENU, NULL,
269 mx, my,
270 DfMenuHeight(mnu->Selections),
271 wd,
272 NULL,
273 wnd,
274 NULL,
275 DF_SHADOW);
276 if (!p2)
277 {
278 Selecting = FALSE;
279 DfSendMessage(wnd, DFM_PAINT, 0, 0);
280 Selecting = TRUE;
281 }
282 if (mnu->Selections[0].SelectionTitle != NULL)
283 {
284 DfSendMessage(mwnd, DFM_BUILD_SELECTIONS, (DF_PARAM) mnu, 0);
285 DfSendMessage(mwnd, DFM_SETFOCUS, TRUE, 0);
286 DfSendMessage(mwnd, DFM_SHOW_WINDOW, 0, 0);
287 }
288 Selecting = FALSE;
289 }
290
291 /* --------- COMMAND Message ---------- */
292 static void CommandMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
293 {
294 if (p1 == DF_ID_HELP)
295 {
296 DfBaseWndProc(DF_MENUBAR, wnd, DFM_COMMAND, p1, p2);
297 return;
298 }
299
300 if (DfIsCascadedCommand(DfActiveMenuBar, (int)p1))
301 {
302 /* find the cascaded menu based on command id in p1 */
303 DF_MENU *mnu = ActiveMenu+mctr;
304 while (mnu->Title != (void *)-1) {
305 if (mnu->CascadeId == (int) p1) {
306 if (casc < DF_MAXCASCADES) {
307 Cascaders[casc++] = mwnd;
308 DfSendMessage(wnd, DFM_MB_SELECTION,
309 (DF_PARAM)(mnu-ActiveMenu), TRUE);
310 }
311 break;
312 }
313 mnu++;
314 }
315 }
316 else {
317 if (mwnd != NULL)
318 DfSendMessage(mwnd, DFM_CLOSE_WINDOW, 0, 0);
319 DfSendMessage(GetDocFocus(), DFM_SETFOCUS, TRUE, 0);
320 DfPostMessage(DfGetParent(wnd), DFM_COMMAND, p1, p2);
321 }
322 }
323
324 /* --------------- DFM_CLOSE_POPDOWN Message --------------- */
325 static void ClosePopdownMsg(DFWINDOW wnd)
326 {
327 if (casc > 0)
328 DfSendMessage(Cascaders[--casc], DFM_CLOSE_WINDOW, 0, 0);
329 else
330 {
331 mwnd = NULL;
332 DfActiveMenuBar->ActiveSelection = -1;
333 if (!Selecting)
334 {
335 DfSendMessage(GetDocFocus(), DFM_SETFOCUS, TRUE, 0);
336 DfSendMessage(wnd, DFM_PAINT, 0, 0);
337 }
338 }
339 }
340
341 /* ---------------- DFM_CLOSE_WINDOW Message --------------- */
342 static void CloseWindowMsg(DFWINDOW wnd)
343 {
344 if (DfGetText(wnd) != NULL)
345 {
346 free(DfGetText(wnd));
347 DfGetText(wnd) = NULL;
348 }
349 mctr = 0;
350 DfActiveMenuBar->ActiveSelection = -1;
351 ActiveMenu = NULL;
352 DfActiveMenuBar = NULL;
353 }
354
355 /* --- Window processing module for DF_MENUBAR window class --- */
356 int DfMenuBarProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
357 {
358 int rtn;
359
360 switch (msg) {
361 case DFM_CREATE_WINDOW:
362 reset_menubar(wnd);
363 break;
364 case DFM_SETFOCUS:
365 return SetFocusMsg(wnd, p1);
366 case DFM_BUILDMENU:
367 BuildMenuMsg(wnd, p1);
368 break;
369 case DFM_PAINT:
370 if (!DfIsVisible(wnd) || DfGetText(wnd) == NULL)
371 break;
372 PaintMsg(wnd);
373 return FALSE;
374 case DFM_BORDER:
375 if (mwnd == NULL)
376 DfSendMessage(wnd, DFM_PAINT, 0, 0);
377 return TRUE;
378 case DFM_KEYBOARD:
379 KeyboardMsg(wnd, p1);
380 return TRUE;
381 case DFM_LEFT_BUTTON:
382 LeftButtonMsg(wnd, p1);
383 return TRUE;
384 case DFM_MB_SELECTION:
385 SelectionMsg(wnd, p1, p2);
386 break;
387 case DFM_COMMAND:
388 CommandMsg(wnd, p1, p2);
389 return TRUE;
390 case DFM_INSIDE_WINDOW:
391 return DfInsideRect(p1, p2, DfWindowRect(wnd));
392 case DFM_CLOSE_POPDOWN:
393 ClosePopdownMsg(wnd);
394 return TRUE;
395 case DFM_CLOSE_WINDOW:
396 CloseWindowMsg(wnd);
397 rtn = DfBaseWndProc(DF_MENUBAR, wnd, msg, p1, p2);
398 return rtn;
399 default:
400 break;
401 }
402 return DfBaseWndProc(DF_MENUBAR, wnd, msg, p1, p2);
403 }
404
405 /* ------------- reset the DF_MENUBAR -------------- */
406 static void reset_menubar(DFWINDOW wnd)
407 {
408 DfGetText(wnd) = DfRealloc(DfGetText(wnd), DfGetScreenWidth()+5);
409 memset(DfGetText(wnd), ' ', DfGetScreenWidth());
410 *(DfGetText(wnd)+DfWindowWidth(wnd)) = '\0';
411 }
412
413 static DFWINDOW GetDocFocus(void)
414 {
415 DFWINDOW wnd = DfApplicationWindow;
416 if (wnd != NULL)
417 {
418 wnd = DfLastWindow(wnd);
419 while (wnd != NULL &&
420 (DfGetClass(wnd) == DF_MENUBAR ||
421 DfGetClass(wnd) == DF_STATUSBAR))
422 wnd = DfPrevWindow(wnd);
423 if (wnd != NULL)
424 {
425 while (wnd->childfocus != NULL)
426 wnd = wnd->childfocus;
427 }
428 }
429 return wnd ? wnd : DfApplicationWindow;
430 }
431
432 /* EOF */