mirror of
https://github.com/reactos/reactos.git
synced 2024-08-17 17:07:37 +00:00
433 lines
12 KiB
C
433 lines
12 KiB
C
/* ---------------- menubar.c ------------------ */
|
|
|
|
#include "dflat.h"
|
|
|
|
static void reset_menubar(DFWINDOW);
|
|
|
|
static struct {
|
|
int x1, x2; /* position in menu bar */
|
|
char sc; /* shortcut key value */
|
|
} menu[10];
|
|
static int mctr;
|
|
|
|
DF_MBAR *DfActiveMenuBar;
|
|
static DF_MENU *ActiveMenu;
|
|
|
|
static DFWINDOW mwnd;
|
|
static BOOL Selecting;
|
|
|
|
static DFWINDOW Cascaders[DF_MAXCASCADES];
|
|
static int casc;
|
|
static DFWINDOW GetDocFocus(void);
|
|
|
|
/* ----------- DFM_SETFOCUS Message ----------- */
|
|
static int SetFocusMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
int rtn;
|
|
rtn = DfBaseWndProc(DF_MENUBAR, wnd, DFM_SETFOCUS, p1, 0);
|
|
if (!(int)p1)
|
|
DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS, 0, 0);
|
|
return rtn;
|
|
}
|
|
|
|
/* --------- DFM_BUILDMENU Message --------- */
|
|
static void BuildMenuMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
int offset = 3;
|
|
reset_menubar(wnd);
|
|
mctr = 0;
|
|
DfActiveMenuBar = (DF_MBAR *) p1;
|
|
ActiveMenu = DfActiveMenuBar->PullDown;
|
|
while (ActiveMenu->Title != NULL &&
|
|
ActiveMenu->Title != (void*)-1)
|
|
{
|
|
char *cp;
|
|
if (strlen(DfGetText(wnd)+offset) <
|
|
strlen(ActiveMenu->Title)+3)
|
|
break;
|
|
DfGetText(wnd) = DfRealloc(DfGetText(wnd),
|
|
strlen(DfGetText(wnd))+5);
|
|
memmove(DfGetText(wnd) + offset+4, DfGetText(wnd) + offset,
|
|
strlen(DfGetText(wnd))-offset+1);
|
|
DfCopyCommand(DfGetText(wnd)+offset,ActiveMenu->Title,FALSE,
|
|
wnd->WindowColors [DF_STD_COLOR] [DF_BG]);
|
|
menu[mctr].x1 = offset;
|
|
offset += strlen(ActiveMenu->Title) + (3+DF_MSPACE);
|
|
menu[mctr].x2 = offset-DF_MSPACE;
|
|
cp = strchr(ActiveMenu->Title, DF_SHORTCUTCHAR);
|
|
if (cp)
|
|
menu[mctr].sc = tolower(*(cp+1));
|
|
mctr++;
|
|
ActiveMenu++;
|
|
}
|
|
ActiveMenu = DfActiveMenuBar->PullDown;
|
|
}
|
|
|
|
/* ---------- DFM_PAINT Message ---------- */
|
|
static void PaintMsg(DFWINDOW wnd)
|
|
{
|
|
if (Selecting)
|
|
return;
|
|
if (wnd == DfInFocus)
|
|
DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS, 0, 0);
|
|
DfSetStandardColor(wnd);
|
|
DfWPuts(wnd, DfGetText(wnd), 0, 0);
|
|
if (DfActiveMenuBar == NULL)
|
|
return;
|
|
if (DfActiveMenuBar->ActiveSelection != -1 &&
|
|
(wnd == DfInFocus || mwnd != NULL)) {
|
|
char *sel, *cp;
|
|
int offset, offset1;
|
|
|
|
sel = DfMalloc(200);
|
|
offset=menu[DfActiveMenuBar->ActiveSelection].x1;
|
|
offset1=menu[DfActiveMenuBar->ActiveSelection].x2;
|
|
DfGetText(wnd)[offset1] = '\0';
|
|
DfSetReverseColor(wnd);
|
|
memset(sel, '\0', 200);
|
|
strcpy(sel, DfGetText(wnd)+offset);
|
|
cp = strchr(sel, DF_CHANGECOLOR);
|
|
if (cp != NULL)
|
|
*(cp + 2) = DfBackground | 0x80;
|
|
DfWPuts(wnd, sel,
|
|
offset-DfActiveMenuBar->ActiveSelection*4, 0);
|
|
DfGetText(wnd)[offset1] = ' ';
|
|
if (mwnd == NULL && wnd == DfInFocus) {
|
|
char *st = ActiveMenu
|
|
[DfActiveMenuBar->ActiveSelection].StatusText;
|
|
if (st != NULL)
|
|
DfSendMessage(DfGetParent(wnd), DFM_ADDSTATUS,
|
|
(DF_PARAM)st, 0);
|
|
}
|
|
free(sel);
|
|
}
|
|
}
|
|
|
|
/* ------------ DFM_KEYBOARD Message ------------- */
|
|
static void KeyboardMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
DF_MENU *mnu;
|
|
int sel;
|
|
if (mwnd == NULL)
|
|
{
|
|
/* ----- search for menu bar shortcut keys ---- */
|
|
int c = tolower((int)p1);
|
|
int a = DfAltConvert((int)p1);
|
|
int j;
|
|
for (j = 0; j < mctr; j++) {
|
|
if ((DfInFocus == wnd && menu[j].sc == c) ||
|
|
(a && menu[j].sc == a)) {
|
|
DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
|
|
DfSendMessage(wnd, DFM_MB_SELECTION, j, 0);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
/* -------- search for accelerator keys -------- */
|
|
mnu = ActiveMenu;
|
|
while (mnu->Title != (void *)-1) {
|
|
struct DfPopDown *pd = mnu->Selections;
|
|
if (mnu->PrepMenu)
|
|
(*(mnu->PrepMenu))(GetDocFocus(), mnu);
|
|
while (pd->SelectionTitle != NULL) {
|
|
if (pd->Accelerator == (int) p1) {
|
|
if (pd->Attrib & DF_INACTIVE)
|
|
DfBeep();
|
|
else {
|
|
if (pd->Attrib & DF_TOGGLE)
|
|
pd->Attrib ^= DF_CHECKED;
|
|
DfSendMessage(GetDocFocus(),
|
|
DFM_SETFOCUS, TRUE, 0);
|
|
DfPostMessage(DfGetParent(wnd),
|
|
DFM_COMMAND, pd->ActionId, 0);
|
|
}
|
|
return;
|
|
}
|
|
pd++;
|
|
}
|
|
mnu++;
|
|
}
|
|
switch ((int)p1)
|
|
{
|
|
case DF_F1:
|
|
if (ActiveMenu == NULL || DfActiveMenuBar == NULL)
|
|
break;
|
|
sel = DfActiveMenuBar->ActiveSelection;
|
|
if (sel == -1)
|
|
{
|
|
DfBaseWndProc(DF_MENUBAR, wnd, DFM_KEYBOARD, DF_F1, 0);
|
|
return;
|
|
}
|
|
mnu = ActiveMenu+sel;
|
|
if (mwnd == NULL ||
|
|
mnu->Selections[0].SelectionTitle == NULL)
|
|
{
|
|
DfDisplayHelp(wnd,mnu->Title+1);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case '\r':
|
|
if (mwnd == NULL &&
|
|
DfActiveMenuBar->ActiveSelection != -1)
|
|
DfSendMessage(wnd, DFM_MB_SELECTION,
|
|
DfActiveMenuBar->ActiveSelection, 0);
|
|
break;
|
|
case DF_F10:
|
|
if (wnd != DfInFocus && mwnd == NULL) {
|
|
DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
|
|
if ( DfActiveMenuBar->ActiveSelection == -1)
|
|
DfActiveMenuBar->ActiveSelection = 0;
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
break;
|
|
}
|
|
/* ------- fall through ------- */
|
|
case DF_ESC:
|
|
if (DfInFocus == wnd && mwnd == NULL) {
|
|
DfActiveMenuBar->ActiveSelection = -1;
|
|
DfSendMessage(GetDocFocus(),DFM_SETFOCUS,TRUE,0);
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
}
|
|
break;
|
|
case DF_FWD:
|
|
DfActiveMenuBar->ActiveSelection++;
|
|
if (DfActiveMenuBar->ActiveSelection == mctr)
|
|
DfActiveMenuBar->ActiveSelection = 0;
|
|
if (mwnd != NULL)
|
|
DfSendMessage(wnd, DFM_MB_SELECTION,
|
|
DfActiveMenuBar->ActiveSelection, 0);
|
|
else
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
break;
|
|
case DF_BS:
|
|
if (DfActiveMenuBar->ActiveSelection == 0 ||
|
|
DfActiveMenuBar->ActiveSelection == -1)
|
|
DfActiveMenuBar->ActiveSelection = mctr;
|
|
--DfActiveMenuBar->ActiveSelection;
|
|
if (mwnd != NULL)
|
|
DfSendMessage(wnd, DFM_MB_SELECTION,
|
|
DfActiveMenuBar->ActiveSelection, 0);
|
|
else
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* --------------- DFM_LEFT_BUTTON Message ---------- */
|
|
static void LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1)
|
|
{
|
|
int i;
|
|
int mx = (int) p1 - DfGetLeft(wnd);
|
|
/* --- compute the selection that the left button hit --- */
|
|
for (i = 0; i < mctr; i++)
|
|
if (mx >= menu[i].x1-4*i &&
|
|
mx <= menu[i].x2-4*i-5)
|
|
break;
|
|
if (i < mctr)
|
|
if (i != DfActiveMenuBar->ActiveSelection || mwnd == NULL)
|
|
DfSendMessage(wnd, DFM_MB_SELECTION, i, 0);
|
|
}
|
|
|
|
/* -------------- DFM_MB_SELECTION Message -------------- */
|
|
static void SelectionMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
int wd, mx, my;
|
|
DF_MENU *mnu;
|
|
|
|
if (!p2)
|
|
{
|
|
DfActiveMenuBar->ActiveSelection = -1;
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
}
|
|
Selecting = TRUE;
|
|
mnu = ActiveMenu+(int)p1;
|
|
if (mnu->PrepMenu != NULL)
|
|
(*(mnu->PrepMenu))(GetDocFocus(), mnu);
|
|
wd = DfMenuWidth(mnu->Selections);
|
|
if (p2)
|
|
{
|
|
int brd = DfGetRight(wnd);
|
|
mx = DfGetLeft(mwnd) + DfWindowWidth(mwnd) - 1;
|
|
if (mx + wd > brd)
|
|
mx = brd - wd;
|
|
my = DfGetTop(mwnd) + mwnd->selection;
|
|
}
|
|
else
|
|
{
|
|
int offset = menu[(int)p1].x1 - 4 * (int)p1;
|
|
if (mwnd != NULL)
|
|
DfSendMessage(mwnd, DFM_CLOSE_WINDOW, 0, 0);
|
|
DfActiveMenuBar->ActiveSelection = (int) p1;
|
|
if (offset > DfWindowWidth(wnd)-wd)
|
|
offset = DfWindowWidth(wnd)-wd;
|
|
mx = DfGetLeft(wnd)+offset;
|
|
my = DfGetTop(wnd)+1;
|
|
}
|
|
mwnd = DfDfCreateWindow(DF_POPDOWNMENU, NULL,
|
|
mx, my,
|
|
DfMenuHeight(mnu->Selections),
|
|
wd,
|
|
NULL,
|
|
wnd,
|
|
NULL,
|
|
DF_SHADOW);
|
|
if (!p2)
|
|
{
|
|
Selecting = FALSE;
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
Selecting = TRUE;
|
|
}
|
|
if (mnu->Selections[0].SelectionTitle != NULL)
|
|
{
|
|
DfSendMessage(mwnd, DFM_BUILD_SELECTIONS, (DF_PARAM) mnu, 0);
|
|
DfSendMessage(mwnd, DFM_SETFOCUS, TRUE, 0);
|
|
DfSendMessage(mwnd, DFM_SHOW_WINDOW, 0, 0);
|
|
}
|
|
Selecting = FALSE;
|
|
}
|
|
|
|
/* --------- COMMAND Message ---------- */
|
|
static void CommandMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
if (p1 == DF_ID_HELP)
|
|
{
|
|
DfBaseWndProc(DF_MENUBAR, wnd, DFM_COMMAND, p1, p2);
|
|
return;
|
|
}
|
|
|
|
if (DfIsCascadedCommand(DfActiveMenuBar, (int)p1))
|
|
{
|
|
/* find the cascaded menu based on command id in p1 */
|
|
DF_MENU *mnu = ActiveMenu+mctr;
|
|
while (mnu->Title != (void *)-1) {
|
|
if (mnu->CascadeId == (int) p1) {
|
|
if (casc < DF_MAXCASCADES) {
|
|
Cascaders[casc++] = mwnd;
|
|
DfSendMessage(wnd, DFM_MB_SELECTION,
|
|
(DF_PARAM)(mnu-ActiveMenu), TRUE);
|
|
}
|
|
break;
|
|
}
|
|
mnu++;
|
|
}
|
|
}
|
|
else {
|
|
if (mwnd != NULL)
|
|
DfSendMessage(mwnd, DFM_CLOSE_WINDOW, 0, 0);
|
|
DfSendMessage(GetDocFocus(), DFM_SETFOCUS, TRUE, 0);
|
|
DfPostMessage(DfGetParent(wnd), DFM_COMMAND, p1, p2);
|
|
}
|
|
}
|
|
|
|
/* --------------- DFM_CLOSE_POPDOWN Message --------------- */
|
|
static void ClosePopdownMsg(DFWINDOW wnd)
|
|
{
|
|
if (casc > 0)
|
|
DfSendMessage(Cascaders[--casc], DFM_CLOSE_WINDOW, 0, 0);
|
|
else
|
|
{
|
|
mwnd = NULL;
|
|
DfActiveMenuBar->ActiveSelection = -1;
|
|
if (!Selecting)
|
|
{
|
|
DfSendMessage(GetDocFocus(), DFM_SETFOCUS, TRUE, 0);
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------- DFM_CLOSE_WINDOW Message --------------- */
|
|
static void CloseWindowMsg(DFWINDOW wnd)
|
|
{
|
|
if (DfGetText(wnd) != NULL)
|
|
{
|
|
free(DfGetText(wnd));
|
|
DfGetText(wnd) = NULL;
|
|
}
|
|
mctr = 0;
|
|
DfActiveMenuBar->ActiveSelection = -1;
|
|
ActiveMenu = NULL;
|
|
DfActiveMenuBar = NULL;
|
|
}
|
|
|
|
/* --- Window processing module for DF_MENUBAR window class --- */
|
|
int DfMenuBarProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
|
|
{
|
|
int rtn;
|
|
|
|
switch (msg) {
|
|
case DFM_CREATE_WINDOW:
|
|
reset_menubar(wnd);
|
|
break;
|
|
case DFM_SETFOCUS:
|
|
return SetFocusMsg(wnd, p1);
|
|
case DFM_BUILDMENU:
|
|
BuildMenuMsg(wnd, p1);
|
|
break;
|
|
case DFM_PAINT:
|
|
if (!DfIsVisible(wnd) || DfGetText(wnd) == NULL)
|
|
break;
|
|
PaintMsg(wnd);
|
|
return FALSE;
|
|
case DFM_BORDER:
|
|
if (mwnd == NULL)
|
|
DfSendMessage(wnd, DFM_PAINT, 0, 0);
|
|
return TRUE;
|
|
case DFM_KEYBOARD:
|
|
KeyboardMsg(wnd, p1);
|
|
return TRUE;
|
|
case DFM_LEFT_BUTTON:
|
|
LeftButtonMsg(wnd, p1);
|
|
return TRUE;
|
|
case DFM_MB_SELECTION:
|
|
SelectionMsg(wnd, p1, p2);
|
|
break;
|
|
case DFM_COMMAND:
|
|
CommandMsg(wnd, p1, p2);
|
|
return TRUE;
|
|
case DFM_INSIDE_WINDOW:
|
|
return DfInsideRect(p1, p2, DfWindowRect(wnd));
|
|
case DFM_CLOSE_POPDOWN:
|
|
ClosePopdownMsg(wnd);
|
|
return TRUE;
|
|
case DFM_CLOSE_WINDOW:
|
|
CloseWindowMsg(wnd);
|
|
rtn = DfBaseWndProc(DF_MENUBAR, wnd, msg, p1, p2);
|
|
return rtn;
|
|
default:
|
|
break;
|
|
}
|
|
return DfBaseWndProc(DF_MENUBAR, wnd, msg, p1, p2);
|
|
}
|
|
|
|
/* ------------- reset the DF_MENUBAR -------------- */
|
|
static void reset_menubar(DFWINDOW wnd)
|
|
{
|
|
DfGetText(wnd) = DfRealloc(DfGetText(wnd), DfGetScreenWidth()+5);
|
|
memset(DfGetText(wnd), ' ', DfGetScreenWidth());
|
|
*(DfGetText(wnd)+DfWindowWidth(wnd)) = '\0';
|
|
}
|
|
|
|
static DFWINDOW GetDocFocus(void)
|
|
{
|
|
DFWINDOW wnd = DfApplicationWindow;
|
|
if (wnd != NULL)
|
|
{
|
|
wnd = DfLastWindow(wnd);
|
|
while (wnd != NULL &&
|
|
(DfGetClass(wnd) == DF_MENUBAR ||
|
|
DfGetClass(wnd) == DF_STATUSBAR))
|
|
wnd = DfPrevWindow(wnd);
|
|
if (wnd != NULL)
|
|
{
|
|
while (wnd->childfocus != NULL)
|
|
wnd = wnd->childfocus;
|
|
}
|
|
}
|
|
return wnd ? wnd : DfApplicationWindow;
|
|
}
|
|
|
|
/* EOF */
|