1 /* ---------------- menubar.c ------------------ */
3 #include "dflat32/dflat.h"
5 static void reset_menubar(DFWINDOW
);
8 int x1
, x2
; /* position in menu bar */
9 char sc
; /* shortcut key value */
14 static MENU
*ActiveMenu
;
17 static BOOL Selecting
;
19 static DFWINDOW Cascaders
[MAXCASCADES
];
21 static DFWINDOW
GetDocFocus(void);
23 /* ----------- SETFOCUS Message ----------- */
24 static int SetFocusMsg(DFWINDOW wnd
, PARAM p1
)
27 rtn
= BaseWndProc(MENUBAR
, wnd
, SETFOCUS
, p1
, 0);
29 DfSendMessage(GetParent(wnd
), ADDSTATUS
, 0, 0);
33 /* --------- BUILDMENU Message --------- */
34 static void BuildMenuMsg(DFWINDOW wnd
, PARAM p1
)
39 ActiveMenuBar
= (MBAR
*) p1
;
40 ActiveMenu
= ActiveMenuBar
->PullDown
;
41 while (ActiveMenu
->Title
!= NULL
&&
42 ActiveMenu
->Title
!= (void*)-1)
45 if (strlen(GetText(wnd
)+offset
) <
46 strlen(ActiveMenu
->Title
)+3)
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
);
59 menu
[mctr
].sc
= tolower(*(cp
+1));
63 ActiveMenu
= ActiveMenuBar
->PullDown
;
66 /* ---------- PAINT Message ---------- */
67 static void PaintMsg(DFWINDOW wnd
)
72 DfSendMessage(GetParent(wnd
), ADDSTATUS
, 0, 0);
73 SetStandardColor(wnd
);
74 wputs(wnd
, GetText(wnd
), 0, 0);
75 if (ActiveMenuBar
== NULL
)
77 if (ActiveMenuBar
->ActiveSelection
!= -1 &&
78 (wnd
== inFocus
|| mwnd
!= NULL
)) {
83 offset
=menu
[ActiveMenuBar
->ActiveSelection
].x1
;
84 offset1
=menu
[ActiveMenuBar
->ActiveSelection
].x2
;
85 GetText(wnd
)[offset1
] = '\0';
87 memset(sel
, '\0', 200);
88 strcpy(sel
, GetText(wnd
)+offset
);
89 cp
= strchr(sel
, CHANGECOLOR
);
91 *(cp
+ 2) = background
| 0x80;
93 offset
-ActiveMenuBar
->ActiveSelection
*4, 0);
94 GetText(wnd
)[offset1
] = ' ';
95 if (mwnd
== NULL
&& wnd
== inFocus
) {
97 [ActiveMenuBar
->ActiveSelection
].StatusText
;
99 DfSendMessage(GetParent(wnd
), ADDSTATUS
,
106 /* ------------ KEYBOARD Message ------------- */
107 static void KeyboardMsg(DFWINDOW wnd
, PARAM p1
)
113 /* ----- search for menu bar shortcut keys ---- */
114 int c
= tolower((int)p1
);
115 int a
= AltConvert((int)p1
);
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);
126 /* -------- search for accelerator keys -------- */
128 while (mnu
->Title
!= (void *)-1) {
129 struct PopDown
*pd
= mnu
->Selections
;
131 (*(mnu
->PrepMenu
))(GetDocFocus(), mnu
);
132 while (pd
->SelectionTitle
!= NULL
) {
133 if (pd
->Accelerator
== (int) p1
) {
134 if (pd
->Attrib
& INACTIVE
)
137 if (pd
->Attrib
& TOGGLE
)
138 pd
->Attrib
^= CHECKED
;
139 DfSendMessage(GetDocFocus(),
141 DfPostMessage(GetParent(wnd
),
142 DFM_COMMAND
, pd
->ActionId
, 0);
153 if (ActiveMenu
== NULL
|| ActiveMenuBar
== NULL
)
155 sel
= ActiveMenuBar
->ActiveSelection
;
158 BaseWndProc(MENUBAR
, wnd
, KEYBOARD
, F1
, 0);
161 mnu
= ActiveMenu
+sel
;
163 mnu
->Selections
[0].SelectionTitle
== NULL
)
165 DisplayHelp(wnd
,mnu
->Title
+1);
172 ActiveMenuBar
->ActiveSelection
!= -1)
173 DfSendMessage(wnd
, MB_SELECTION
,
174 ActiveMenuBar
->ActiveSelection
, 0);
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);
184 /* ------- fall through ------- */
186 if (inFocus
== wnd
&& mwnd
== NULL
) {
187 ActiveMenuBar
->ActiveSelection
= -1;
188 DfSendMessage(GetDocFocus(),SETFOCUS
,TRUE
,0);
189 DfSendMessage(wnd
, PAINT
, 0, 0);
193 ActiveMenuBar
->ActiveSelection
++;
194 if (ActiveMenuBar
->ActiveSelection
== mctr
)
195 ActiveMenuBar
->ActiveSelection
= 0;
197 DfSendMessage(wnd
, MB_SELECTION
,
198 ActiveMenuBar
->ActiveSelection
, 0);
200 DfSendMessage(wnd
, PAINT
, 0, 0);
203 if (ActiveMenuBar
->ActiveSelection
== 0 ||
204 ActiveMenuBar
->ActiveSelection
== -1)
205 ActiveMenuBar
->ActiveSelection
= mctr
;
206 --ActiveMenuBar
->ActiveSelection
;
208 DfSendMessage(wnd
, MB_SELECTION
,
209 ActiveMenuBar
->ActiveSelection
, 0);
211 DfSendMessage(wnd
, PAINT
, 0, 0);
218 /* --------------- LEFT_BUTTON Message ---------- */
219 static void LeftButtonMsg(DFWINDOW wnd
, PARAM p1
)
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)
229 if (i
!= ActiveMenuBar
->ActiveSelection
|| mwnd
== NULL
)
230 DfSendMessage(wnd
, MB_SELECTION
, i
, 0);
233 /* -------------- MB_SELECTION Message -------------- */
234 static void SelectionMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
241 ActiveMenuBar
->ActiveSelection
= -1;
242 DfSendMessage(wnd
, PAINT
, 0, 0);
245 mnu
= ActiveMenu
+(int)p1
;
246 if (mnu
->PrepMenu
!= NULL
)
247 (*(mnu
->PrepMenu
))(GetDocFocus(), mnu
);
248 wd
= MenuWidth(mnu
->Selections
);
251 int brd
= GetRight(wnd
);
252 mx
= GetLeft(mwnd
) + WindowWidth(mwnd
) - 1;
255 my
= GetTop(mwnd
) + mwnd
->selection
;
259 int offset
= menu
[(int)p1
].x1
- 4 * (int)p1
;
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
;
268 mwnd
= DfCreateWindow(POPDOWNMENU
, NULL
,
270 MenuHeight(mnu
->Selections
),
279 DfSendMessage(wnd
, PAINT
, 0, 0);
282 if (mnu
->Selections
[0].SelectionTitle
!= NULL
)
284 DfSendMessage(mwnd
, BUILD_SELECTIONS
, (PARAM
) mnu
, 0);
285 DfSendMessage(mwnd
, SETFOCUS
, TRUE
, 0);
286 DfSendMessage(mwnd
, SHOW_WINDOW
, 0, 0);
291 /* --------- COMMAND Message ---------- */
292 static void CommandMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
296 BaseWndProc(MENUBAR
, wnd
, DFM_COMMAND
, p1
, p2
);
300 if (isCascadedCommand(ActiveMenuBar
, (int)p1
))
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
);
318 DfSendMessage(mwnd
, CLOSE_WINDOW
, 0, 0);
319 DfSendMessage(GetDocFocus(), SETFOCUS
, TRUE
, 0);
320 DfPostMessage(GetParent(wnd
), DFM_COMMAND
, p1
, p2
);
324 /* --------------- CLOSE_POPDOWN Message --------------- */
325 static void ClosePopdownMsg(DFWINDOW wnd
)
328 DfSendMessage(Cascaders
[--casc
], CLOSE_WINDOW
, 0, 0);
332 ActiveMenuBar
->ActiveSelection
= -1;
335 DfSendMessage(GetDocFocus(), SETFOCUS
, TRUE
, 0);
336 DfSendMessage(wnd
, PAINT
, 0, 0);
341 /* ---------------- CLOSE_WINDOW Message --------------- */
342 static void CloseWindowMsg(DFWINDOW wnd
)
344 if (GetText(wnd
) != NULL
)
350 ActiveMenuBar
->ActiveSelection
= -1;
352 ActiveMenuBar
= NULL
;
355 /* --- Window processing module for MENUBAR window class --- */
356 int MenuBarProc(DFWINDOW wnd
, DFMESSAGE msg
, PARAM p1
, PARAM p2
)
365 return SetFocusMsg(wnd
, p1
);
367 BuildMenuMsg(wnd
, p1
);
370 if (!isVisible(wnd
) || GetText(wnd
) == NULL
)
376 DfSendMessage(wnd
, PAINT
, 0, 0);
379 KeyboardMsg(wnd
, p1
);
382 LeftButtonMsg(wnd
, p1
);
385 SelectionMsg(wnd
, p1
, p2
);
388 CommandMsg(wnd
, p1
, p2
);
391 return InsideRect(p1
, p2
, WindowRect(wnd
));
393 ClosePopdownMsg(wnd
);
397 rtn
= BaseWndProc(MENUBAR
, wnd
, msg
, p1
, p2
);
402 return BaseWndProc(MENUBAR
, wnd
, msg
, p1
, p2
);
405 /* ------------- reset the MENUBAR -------------- */
406 static void reset_menubar(DFWINDOW wnd
)
408 GetText(wnd
) = DFrealloc(GetText(wnd
), DfGetScreenWidth()+5);
409 memset(GetText(wnd
), ' ', DfGetScreenWidth());
410 *(GetText(wnd
)+WindowWidth(wnd
)) = '\0';
413 static DFWINDOW
GetDocFocus(void)
415 DFWINDOW wnd
= ApplicationWindow
;
418 wnd
= LastWindow(wnd
);
419 while (wnd
!= NULL
&&
420 (GetClass(wnd
) == MENUBAR
||
421 GetClass(wnd
) == STATUSBAR
))
422 wnd
= PrevWindow(wnd
);
425 while (wnd
->childfocus
!= NULL
)
426 wnd
= wnd
->childfocus
;
429 return wnd
? wnd
: ApplicationWindow
;