mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +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;
|
||||
pbool typedefed;
|
||||
char *name;
|
||||
char *aname;
|
||||
} QCC_type_t;
|
||||
int typecmp(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;
|
||||
char *name;
|
||||
char *comment; //ui info
|
||||
struct QCC_def_s *next;
|
||||
struct QCC_def_s *nextlocal; //provides a chain of local variables for the opt_locals_marshalling optimisation.
|
||||
gofs_t ofs;
|
||||
|
|
|
@ -9928,10 +9928,10 @@ void QCC_PR_ParseDefs (char *classname)
|
|||
} while (QCC_PR_CheckToken (","));
|
||||
|
||||
if (type->type == ev_function)
|
||||
QCC_PR_CheckToken (";");
|
||||
QCC_PR_CheckTokenComment (";", &def->comment);
|
||||
else
|
||||
{
|
||||
if (!QCC_PR_CheckToken (";"))
|
||||
if (!QCC_PR_CheckTokenComment (";", &def->comment))
|
||||
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "Missing semicolon at end of definition");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3008,7 +3008,121 @@ void QCC_PR_Expect (char *string)
|
|||
}
|
||||
#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
|
||||
|
@ -3274,6 +3388,11 @@ char *TypeName(QCC_type_t *type)
|
|||
args--;
|
||||
|
||||
strcat(ret, type->name);
|
||||
if (type->aname)
|
||||
{
|
||||
strcat(ret, " ");
|
||||
strcat(ret, type->aname);
|
||||
}
|
||||
type = type->next;
|
||||
|
||||
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, ")"))
|
||||
{
|
||||
newtype = true;
|
||||
name = QCC_PR_ParseName ();
|
||||
nptype->aname = qccHunkAlloc(strlen(name)+1);
|
||||
strcpy(nptype->aname, name);
|
||||
if (definenames)
|
||||
strcpy (pr_parm_names[numparms], name);
|
||||
}
|
||||
|
|
|
@ -280,6 +280,8 @@ typedef struct editor_s {
|
|||
char filename[MAX_PATH]; //abs
|
||||
HWND window;
|
||||
HWND editpane;
|
||||
HWND tooltip;
|
||||
char tooltiptext[1024];
|
||||
pbool modified;
|
||||
time_t filemodifiedtime;
|
||||
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,
|
||||
WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
|
@ -449,25 +524,27 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
goto gdefault;
|
||||
case WM_CREATE:
|
||||
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)
|
||||
{
|
||||
SendMessage(editor->editpane, EM_EXLIMITTEXT, 0, 1<<31);
|
||||
|
||||
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;
|
||||
case WM_SIZE:
|
||||
GetClientRect(hWnd, &rect);
|
||||
|
@ -479,6 +556,38 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
return TRUE;
|
||||
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:
|
||||
if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == editor->editpane)
|
||||
{
|
||||
|
@ -1044,6 +1153,8 @@ void EditFile(char *name, int line)
|
|||
|
||||
int EditorSave(editor_t *edit)
|
||||
{
|
||||
DWORD selstart;
|
||||
char title[2048];
|
||||
struct stat sbuf;
|
||||
int len;
|
||||
char *file;
|
||||
|
@ -1067,6 +1178,11 @@ int EditorSave(editor_t *edit)
|
|||
stat(edit->filename, &sbuf);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
ShowWindow(gotodefbox, SW_SHOW);
|
||||
|
||||
gotodefaccept = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "GO",
|
||||
gotodefaccept = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Def",
|
||||
WS_CHILD | WS_CLIPCHILDREN | BS_DEFPUSHBUTTON,
|
||||
0, 0, 320, 200, hWnd, (HMENU) 0x4404, ghInstance, (LPSTR) NULL);
|
||||
ShowWindow(gotodefaccept, SW_SHOW);
|
||||
|
|
|
@ -3419,9 +3419,19 @@ void QCC_ContinueCompile(void)
|
|||
QCC_FinishCompile();
|
||||
|
||||
PostCompile();
|
||||
if (!PreCompile())
|
||||
return;
|
||||
QCC_main(myargc, myargv);
|
||||
|
||||
if (currentsourcefile < numsourcefiles)
|
||||
{
|
||||
if (!PreCompile())
|
||||
return;
|
||||
QCC_main(myargc, myargv);
|
||||
}
|
||||
else
|
||||
{
|
||||
qcc_compileactive = false;
|
||||
numsourcefiles = 0;
|
||||
currentsourcefile = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
s = qcc_token;
|
||||
|
|
Loading…
Reference in a new issue