mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-02-01 13:10:47 +00:00
------------------------------------------------------------------------
r4239 | acceptthis | 2013-03-08 02:41:00 +0000 (Fri, 08 Mar 2013) | 2 lines Give the text edit input focus when alt-tabbing. Display tooltips on mouseover for the various defs. You need to compile first for them to show. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4235 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
197bb250dd
commit
0543a97976
5 changed files with 270 additions and 20 deletions
|
@ -310,6 +310,7 @@ typedef struct QCC_type_s
|
||||||
unsigned int arraysize;
|
unsigned int arraysize;
|
||||||
pbool typedefed;
|
pbool typedefed;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *aname;
|
||||||
} QCC_type_t;
|
} QCC_type_t;
|
||||||
int typecmp(QCC_type_t *a, QCC_type_t *b);
|
int typecmp(QCC_type_t *a, QCC_type_t *b);
|
||||||
int typecmp_lax(QCC_type_t *a, QCC_type_t *b);
|
int typecmp_lax(QCC_type_t *a, QCC_type_t *b);
|
||||||
|
@ -331,6 +332,7 @@ typedef struct QCC_def_s
|
||||||
{
|
{
|
||||||
QCC_type_t *type;
|
QCC_type_t *type;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *comment; //ui info
|
||||||
struct QCC_def_s *next;
|
struct QCC_def_s *next;
|
||||||
struct QCC_def_s *nextlocal; //provides a chain of local variables for the opt_locals_marshalling optimisation.
|
struct QCC_def_s *nextlocal; //provides a chain of local variables for the opt_locals_marshalling optimisation.
|
||||||
gofs_t ofs;
|
gofs_t ofs;
|
||||||
|
|
|
@ -9928,10 +9928,10 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
} while (QCC_PR_CheckToken (","));
|
} while (QCC_PR_CheckToken (","));
|
||||||
|
|
||||||
if (type->type == ev_function)
|
if (type->type == ev_function)
|
||||||
QCC_PR_CheckToken (";");
|
QCC_PR_CheckTokenComment (";", &def->comment);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!QCC_PR_CheckToken (";"))
|
if (!QCC_PR_CheckTokenComment (";", &def->comment))
|
||||||
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "Missing semicolon at end of definition");
|
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "Missing semicolon at end of definition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3008,7 +3008,121 @@ void QCC_PR_Expect (char *string)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pbool QCC_PR_CheckTokenComment(char *string, char **comment)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
char *start;
|
||||||
|
int nl;
|
||||||
|
char *old;
|
||||||
|
int oldlen;
|
||||||
|
pbool replace = true;
|
||||||
|
pbool nextcomment = true;
|
||||||
|
|
||||||
|
if (pr_token_type != tt_punct)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (STRCMP (string, pr_token))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (comment)
|
||||||
|
{
|
||||||
|
// skip whitespace
|
||||||
|
nl = false;
|
||||||
|
while(nextcomment)
|
||||||
|
{
|
||||||
|
nextcomment = false;
|
||||||
|
|
||||||
|
while ((c = *pr_file_p) && qcc_iswhite(c))
|
||||||
|
{
|
||||||
|
if (c=='\n') //allow new lines, but only if there's whitespace before any tokens, and no double newlines.
|
||||||
|
{
|
||||||
|
if (nl)
|
||||||
|
{
|
||||||
|
QCC_PR_NewLine(false);
|
||||||
|
pr_file_p++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nl = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pr_file_p++;
|
||||||
|
nl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nl)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// parse // comments
|
||||||
|
if (c=='/' && pr_file_p[1] == '/')
|
||||||
|
{
|
||||||
|
pr_file_p += 2;
|
||||||
|
while (*pr_file_p == ' ' || *pr_file_p == '\t')
|
||||||
|
pr_file_p++;
|
||||||
|
start = pr_file_p;
|
||||||
|
while (*pr_file_p && *pr_file_p != '\n')
|
||||||
|
pr_file_p++;
|
||||||
|
|
||||||
|
if (*pr_file_p == '\n')
|
||||||
|
{
|
||||||
|
QCC_PR_NewLine(true);
|
||||||
|
pr_file_p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = replace?NULL:*comment;
|
||||||
|
replace = false;
|
||||||
|
oldlen = old?strlen(old)+1:0;
|
||||||
|
*comment = qccHunkAlloc(oldlen + (pr_file_p-start)+1);
|
||||||
|
if (oldlen)
|
||||||
|
{
|
||||||
|
memcpy(*comment, old, oldlen-1);
|
||||||
|
memcpy(*comment+oldlen-1, "\n", 1);
|
||||||
|
}
|
||||||
|
memcpy(*comment + oldlen, start, pr_file_p - start);
|
||||||
|
oldlen = oldlen+pr_file_p - start;
|
||||||
|
while(oldlen > 0 && ((*comment)[oldlen-1] == '\r' || (*comment)[oldlen-1] == '\n' || (*comment)[oldlen-1] == '\t' || (*comment)[oldlen-1] == ' '))
|
||||||
|
oldlen--;
|
||||||
|
(*comment)[oldlen] = 0;
|
||||||
|
nextcomment = true; //include the next // too
|
||||||
|
nl = true;
|
||||||
|
}
|
||||||
|
// parse /* comments
|
||||||
|
else if (c=='/' && pr_file_p[1] == '*' && replace)
|
||||||
|
{
|
||||||
|
pr_file_p+=2;
|
||||||
|
start = pr_file_p;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (pr_file_p[0]=='\n')
|
||||||
|
QCC_PR_NewLine(true);
|
||||||
|
if (pr_file_p[1] == 0)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseError(0, "EOF inside comment\n");
|
||||||
|
pr_file_p++;
|
||||||
|
pr_file_p-=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr_file_p++;
|
||||||
|
} while (pr_file_p[0] != '*' || pr_file_p[1] != '/');
|
||||||
|
|
||||||
|
old = replace?NULL:*comment;
|
||||||
|
replace = false;
|
||||||
|
oldlen = old?strlen(old):0;
|
||||||
|
*comment = qccHunkAlloc(oldlen + (pr_file_p-start)+1);
|
||||||
|
memcpy(*comment, old, oldlen);
|
||||||
|
memcpy(*comment + oldlen, start, pr_file_p - start);
|
||||||
|
(*comment)[oldlen+pr_file_p - start] = 0;
|
||||||
|
|
||||||
|
pr_file_p+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//and then do the rest properly.
|
||||||
|
QCC_PR_Lex ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
PR_Check
|
PR_Check
|
||||||
|
@ -3274,6 +3388,11 @@ char *TypeName(QCC_type_t *type)
|
||||||
args--;
|
args--;
|
||||||
|
|
||||||
strcat(ret, type->name);
|
strcat(ret, type->name);
|
||||||
|
if (type->aname)
|
||||||
|
{
|
||||||
|
strcat(ret, " ");
|
||||||
|
strcat(ret, type->aname);
|
||||||
|
}
|
||||||
type = type->next;
|
type = type->next;
|
||||||
|
|
||||||
if (type || varg)
|
if (type || varg)
|
||||||
|
@ -3472,7 +3591,10 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
||||||
|
|
||||||
if (STRCMP(pr_token, ",") && STRCMP(pr_token, ")"))
|
if (STRCMP(pr_token, ",") && STRCMP(pr_token, ")"))
|
||||||
{
|
{
|
||||||
|
newtype = true;
|
||||||
name = QCC_PR_ParseName ();
|
name = QCC_PR_ParseName ();
|
||||||
|
nptype->aname = qccHunkAlloc(strlen(name)+1);
|
||||||
|
strcpy(nptype->aname, name);
|
||||||
if (definenames)
|
if (definenames)
|
||||||
strcpy (pr_parm_names[numparms], name);
|
strcpy (pr_parm_names[numparms], name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,6 +280,8 @@ typedef struct editor_s {
|
||||||
char filename[MAX_PATH]; //abs
|
char filename[MAX_PATH]; //abs
|
||||||
HWND window;
|
HWND window;
|
||||||
HWND editpane;
|
HWND editpane;
|
||||||
|
HWND tooltip;
|
||||||
|
char tooltiptext[1024];
|
||||||
pbool modified;
|
pbool modified;
|
||||||
time_t filemodifiedtime;
|
time_t filemodifiedtime;
|
||||||
struct editor_s *next;
|
struct editor_s *next;
|
||||||
|
@ -389,6 +391,79 @@ void EditorMenu(editor_t *editor, WPARAM wParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *WordUnderCursor(editor_t *editor, char *buffer, int buffersize)
|
||||||
|
{
|
||||||
|
unsigned char linebuf[1024];
|
||||||
|
DWORD charidx;
|
||||||
|
DWORD lineidx;
|
||||||
|
POINT pos;
|
||||||
|
RECT rect;
|
||||||
|
GetCursorPos(&pos);
|
||||||
|
GetWindowRect(editor->editpane, &rect);
|
||||||
|
pos.x -= rect.left;
|
||||||
|
pos.y -= rect.top;
|
||||||
|
charidx = SendMessage(editor->editpane, EM_CHARFROMPOS, 0, (LPARAM)&pos);
|
||||||
|
lineidx = SendMessage(editor->editpane, EM_LINEFROMCHAR, charidx, 0);
|
||||||
|
charidx -= SendMessage(editor->editpane, EM_LINEINDEX, lineidx, 0);
|
||||||
|
|
||||||
|
Edit_GetLine(editor->editpane, lineidx, linebuf, sizeof(linebuf));
|
||||||
|
|
||||||
|
//skip back to the start of the word
|
||||||
|
while(charidx > 0 && (
|
||||||
|
(linebuf[charidx-1] >= 'a' && linebuf[charidx-1] <= 'z') ||
|
||||||
|
(linebuf[charidx-1] >= 'A' && linebuf[charidx-1] <= 'Z') ||
|
||||||
|
(linebuf[charidx-1] >= '0' && linebuf[charidx-1] <= '9') ||
|
||||||
|
linebuf[charidx-1] == '_' ||
|
||||||
|
linebuf[charidx-1] >= 128
|
||||||
|
))
|
||||||
|
{
|
||||||
|
charidx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the result out
|
||||||
|
lineidx = 0;
|
||||||
|
buffersize--;
|
||||||
|
while (buffersize &&
|
||||||
|
(linebuf[charidx] >= 'a' && linebuf[charidx] <= 'z') ||
|
||||||
|
(linebuf[charidx] >= 'A' && linebuf[charidx] <= 'Z') ||
|
||||||
|
(linebuf[charidx] >= '0' && linebuf[charidx] <= '9') ||
|
||||||
|
linebuf[charidx] == '_' ||
|
||||||
|
linebuf[charidx] >= 128
|
||||||
|
)
|
||||||
|
{
|
||||||
|
buffer[lineidx++] = linebuf[charidx++];
|
||||||
|
buffersize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[lineidx++] = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
char *GetTooltipText(editor_t *editor)
|
||||||
|
{
|
||||||
|
char wordbuf[256];
|
||||||
|
char *defname;
|
||||||
|
defname = WordUnderCursor(editor, wordbuf, sizeof(wordbuf));
|
||||||
|
if (!*defname)
|
||||||
|
return NULL;
|
||||||
|
else if (globalstable.numbuckets)
|
||||||
|
{
|
||||||
|
QCC_def_t *def;
|
||||||
|
def = QCC_PR_GetDef(NULL, defname, NULL, false, 0, false);
|
||||||
|
if (def)
|
||||||
|
{
|
||||||
|
static char buffer[1024];
|
||||||
|
//note function argument names do not persist beyond the function def. we might be able to read the function's localdefs for them, but that's unreliable/broken with builtins where they're most needed.
|
||||||
|
if (def->comment)
|
||||||
|
_snprintf(buffer, sizeof(buffer)-1, "%s %s\r\n%s", TypeName(def->type), def->name, def->comment);
|
||||||
|
else
|
||||||
|
_snprintf(buffer, sizeof(buffer)-1, "%s %s", TypeName(def->type), def->name);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;//"Type info not available. Compile first.";
|
||||||
|
}
|
||||||
static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
||||||
WPARAM wParam,LPARAM lParam)
|
WPARAM wParam,LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -449,25 +524,27 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
||||||
goto gdefault;
|
goto gdefault;
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
editor->editpane = CreateAnEditControl(hWnd);
|
editor->editpane = CreateAnEditControl(hWnd);
|
||||||
/*
|
|
||||||
editor->editpane=CreateWindowEx(WS_EX_CLIENTEDGE,
|
|
||||||
richedit?RICHEDIT_CLASS:"EDIT",
|
|
||||||
"",
|
|
||||||
WS_CHILD | WS_VISIBLE |
|
|
||||||
WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
|
|
||||||
ES_MULTILINE | ES_AUTOVSCROLL,
|
|
||||||
0, 0, 0, 0,
|
|
||||||
hWnd,
|
|
||||||
NULL,
|
|
||||||
ghInstance,
|
|
||||||
NULL);
|
|
||||||
*/
|
|
||||||
if (richedit)
|
if (richedit)
|
||||||
{
|
{
|
||||||
SendMessage(editor->editpane, EM_EXLIMITTEXT, 0, 1<<31);
|
SendMessage(editor->editpane, EM_EXLIMITTEXT, 0, 1<<31);
|
||||||
|
|
||||||
SendMessage(editor->editpane, EM_SETUNDOLIMIT, 256, 256);
|
SendMessage(editor->editpane, EM_SETUNDOLIMIT, 256, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editor->tooltip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_ALWAYSTIP|TTS_NOPREFIX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, ghInstance, NULL);
|
||||||
|
if (editor->tooltip)
|
||||||
|
{
|
||||||
|
TOOLINFO toolInfo = { 0 };
|
||||||
|
toolInfo.cbSize = sizeof(toolInfo);
|
||||||
|
toolInfo.hwnd = hWnd;
|
||||||
|
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRACK | TTF_ABSOLUTE;
|
||||||
|
toolInfo.uId = (UINT_PTR)editor->editpane;
|
||||||
|
toolInfo.lpszText = "";
|
||||||
|
SendMessage(editor->tooltip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
|
||||||
|
SendMessage(editor->tooltip, TTM_SETMAXTIPWIDTH, 0, 500);
|
||||||
|
}
|
||||||
|
goto gdefault;
|
||||||
|
case WM_SETFOCUS:
|
||||||
|
SetFocus(editor->editpane);
|
||||||
goto gdefault;
|
goto gdefault;
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
GetClientRect(hWnd, &rect);
|
GetClientRect(hWnd, &rect);
|
||||||
|
@ -479,6 +556,38 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
||||||
EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
|
case WM_SETCURSOR:
|
||||||
|
{
|
||||||
|
POINT pos;
|
||||||
|
char *newtext;
|
||||||
|
TOOLINFO toolInfo = { 0 };
|
||||||
|
toolInfo.cbSize = sizeof(toolInfo);
|
||||||
|
toolInfo.hwnd = hWnd;
|
||||||
|
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRACK;
|
||||||
|
toolInfo.uId = (UINT_PTR)editor->editpane;
|
||||||
|
newtext = GetTooltipText(editor);
|
||||||
|
toolInfo.lpszText = editor->tooltiptext;
|
||||||
|
if (!newtext)
|
||||||
|
newtext = "";
|
||||||
|
if (strcmp(editor->tooltiptext, newtext))
|
||||||
|
{
|
||||||
|
strncpy(editor->tooltiptext, newtext, sizeof(editor->tooltiptext)-1);
|
||||||
|
SendMessage(editor->tooltip, TTM_UPDATETIPTEXT, (WPARAM)0, (LPARAM)&toolInfo);
|
||||||
|
if (*editor->tooltiptext)
|
||||||
|
SendMessage(editor->tooltip, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&toolInfo);
|
||||||
|
else
|
||||||
|
SendMessage(editor->tooltip, TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&toolInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetCursorPos(&pos);
|
||||||
|
if (pos.x >= 60)
|
||||||
|
pos.x -= 60;
|
||||||
|
else
|
||||||
|
pos.x = 0;
|
||||||
|
pos.y += 30;
|
||||||
|
SendMessage(editor->tooltip, TTM_TRACKPOSITION, (WPARAM)0, MAKELONG(pos.x, pos.y));
|
||||||
|
}
|
||||||
|
goto gdefault;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == editor->editpane)
|
if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == editor->editpane)
|
||||||
{
|
{
|
||||||
|
@ -1044,6 +1153,8 @@ void EditFile(char *name, int line)
|
||||||
|
|
||||||
int EditorSave(editor_t *edit)
|
int EditorSave(editor_t *edit)
|
||||||
{
|
{
|
||||||
|
DWORD selstart;
|
||||||
|
char title[2048];
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
int len;
|
int len;
|
||||||
char *file;
|
char *file;
|
||||||
|
@ -1067,6 +1178,11 @@ int EditorSave(editor_t *edit)
|
||||||
stat(edit->filename, &sbuf);
|
stat(edit->filename, &sbuf);
|
||||||
edit->filemodifiedtime = sbuf.st_mtime;
|
edit->filemodifiedtime = sbuf.st_mtime;
|
||||||
|
|
||||||
|
//remove the * in a silly way.
|
||||||
|
SendMessage(edit->editpane, EM_GETSEL, (WPARAM)&selstart, (LPARAM)0);
|
||||||
|
sprintf(title, "%s:%i - FTEQCC Editor", edit->filename, 1+Edit_LineFromChar(edit->editpane, selstart));
|
||||||
|
SetWindowText(edit->window, title);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void EditorsRun(void)
|
void EditorsRun(void)
|
||||||
|
@ -1650,7 +1766,7 @@ static LONG CALLBACK MainWndProc(HWND hWnd,UINT message,
|
||||||
0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) NULL);
|
0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) NULL);
|
||||||
ShowWindow(gotodefbox, SW_SHOW);
|
ShowWindow(gotodefbox, SW_SHOW);
|
||||||
|
|
||||||
gotodefaccept = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "GO",
|
gotodefaccept = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Def",
|
||||||
WS_CHILD | WS_CLIPCHILDREN | BS_DEFPUSHBUTTON,
|
WS_CHILD | WS_CLIPCHILDREN | BS_DEFPUSHBUTTON,
|
||||||
0, 0, 320, 200, hWnd, (HMENU) 0x4404, ghInstance, (LPSTR) NULL);
|
0, 0, 320, 200, hWnd, (HMENU) 0x4404, ghInstance, (LPSTR) NULL);
|
||||||
ShowWindow(gotodefaccept, SW_SHOW);
|
ShowWindow(gotodefaccept, SW_SHOW);
|
||||||
|
|
|
@ -3419,9 +3419,19 @@ void QCC_ContinueCompile(void)
|
||||||
QCC_FinishCompile();
|
QCC_FinishCompile();
|
||||||
|
|
||||||
PostCompile();
|
PostCompile();
|
||||||
if (!PreCompile())
|
|
||||||
return;
|
if (currentsourcefile < numsourcefiles)
|
||||||
QCC_main(myargc, myargv);
|
{
|
||||||
|
if (!PreCompile())
|
||||||
|
return;
|
||||||
|
QCC_main(myargc, myargv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qcc_compileactive = false;
|
||||||
|
numsourcefiles = 0;
|
||||||
|
currentsourcefile = 0;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s = qcc_token;
|
s = qcc_token;
|
||||||
|
|
Loading…
Reference in a new issue