home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
05
/
d_flat
/
popdown.c
< prev
next >
Wrap
Text File
|
1991-02-18
|
6KB
|
250 lines
/* ------------- popdown.c ----------- */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "dflat.h"
static int SelectionWidth(struct PopDown *);
extern char *Clipboard;
static MENU *mnu;
int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int wd, rtn, i;
struct PopDown *pd1;
char sep[80], *cp = sep;
char sel[80];
static struct PopDown *ActivePopDown = NULL;
switch (msg) {
case CREATE_WINDOW:
ClearAttribute(wnd, TITLEBAR |
VSCROLLBAR |
MOVEABLE |
SIZEABLE |
HSCROLLBAR);
rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
SendMessage(wnd, CAPTURE_MOUSE, 0, 0);
SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0);
SendMessage(NULLWND, SAVE_CURSOR, 0, 0);
SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
return rtn;
case SETFOCUS:
return FALSE;
case BUILD_SELECTIONS:
mnu = (void *) p1;
ActivePopDown = pd1 = mnu->Selections;
wd = MenuWidth(ActivePopDown)-2;
while (wd--)
*cp++ = LINE;
*cp = '\0';
while (pd1->SelectionTitle != NULL) {
if (*pd1->SelectionTitle == LINE)
SendMessage(wnd, ADDTEXT, (PARAM) sep, 0);
else {
memset(sel, '\0', sizeof sel);
if (pd1->Attrib & INACTIVE) {
strcpy(sel, " ");
*sel = CHANGECOLOR;
*(sel+1) = cfg.clr.InactiveSelFG | 0x80;
*(sel+2) = cfg.clr.PopDownBG | 0x80;
}
strcat(sel, " ");
CopyCommand(sel+strlen(sel), pd1->SelectionTitle,
pd1->Attrib & INACTIVE, cfg.clr.PopDownBG);
if (pd1->Attrib & CHECKED)
*sel = CHECKMARK;
if (pd1->Accelerator) {
int i;
int wd1 = 2+SelectionWidth(ActivePopDown) - strlen(pd1->SelectionTitle);
for (i = 0; keys[i].keylabel; i++)
if (keys[i].keycode == pd1->Accelerator) {
while (wd1--)
strcat(sel, " ");
strcat(sel, "[");
strcat(sel, keys[i].keylabel);
strcat(sel, "]");
break;
}
}
strcat(sel, " ");
sel[strlen(sel)-1] = RESETCOLOR;
SendMessage(wnd, ADDTEXT, (PARAM) sel, 0);
}
pd1++;
PostMessage(wnd, LB_SETSELECTION, mnu->Selection, 0);
}
break;
case HORIZSCROLL:
return FALSE;
case LEFT_BUTTON:
if (SendMessage(wnd, INSIDE_WINDOW, p1, p2))
break;
/* --- note: fall through here --- */
case DOUBLE_CLICK:
if (p2 == GetTop(GetParent(wnd)))
PostMessage(GetParent(wnd), msg, p1, p2);
SendMessage(wnd, CLOSE_WINDOW, 0, 0);
return FALSE;
case BORDER:
rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
for (i = 0; i < ClientHeight(wnd); i++) {
if (*TextLine(wnd, i) == LINE) {
wputch(wnd, LEDGE, -1, i);
wputch(wnd, REDGE, WindowWidth(wnd)-2, i);
}
}
return rtn;
case LB_SELECTION:
rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
if (ActivePopDown != NULL) {
mnu->Selection = (int)p1;
if (p2 && GetParent(wnd)) {
int *attr = &(ActivePopDown+(int)p1)->Attrib;
if (*attr & INACTIVE)
beep();
else if (*attr & TOGGLE) {
char *tl = TextLine(wnd, (int)p1);
*attr ^= CHECKED;
if (*attr & CHECKED)
*tl = CHECKMARK;
else
*tl = ' ';
SendMessage(wnd, PAINT, 0, 0);
}
else {
PostMessage(GetParent(wnd), COMMAND,
(ActivePopDown+(int)p1)->ActionId, p1);
SendMessage(wnd, CLOSE_WINDOW, 0, 0);
}
}
}
return rtn;
case KEYBOARD:
if (ActivePopDown != NULL) {
int c = tolower((int)p1);
int sel = 0;
struct PopDown *pd = ActivePopDown;
while (pd->SelectionTitle != NULL) {
char *cp = strchr(pd->SelectionTitle,
SHORTCUTCHAR);
if (cp && tolower(*(cp+1)) == c ||
pd->Accelerator == (int) p1) {
PostMessage(wnd, LB_SELECTION, sel, TRUE);
return TRUE;
}
pd++, sel++;
}
}
if (p1 == ESC) {
SendMessage(wnd, CLOSE_WINDOW, 0, 0);
return TRUE;
}
switch ((int)p1) {
case FWD:
case BS:
if (GetClass(GetParent(wnd)) == MENUBAR) {
PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
return TRUE;
}
break;
case UP:
if (wnd->selection == 0) {
if (wnd->wlines == ClientHeight(wnd)) {
PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
return TRUE;
}
}
return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
case DN:
if (wnd->selection == wnd->wlines-1) {
if (wnd->wlines == ClientHeight(wnd)) {
PostMessage(wnd, LB_SELECTION, 0, FALSE);
return TRUE;
}
}
return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
case HOME:
case END:
case '\r':
return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
}
return FALSE;
case CLOSE_WINDOW:
SendMessage(wnd, RELEASE_MOUSE, 0, 0);
SendMessage(wnd, RELEASE_KEYBOARD, 0, 0);
SendMessage(GetParent(wnd), CLOSE_POPDOWN, 0, 0);
ActivePopDown = NULL;
mnu = NULL;
SendMessage(NULLWND, RESTORE_CURSOR, 0, 0);
break;
default:
break;
}
return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
}
int MenuHeight(struct PopDown *pd)
{
int ht = 0;
while (pd[ht].SelectionTitle != NULL)
ht++;
return ht+2;
}
int MenuWidth(struct PopDown *pd)
{
int wd = 0, i;
int len = 0;
wd = SelectionWidth(pd);
while (pd->SelectionTitle != NULL) {
if (pd->Accelerator) {
for (i = 0; keys[i].keylabel; i++)
if (keys[i].keycode == pd->Accelerator) {
len = max(len, 2+strlen(keys[i].keylabel));
break;
}
}
pd++;
}
return wd+5+len;
}
static int SelectionWidth(struct PopDown *pd)
{
int wd = 0;
while (pd->SelectionTitle != NULL) {
int len = strlen(pd->SelectionTitle)-1;
wd = max(wd, len);
pd++;
}
return wd;
}
int CopyCommand(char *dest, char *src, int skipcolor, int bg)
{
char *d = dest;
while (*src && *src != '\n') {
if (*src == SHORTCUTCHAR) {
src++;
if (!skipcolor) {
*dest++ = CHANGECOLOR;
*dest++ = cfg.clr.ShortCutFG | 0x80;
*dest++ = bg | 0x80;
*dest++ = *src++;
*dest++ = RESETCOLOR;
}
}
else
*dest++ = *src++;
}
return (int) (dest - d);
}