home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
05
/
d_flat
/
menubar.c
< prev
next >
Wrap
Text File
|
1991-02-18
|
7KB
|
279 lines
/* ---------------- menubar.c -------------- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dflat.h"
static void reset_menubar(void);
static void ClosePopDown(void);
static int TestGlobalKeys(PARAM, PARAM);
static char *menubar;
static struct {
int x1, x2; /* position in menu bar */
char sc; /* shortcut key value */
} menu[10];
static int mctr;
MENU *ActiveMenu;
int ActiveSelection = -1;
static WINDOW mwnd = NULL;
#define MSPACE 2
int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int offset = 3, wd, offset1, i, j;
int mx = (int) p1 - GetLeft(wnd);
MENU *mnu;
switch (msg) {
case CREATE_WINDOW:
reset_menubar();
PostMessage(wnd, PAINT, 0, 0);
break;
case COMMAND:
PostMessage(GetParent(wnd), msg, p1, p2);
return FALSE;
case SETFOCUS:
if (p1) {
if (!p2)
return FALSE;
else {
/* --- accept the focus only if there are no others --- */
WINDOW wnd1 = Focus.FirstWindow;
while (wnd1 != NULLWND) {
if (wnd != wnd1 && GetParent(wnd) == GetParent(wnd1))
break;
wnd1 = NextWindow(wnd1);
}
if (wnd1 != NULLWND)
return FALSE;
}
}
break;
case BUILDMENU:
reset_menubar();
mctr = 0;
ActiveMenu = (MENU *) p1;
while (ActiveMenu->Title != NULL) {
char *cp;
menubar = realloc(menubar, strlen(menubar)+5);
memmove(menubar + offset+4, menubar + offset, strlen(menubar)-offset+1);
CopyCommand(menubar+offset, ActiveMenu->Title, FALSE, cfg.clr.MenuBarBG);
menu[mctr].x1 = offset;
offset += strlen(ActiveMenu->Title) + (3+MSPACE);
menu[mctr].x2 = offset-MSPACE;
cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
if (cp)
menu[mctr].sc = tolower(*(cp+1));
ActiveMenu++;
mctr++;
}
ActiveMenu = (MENU *) p1;
break;
case PAINT:
if (!isVisible(wnd))
break;
SetStandardColor(wnd);
writefull(wnd, menubar, 0);
if (ActiveSelection != -1) {
char sel[80], *cp;
offset = menu[ActiveSelection].x1;
offset1 = menu[ActiveSelection].x2;
menubar[offset1] = '\0';
SetReverseColor(wnd);
memset(sel, '\0', sizeof sel);
strcpy(sel, menubar+offset);
cp = strchr(sel, CHANGECOLOR);
if (cp != NULL)
*(cp + 2) = background | 0x80;
wputs(wnd, sel, offset-ActiveSelection*(MSPACE+2), 0);
menubar[offset1] = ' ';
}
return FALSE;
case KEYBOARD:
if (mwnd == NULL) {
/* ----- search for menu bar shortcut keys ---- */
for (i = 0; i < 26; i++)
if ((char) p1 == altconvert[i])
break;
if (i < 26) {
for (j = 0; j < mctr; j++) {
if (menu[j].sc == 'a' + i) {
SendMessage(wnd, SELECTION, j, 0);
return FALSE;
}
}
}
}
/* -------- search for accelerator keys -------- */
mnu = ActiveMenu;
while (mnu->Title != NULL) {
struct PopDown *pd = mnu->Selections;
if (mnu->PrepMenu)
(*(mnu->PrepMenu))(GetParent(wnd), mnu);
while (pd->SelectionTitle != NULL) {
if (pd->Accelerator == (int) p1) {
if (pd->Attrib & INACTIVE)
beep();
else
PostMessage(GetParent(wnd),
COMMAND, pd->ActionId, 0);
return TRUE;
}
pd++;
}
mnu++;
}
if (TestGlobalKeys(p1, p2))
return FALSE;
if (mwnd == NULLWND)
return FALSE;
switch ((int)p1) {
case FWD:
ActiveSelection++;
if (ActiveSelection == mctr)
ActiveSelection = 0;
SendMessage(wnd, SELECTION, ActiveSelection, 0);
return FALSE;
case BS:
if (ActiveSelection == 0)
ActiveSelection = mctr;
--ActiveSelection;
SendMessage(wnd, SELECTION, ActiveSelection, 0);
return FALSE;
default:
break;
}
if (mwnd == (void *)-1)
return FALSE;
break;
case LEFT_BUTTON:
for (i = 0; i < mctr; i++)
if (mx >= menu[i].x1-(MSPACE+2)*i &&
mx <= menu[i].x2-(MSPACE+2)*i-5)
break;
if (i < mctr) {
if (i != ActiveSelection || mwnd == NULL) {
SendMessage(wnd, SELECTION, i, 0);
SendMessage(NULLWND, WAITMOUSE, 0, 0);
}
}
break;
case SELECTION:
if (mwnd && mwnd != (void *)-1)
SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
mwnd = NULL;
ActiveSelection = (int) p1;
offset = menu[ActiveSelection].x1 -
(MSPACE+2) * ActiveSelection;
mnu = ActiveMenu+ActiveSelection;
if (mnu->PrepMenu != NULL)
(*(mnu->PrepMenu))(GetParent(wnd), mnu);
wd = MenuWidth(mnu->Selections);
if (offset > WindowWidth(wnd)-wd)
offset = WindowWidth(wnd)-wd;
if (mnu->Selections[0].SelectionTitle != NULL) {
mwnd = CreateWindow(POPDOWNMENU, NULL,
GetLeft(wnd)+offset, GetTop(wnd)+1,
MenuHeight(mnu->Selections),
wd,
NULL,
wnd,
NULL,
0);
AddAttribute(mwnd, SHADOW);
SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
SendMessage(wnd, PAINT, 0, 0);
SendMessage(mwnd, SHOW_WINDOW, 0, 0);
}
else
mwnd = (void *)-1;
SendMessage(wnd, PAINT, 0, 0);
break;
case BORDER:
return TRUE;
case INSIDE_WINDOW:
return InsideRect(p1, p2, WindowRect(wnd));
case CLOSE_POPDOWN:
ClosePopDown();
SendMessage(wnd, PAINT, 0, 0);
break;
case CLOSE_WINDOW:
if (menubar != NULL)
free(menubar);
mctr = 0;
ActiveSelection = -1;
ActiveMenu = NULL;
break;
default:
break;
}
return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
}
static void reset_menubar(void)
{
menubar = realloc(menubar, SCREENWIDTH+5);
memset(menubar, ' ', SCREENWIDTH);
*(menubar+SCREENWIDTH) = '\0';
}
static void ClosePopDown(void)
{
ActiveSelection = -1;
mwnd = NULLWND;
}
static int TestGlobalKeys(PARAM p1, PARAM p2)
{
switch ((int)p1) {
case ALT_F6:
if (GetClass(inFocus) != MENUBAR &&
GetClass(inFocus) != POPDOWNMENU)
SetNextFocus(inFocus, FALSE);
return TRUE;
case ALT_HYPHEN:
if (GetClass(inFocus) == POPDOWNMENU)
SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
if (GetClass(GetParent(inFocus)) == APPLICATION)
BuildSystemMenu(GetParent(inFocus));
return TRUE;
case ' ':
if (p2 & ALTKEY) {
if (GetClass(inFocus) == POPDOWNMENU)
SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
if (GetClass(inFocus) != MENUBAR &&
TestAttribute(inFocus, TITLEBAR) &&
TestAttribute(inFocus, CONTROLBOX))
BuildSystemMenu(inFocus);
return TRUE;
}
break;
case ALT_F4:
if (GetClass(inFocus) != MENUBAR)
PostMessage(inFocus, CLOSE_WINDOW, 0, 0);
else
PostMessage(GetParent(inFocus), CLOSE_WINDOW, 0, 0);
return TRUE;
default:
break;
}
return FALSE;
}