1 /* ---------------- menubar.c ------------------ */
5 static void reset_menubar(DFWINDOW
);
8 int x1
, x2
; /* position in menu bar */
9 char sc
; /* shortcut key value */
13 DF_MBAR
*DfActiveMenuBar
;
14 static DF_MENU
*ActiveMenu
;
17 static BOOL Selecting
;
19 static DFWINDOW Cascaders
[DF_MAXCASCADES
];
21 static DFWINDOW
GetDocFocus(void);
23 /* ----------- DFM_SETFOCUS Message ----------- */
24 static int SetFocusMsg(DFWINDOW wnd
, DF_PARAM p1
)
27 rtn
= DfBaseWndProc(DF_MENUBAR
, wnd
, DFM_SETFOCUS
, p1
, 0);
29 DfSendMessage(DfGetParent(wnd
), DFM_ADDSTATUS
, 0, 0);
33 /* --------- DFM_BUILDMENU Message --------- */
34 static void BuildMenuMsg(DFWINDOW wnd
, DF_PARAM p1
)
39 DfActiveMenuBar
= (DF_MBAR
*) p1
;
40 ActiveMenu
= DfActiveMenuBar
->PullDown
;
41 while (ActiveMenu
->Title
!= NULL
&&
42 ActiveMenu
->Title
!= (void*)-1)
45 if (strlen(DfGetText(wnd
)+offset
) <
46 strlen(ActiveMenu
->Title
)+3)
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
);
59 menu
[mctr
].sc
= tolower(*(cp
+1));
63 ActiveMenu
= DfActiveMenuBar
->PullDown
;
66 /* ---------- DFM_PAINT Message ---------- */
67 static void PaintMsg(DFWINDOW wnd
)
72 DfSendMessage(DfGetParent(wnd
), DFM_ADDSTATUS
, 0, 0);
73 DfSetStandardColor(wnd
);
74 DfWPuts(wnd
, DfGetText(wnd
), 0, 0);
75 if (DfActiveMenuBar
== NULL
)
77 if (DfActiveMenuBar
->ActiveSelection
!= -1 &&
78 (wnd
== DfInFocus
|| mwnd
!= NULL
)) {
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
);
91 *(cp
+ 2) = DfBackground
| 0x80;
93 offset
-DfActiveMenuBar
->ActiveSelection
*4, 0);
94 DfGetText(wnd
)[offset1
] = ' ';
95 if (mwnd
== NULL
&& wnd
== DfInFocus
) {
97 [DfActiveMenuBar
->ActiveSelection
].StatusText
;
99 DfSendMessage(DfGetParent(wnd
), DFM_ADDSTATUS
,
106 /* ------------ DFM_KEYBOARD Message ------------- */
107 static void KeyboardMsg(DFWINDOW wnd
, DF_PARAM p1
)
113 /* ----- search for menu bar shortcut keys ---- */
114 int c
= tolower((int)p1
);
115 int a
= DfAltConvert((int)p1
);
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);
126 /* -------- search for accelerator keys -------- */
128 while (mnu
->Title
!= (void *)-1) {
129 struct DfPopDown
*pd
= mnu
->Selections
;
131 (*(mnu
->PrepMenu
))(GetDocFocus(), mnu
);
132 while (pd
->SelectionTitle
!= NULL
) {
133 if (pd
->Accelerator
== (int) p1
) {
134 if (pd
->Attrib
& DF_INACTIVE
)
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);
153 if (ActiveMenu
== NULL
|| DfActiveMenuBar
== NULL
)
155 sel
= DfActiveMenuBar
->ActiveSelection
;
158 DfBaseWndProc(DF_MENUBAR
, wnd
, DFM_KEYBOARD
, DF_F1
, 0);
161 mnu
= ActiveMenu
+sel
;
163 mnu
->Selections
[0].SelectionTitle
== NULL
)
165 DfDisplayHelp(wnd
,mnu
->Title
+1);
172 DfActiveMenuBar
->ActiveSelection
!= -1)
173 DfSendMessage(wnd
, DFM_MB_SELECTION
,
174 DfActiveMenuBar
->ActiveSelection
, 0);
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);
184 /* ------- fall through ------- */
186 if (DfInFocus
== wnd
&& mwnd
== NULL
) {
187 DfActiveMenuBar
->ActiveSelection
= -1;
188 DfSendMessage(GetDocFocus(),DFM_SETFOCUS
,TRUE
,0);
189 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
193 DfActiveMenuBar
->ActiveSelection
++;
194 if (DfActiveMenuBar
->ActiveSelection
== mctr
)
195 DfActiveMenuBar
->ActiveSelection
= 0;
197 DfSendMessage(wnd
, DFM_MB_SELECTION
,
198 DfActiveMenuBar
->ActiveSelection
, 0);
200 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
203 if (DfActiveMenuBar
->ActiveSelection
== 0 ||
204 DfActiveMenuBar
->ActiveSelection
== -1)
205 DfActiveMenuBar
->ActiveSelection
= mctr
;
206 --DfActiveMenuBar
->ActiveSelection
;
208 DfSendMessage(wnd
, DFM_MB_SELECTION
,
209 DfActiveMenuBar
->ActiveSelection
, 0);
211 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
218 /* --------------- DFM_LEFT_BUTTON Message ---------- */
219 static void LeftButtonMsg(DFWINDOW wnd
, DF_PARAM p1
)
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)
229 if (i
!= DfActiveMenuBar
->ActiveSelection
|| mwnd
== NULL
)
230 DfSendMessage(wnd
, DFM_MB_SELECTION
, i
, 0);
233 /* -------------- DFM_MB_SELECTION Message -------------- */
234 static void SelectionMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
241 DfActiveMenuBar
->ActiveSelection
= -1;
242 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
245 mnu
= ActiveMenu
+(int)p1
;
246 if (mnu
->PrepMenu
!= NULL
)
247 (*(mnu
->PrepMenu
))(GetDocFocus(), mnu
);
248 wd
= DfMenuWidth(mnu
->Selections
);
251 int brd
= DfGetRight(wnd
);
252 mx
= DfGetLeft(mwnd
) + DfWindowWidth(mwnd
) - 1;
255 my
= DfGetTop(mwnd
) + mwnd
->selection
;
259 int offset
= menu
[(int)p1
].x1
- 4 * (int)p1
;
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;
268 mwnd
= DfDfCreateWindow(DF_POPDOWNMENU
, NULL
,
270 DfMenuHeight(mnu
->Selections
),
279 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
282 if (mnu
->Selections
[0].SelectionTitle
!= NULL
)
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);
291 /* --------- COMMAND Message ---------- */
292 static void CommandMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
294 if (p1
== DF_ID_HELP
)
296 DfBaseWndProc(DF_MENUBAR
, wnd
, DFM_COMMAND
, p1
, p2
);
300 if (DfIsCascadedCommand(DfActiveMenuBar
, (int)p1
))
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
);
318 DfSendMessage(mwnd
, DFM_CLOSE_WINDOW
, 0, 0);
319 DfSendMessage(GetDocFocus(), DFM_SETFOCUS
, TRUE
, 0);
320 DfPostMessage(DfGetParent(wnd
), DFM_COMMAND
, p1
, p2
);
324 /* --------------- DFM_CLOSE_POPDOWN Message --------------- */
325 static void ClosePopdownMsg(DFWINDOW wnd
)
328 DfSendMessage(Cascaders
[--casc
], DFM_CLOSE_WINDOW
, 0, 0);
332 DfActiveMenuBar
->ActiveSelection
= -1;
335 DfSendMessage(GetDocFocus(), DFM_SETFOCUS
, TRUE
, 0);
336 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
341 /* ---------------- DFM_CLOSE_WINDOW Message --------------- */
342 static void CloseWindowMsg(DFWINDOW wnd
)
344 if (DfGetText(wnd
) != NULL
)
346 free(DfGetText(wnd
));
347 DfGetText(wnd
) = NULL
;
350 DfActiveMenuBar
->ActiveSelection
= -1;
352 DfActiveMenuBar
= NULL
;
355 /* --- Window processing module for DF_MENUBAR window class --- */
356 int DfMenuBarProc(DFWINDOW wnd
, DFMESSAGE msg
, DF_PARAM p1
, DF_PARAM p2
)
361 case DFM_CREATE_WINDOW
:
365 return SetFocusMsg(wnd
, p1
);
367 BuildMenuMsg(wnd
, p1
);
370 if (!DfIsVisible(wnd
) || DfGetText(wnd
) == NULL
)
376 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
379 KeyboardMsg(wnd
, p1
);
381 case DFM_LEFT_BUTTON
:
382 LeftButtonMsg(wnd
, p1
);
384 case DFM_MB_SELECTION
:
385 SelectionMsg(wnd
, p1
, p2
);
388 CommandMsg(wnd
, p1
, p2
);
390 case DFM_INSIDE_WINDOW
:
391 return DfInsideRect(p1
, p2
, DfWindowRect(wnd
));
392 case DFM_CLOSE_POPDOWN
:
393 ClosePopdownMsg(wnd
);
395 case DFM_CLOSE_WINDOW
:
397 rtn
= DfBaseWndProc(DF_MENUBAR
, wnd
, msg
, p1
, p2
);
402 return DfBaseWndProc(DF_MENUBAR
, wnd
, msg
, p1
, p2
);
405 /* ------------- reset the DF_MENUBAR -------------- */
406 static void reset_menubar(DFWINDOW wnd
)
408 DfGetText(wnd
) = DfRealloc(DfGetText(wnd
), DfGetScreenWidth()+5);
409 memset(DfGetText(wnd
), ' ', DfGetScreenWidth());
410 *(DfGetText(wnd
)+DfWindowWidth(wnd
)) = '\0';
413 static DFWINDOW
GetDocFocus(void)
415 DFWINDOW wnd
= DfApplicationWindow
;
418 wnd
= DfLastWindow(wnd
);
419 while (wnd
!= NULL
&&
420 (DfGetClass(wnd
) == DF_MENUBAR
||
421 DfGetClass(wnd
) == DF_STATUSBAR
))
422 wnd
= DfPrevWindow(wnd
);
425 while (wnd
->childfocus
!= NULL
)
426 wnd
= wnd
->childfocus
;
429 return wnd
? wnd
: DfApplicationWindow
;