📄 helpbox.c
字号:
/* ------------ helpbox.c ----------- */
#include "dflat.h"
#include "htree.h"
extern DF_DBOX HelpBox;
/* -------- strings of D-Flat classes for calling default
help text collections -------- */
char *DfClassNames[] = {
#undef DfClassDef
#define DfClassDef(c,b,p,a) #c,
#include "classes.h"
NULL
};
#define MAXHEIGHT (DfGetScreenHeight()-10)
/* --------- linked list of help text collections -------- */
struct helps {
char *hname;
char *NextName;
char *PrevName;
long hptr;
int bit;
int hheight;
int hwidth;
DFWINDOW hwnd;
struct helps *NextHelp;
};
static struct helps *FirstHelp;
static struct helps *LastHelp;
static struct helps *ThisHelp;
/* --- linked stack of help windows that have beed used --- */
struct HelpStack {
char *hname;
struct HelpStack *PrevStack;
};
static struct HelpStack *LastStack;
static struct HelpStack *ThisStack;
/* --- linked list of keywords in the current help
text collection (listhead is in window) -------- */
struct keywords {
char *hname;
int lineno;
int off1, off2, off3;
int isDefinition;
struct keywords *nextword;
struct keywords *prevword;
};
static FILE *helpfp;
static char hline [160];
static BOOL Helping;
static void SelectHelp(DFWINDOW, char *);
static void ReadHelp(DFWINDOW);
static void FindHelp(char *);
static void FindHelpWindow(DFWINDOW);
static void DisplayDefinition(DFWINDOW, char *);
static void BestFit(DFWINDOW, DF_DIALOGWINDOW *);
/* ------------- DFM_CREATE_WINDOW message ------------ */
static void CreateWindowMsg(DFWINDOW wnd)
{
Helping = TRUE;
DfGetClass(wnd) = DF_HELPBOX;
DfInitWindowColors(wnd);
if (ThisHelp != NULL)
ThisHelp->hwnd = wnd;
}
/* ------------- COMMAND message ------------ */
static BOOL CommandMsg(DFWINDOW wnd, DF_PARAM p1)
{
switch ((int)p1) {
case DF_ID_CANCEL:
ThisStack = LastStack;
while (ThisStack != NULL) {
LastStack = ThisStack->PrevStack;
if (ThisStack->hname != NULL)
free(ThisStack->hname);
free(ThisStack);
ThisStack = LastStack;
}
break;
case DF_ID_PREV:
FindHelpWindow(wnd);
if (ThisHelp != NULL)
SelectHelp(wnd, ThisHelp->PrevName);
return TRUE;
case DF_ID_NEXT:
FindHelpWindow(wnd);
if (ThisHelp != NULL)
SelectHelp(wnd, ThisHelp->NextName);
return TRUE;
case DF_ID_BACK:
if (LastStack != NULL) {
if (LastStack->PrevStack != NULL) {
ThisStack = LastStack->PrevStack;
if (LastStack->hname != NULL)
free(LastStack->hname);
free(LastStack);
LastStack = ThisStack;
SelectHelp(wnd, ThisStack->hname);
}
}
return TRUE;
default:
break;
}
return FALSE;
}
/* ------------- DFM_KEYBOARD message ------------ */
static BOOL KeyboardMsg(DFWINDOW wnd, DF_PARAM p1)
{
DFWINDOW cwnd;
struct keywords *thisword;
static char HelpName[50];
cwnd = DfControlWindow(wnd->extension, DF_ID_HELPTEXT);
if (cwnd == NULL || DfInFocus != cwnd)
return FALSE;
thisword = cwnd->thisword;
switch ((int)p1) {
case '\r':
if (thisword != NULL) {
if (thisword->isDefinition)
DisplayDefinition(DfGetParent(wnd),
thisword->hname);
else {
strncpy(HelpName, thisword->hname,
sizeof HelpName);
SelectHelp(wnd, HelpName);
}
}
return TRUE;
case '\t':
if (thisword == NULL)
thisword = cwnd->firstword;
else {
if (thisword->nextword == NULL)
thisword = cwnd->firstword;
else
thisword = thisword->nextword;
}
break;
case DF_SHIFT_HT:
if (thisword == NULL)
thisword = cwnd->lastword;
else {
if (thisword->prevword == NULL)
thisword = cwnd->lastword;
else
thisword = thisword->prevword;
}
break;
default:
thisword = NULL;
break;
}
if (thisword != NULL) {
cwnd->thisword = thisword;
if (thisword->lineno < cwnd->wtop ||
thisword->lineno >=
cwnd->wtop + DfClientHeight(cwnd)) {
int distance = DfClientHeight(cwnd)/2;
do {
cwnd->wtop = thisword->lineno-distance;
distance /= 2;
}
while (cwnd->wtop < 0);
}
DfSendMessage(cwnd, DFM_PAINT, 0, 0);
return TRUE;
}
return FALSE;
}
/* ---- window processing module for the DF_HELPBOX ------- */
int DfHelpBoxProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
{
DF_DBOX *db = wnd->extension;
switch (msg) {
case DFM_CREATE_WINDOW:
CreateWindowMsg(wnd);
break;
case DFM_INITIATE_DIALOG:
ReadHelp(wnd);
break;
case DFM_COMMAND:
if (p2 != 0)
break;
if (CommandMsg(wnd, p1))
return TRUE;
break;
case DFM_KEYBOARD:
if (DfWindowMoving)
break;
if (KeyboardMsg(wnd, p1))
return TRUE;
break;
case DFM_CLOSE_WINDOW:
if (db != NULL) {
if (db->dwnd.title != NULL) {
free(db->dwnd.title);
db->dwnd.title = NULL;
}
}
FindHelpWindow(wnd);
if (ThisHelp != NULL)
ThisHelp->hwnd = NULL;
Helping = FALSE;
break;
default:
break;
}
return DfBaseWndProc(DF_HELPBOX, wnd, msg, p1, p2);
}
/* ----- select a new help window from its name ----- */
static void SelectHelp(DFWINDOW wnd, char *hname)
{
if (hname != NULL) {
DFWINDOW pwnd = DfGetParent(wnd);
DfPostMessage(wnd, DFM_ENDDIALOG, 0, 0);
DfPostMessage(pwnd, DFM_DISPLAY_HELP, (DF_PARAM) hname, 0);
}
}
/* ---- DFM_PAINT message for the helpbox text editbox ---- */
static int PaintMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
struct keywords *thisword;
int rtn;
if (wnd->thisword != NULL) {
DFWINDOW pwnd = DfGetParent(wnd);
char *cp;
thisword = wnd->thisword;
cp = DfTextLine(wnd, thisword->lineno);
cp += thisword->off1;
*(cp+1) =
(pwnd->WindowColors[DF_SELECT_COLOR][DF_FG] & 255) | 0x80;
*(cp+2) =
(pwnd->WindowColors[DF_SELECT_COLOR][DF_BG] & 255) | 0x80;
rtn = DfDefaultWndProc(wnd, DFM_PAINT, p1, p2);
*(cp+1) =
(pwnd->WindowColors[DF_HILITE_COLOR][DF_FG] & 255) | 0x80;
*(cp+2) =
(pwnd->WindowColors[DF_HILITE_COLOR][DF_BG] & 255) | 0x80;
return rtn;
}
return DfDefaultWndProc(wnd, DFM_PAINT, p1, p2);
}
/* ---- DFM_LEFT_BUTTON message for the helpbox text editbox ---- */
static int LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
struct keywords *thisword;
int rtn, mx, my;
rtn = DfDefaultWndProc(wnd, DFM_LEFT_BUTTON, p1, p2);
mx = (int)p1 - DfGetClientLeft(wnd);
my = (int)p2 - DfGetClientTop(wnd);
my += wnd->wtop;
thisword = wnd->firstword;
while (thisword != NULL) {
if (my == thisword->lineno) {
if (mx >= thisword->off2 &&
mx < thisword->off3) {
wnd->thisword = thisword;
DfSendMessage(wnd, DFM_PAINT, 0, 0);
if (thisword->isDefinition) {
DFWINDOW pwnd = DfGetParent(wnd);
if (pwnd != NULL)
DisplayDefinition(DfGetParent(pwnd),
thisword->hname);
}
break;
}
}
thisword = thisword->nextword;
}
return rtn;
}
/* --- window processing module for DF_HELPBOX's text DF_EDITBOX -- */
int HelpTextProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
{
struct keywords *thisword;
switch (msg) {
case DFM_PAINT:
return PaintMsg(wnd, p1, p2);
case DFM_LEFT_BUTTON:
return LeftButtonMsg(wnd, p1, p2);
case DOUBLE_CLICK:
DfPostMessage(wnd, DFM_KEYBOARD, '\r', 0);
break;
case DFM_CLOSE_WINDOW:
thisword = wnd->firstword;
while (thisword != NULL) {
struct keywords *nextword = thisword->nextword;
if (thisword->hname != NULL)
free(thisword->hname);
free(thisword);
thisword = nextword;
}
break;
default:
break;
}
return DfDefaultWndProc(wnd, msg, p1, p2);
}
/* -------- read the help text into the editbox ------- */
static void ReadHelp(DFWINDOW wnd)
{
DFWINDOW cwnd = DfControlWindow(wnd->extension, DF_ID_HELPTEXT);
int linectr = 0;
if (cwnd == NULL)
return;
cwnd->wndproc = HelpTextProc;
/* ----- read the help text ------- */
while (TRUE) {
char *cp = hline, *cp1;
int colorct = 0;
if (DfGetHelpLine(hline) == NULL)
break;
if (*hline == '<')
break;
hline[strlen(hline)-1] = '\0';
/* --- add help text to the help window --- */
while (cp != NULL) {
if ((cp = strchr(cp, '[')) != NULL) {
/* ----- hit a new key word ----- */
struct keywords *thisword;
if (*(cp+1) != '.' && *(cp+1) != '*') {
cp++;
continue;
}
thisword = DfCalloc(1, sizeof(struct keywords));
if (cwnd->firstword == NULL)
cwnd->firstword = thisword;
if (cwnd->lastword != NULL) {
((struct keywords *)
(cwnd->lastword))->nextword = thisword;
thisword->prevword = cwnd->lastword;
}
cwnd->lastword = thisword;
thisword->lineno = cwnd->wlines;
thisword->off1 = (int) ((int)cp - (int)hline);
thisword->off2 = thisword->off1 - colorct * 4;
thisword->isDefinition = *(cp+1) == '*';
colorct++;
*cp++ = DF_CHANGECOLOR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -