📄 helpsys.c
字号:
/******************************************************************
* SEAL 2.0 *
* Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved. *
* *
* Web site: http://sealsystem.sourceforge.net/ *
* E-mail (current maintainer): orudge@users.sourceforge.net *
******************************************************************/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Revision History:
*
* DATE CHANGE VERSION
* 06/11/2001 Added <FONT> tag (orudge) 0.31
*/
#include <seal.h>
#include <iodlg.h>
#include <helpsys.h>
#include <registry.h>
GrFont *old_font;
l_color flat;
l_color text;
l_color face3d;
l_color light3d;
l_color shadow3d;
l_color dark3d;
l_color _link;
p_helpbox (*helpbox_init)(p_helpbox o, t_rect r)=&_helpbox_init;
typedef struct t_topic
{
char name[51];
int pos, size;
} t_topic;
typedef struct t_bitmap_info
{
char name[13];
int width, height, bpp;
int pos;
} t_bitmap_info;
typedef struct t_head
{
char ID[5];
int version;
int topics;
int bitmaps;
} t_head;
static p_list get_file_items()
{
p_list p = list_init(malloc(sizeof(t_list)), &free_filehistory_item, 0);
if (p) {
p->insert(p, new_filehistory_item("Help files (*.hlp)", "*.hlp"));
p->insert(p, new_filehistory_item("All files (*.*)", "*.*"));
};
return p;
}
#ifndef Bad_Seal
void draw_bevel(BITMAP *out, int x1, int y1, int x2, int y2, int c1, int c2)
{
if (out) {
line(out, x1, y1, x2, y1, c1);
line(out, x1, y1, x1, y2, c1);
line(out, x2, y1, x2, y2, c2);
line(out, x1, y2, x2, y2, c2);
}
}
#else
void draw_bevel(BITMAP *out, int x1, int y1, int x2, int y2, int c1, int c2);
/* this function is exported from Bad Controls */
#endif
/* begin of draw_string */
#define draw_string \
s[sc] = 0; \
xx = x+FONT_GETSTRWIDTH(VIEW(o)->font, s, -1); \
if (xx >= mx-5) { \
xx = 5+FONT_GETSTRWIDTH(VIEW(o)->font, s, -1); \
if (o->u_link) o->link[o->links].x2 = x; \
x = 5; \
y += FONT_GETHEIGHT(VIEW(o)->font); \
if (o->u_link) { \
o->links++; \
o->link[o->links].where = strdup(o->link[o->links-1].where); \
o->link[o->links].target = strdup(o->link[o->links-1].target); \
o->link[o->links].x1 = 5; \
o->link[o->links].y1 = y; \
o->link[o->links].x2 = 6; \
o->link[o->links].y2 = y+FONT_GETHEIGHT(VIEW(o)->font); \
}; \
}; \
if (y > 0) { \
l_int align = TX_ALIGN_LEFT; \
l_color color = text; \
if (o->u_link) { \
align |= TX_UNDERLINE; \
color = _link; \
}; \
textout_draw(d, VIEW(o)->font, s, -1, x, y, align, color, -2 /*was TX_NOCOLOR*/); \
if (o->u_bold) \
textout_draw_rect(d, VIEW(o)->font, s, -1, x+1, y, x+1, y, align, color, -2, FALSE); \
}; \
x = xx; if (o->u_bold) x++;\
s[0] = 0; \
sc = 0;
/* end of draw_string */
#define free_links(o) { \
int i; \
for (i=0;i<o->links;i++) { \
if (o->link[i].where) afree(&o->link[i].where); \
if (o->link[i].target) afree(&o->link[i].target); \
}; \
o->links = 0; \
}
p_helpbox base_helpbox(p_helpbox o)
{
if (!o->f_in_split) return o;
do {
o = HELPBOX(OBJECT(o)->owner);
} while (o->f_in_split);
return o;
}
p_helpbox get_split(p_helpbox o, l_text name)
{
__p_hbsplit p;
p_helpbox fo = o;
if (!o->f_in_split) return o;
o = base_helpbox(o);
p = o->splits;
do {
if (!stricmp(p->name, name)) return p->split;
p = p->next;
} while (p);
return fo;
}
void helpbox_parse_cmd(p_helpbox o, BITMAP *d, t_rect r, t_point p, l_text s, l_int *scp, l_text cmd)
{
l_int i, x = o->f_x, y = o->f_y, mx = o->f_mx, my = o->f_my, sc = *scp;
l_char par[16][256];
l_int pars = 0;
l_int argc = 0;
l_bool u_str = FALSE;
for (i=0;i<16;i++) par[i][0] = 0;
for (i=0;i<strlen(cmd);i++) {
switch (cmd[i]) {
case ' ': if (!u_str) {
if (argc > 0) {
par[pars][argc] = 0;
pars++;
argc = 0;
};
} else {
par[pars][argc] = cmd[i];
argc++;
}; break;
case '"': {
u_str = !u_str;
}; break;
default: {
par[pars][argc] = cmd[i];
argc++;
}; break;
};
};
if (argc > 0) par[pars][argc] = 0;
if (!stricmp(par[0], "BR")) {
l_int xx;
draw_string;
if (o->u_link) o->link[o->links].x2 = x;
x = 5;
y += FONT_GETHEIGHT(VIEW(o)->font);
if (o->u_link) {
o->links++;
o->link[o->links].where = strdup(o->link[o->links-1].where);
o->link[o->links].target = strdup(o->link[o->links-1].target);
o->link[o->links].x1 = 5;
o->link[o->links].y1 = y;
o->link[o->links].x2 = 6; /* will changed by <LE> */
o->link[o->links].y2 = y+FONT_GETHEIGHT(VIEW(o)->font);
};
};
if (!stricmp(par[0], "L")) {
l_int xx;
draw_string;
if (!o->u_link) o->links++;
if (pars) o->link[o->links].where = strdup(par[1]);
if (pars > 1) {
if (o->f_in_split)
o->link[o->links].target = strdup(par[2]);
else
o->link[o->links].target = NULL;
} else o->link[o->links].target = NULL;
o->link[o->links].x1 = x;
o->link[o->links].y1 = y;
o->link[o->links].x2 = x+1; /* will changed by <LE> */
o->link[o->links].y2 = y+FONT_GETHEIGHT(VIEW(o)->font);
o->u_link = TRUE;
};
if (!stricmp(par[0], "LE") && o->u_link) {
l_int xx;
draw_string;
o->link[o->links].x2 = x;
if (pars) o->link[o->links].name = strdup(par[1]); else o->link[o->links].name = NULL;
o->u_link = FALSE;
};
if (!stricmp(par[0], "B")) {
l_int xx;
draw_string;
o->u_bold = TRUE;
};
if (!stricmp(par[0], "/B")) {
l_int xx;
draw_string;
o->u_bold = FALSE;
};
if (!stricmp(par[0], "HL")) {
l_int xx;
draw_string;
if (o->u_link) o->link[o->links].x2 = x;
x = 5;
y += FONT_GETHEIGHT(VIEW(o)->font);
hline(d, 4, y+4, mx-5, COLOR(0));
hline(d, 4, y+5, mx-5, COLOR(0));
y += 11;
if (o->u_link) {
o->links++;
o->link[o->links].where = strdup(o->link[o->links-1].where);
o->link[o->links].target = strdup(o->link[o->links-1].target);
o->link[o->links].x1 = 5;
o->link[o->links].y1 = y;
o->link[o->links].x2 = 6; /* will changed by <LE> */
o->link[o->links].y2 = y+FONT_GETHEIGHT(VIEW(o)->font);
};
};
if (!stricmp(par[0], "BACKGROUND")) {
if (o->background) free(o->background);
o->background = strdup(par[1]);
if (pars > 1 && !stricmp(par[2], "WATERMARK")) o->flags |= HBF_WATERMARK;
};
if (!stricmp(par[0], "IMAGE")) {
l_int xx;
BITMAP *bmp;
draw_string;
if (par[1]) bmp = o->get_bitmap(o, par[1]); else bmp = NULL;
if (bmp) {
draw_sprite(d, bmp, x, y);
x += bmp->w;
if (o->u_link)
o->link[o->links].y2 = y+bmp->h;
if (!(pars > 1 && !stricmp(par[2], "STAY"))) y += bmp->h-FONT_GETHEIGHT(VIEW(o)->font);
};
};
if (!stricmp(par[0], "SPLIT")) {
p_helpbox s1, s2, base;
l_int splitx = atoi(par[1]);
o->f_split = TRUE;
if (o->f_in_split)
s1 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(0, 0, splitx, rect_sizey(VIEW(o)->bounds)));
else
s1 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(2, 2, splitx, rect_sizey(VIEW(o)->bounds)-2));
s1->f_in_split = TRUE;
VIEW(s1)->align |= TX_ALIGN_BOTTOM;
OBJECT(o)->insert(OBJECT(o), OBJECT(s1));
if (o->f_in_split)
s2 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(splitx+1, 0, rect_sizex(VIEW(o)->bounds), rect_sizey(VIEW(o)->bounds)));
else
s2 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(splitx+1, 2, rect_sizex(VIEW(o)->bounds)-2, rect_sizey(VIEW(o)->bounds)-2));
s2->f_in_split = TRUE;
VIEW(s2)->align |= TX_ALIGN_BOTTOM+TX_ALIGN_RIGHT;
OBJECT(o)->insert(OBJECT(o), OBJECT(s2));
s1->filename = strdup(o->filename);
s2->filename = strdup(o->filename);
helpbox_navigate(s1, par[2]);
helpbox_navigate(s2, par[3]);
OBJECT(s2)->select(OBJECT(s2));
base = base_helpbox(o);
base->active_split = s2;
#define add_split(asplit, aname) { \
p_helpbox bo = base_helpbox(o); \
__p_hbsplit s = bo->splits; \
if (!s) { \
s = (__p_hbsplit) malloc(sizeof(__t_hbsplit)); \
strcpy(s->name, aname); \
s->split = asplit; \
s->prev = NULL; \
s->next = NULL; \
bo->splits = s; \
} else { \
if (s->next) do { \
s = s->next; \
} while (s->next); \
s->next = (__p_hbsplit) malloc(sizeof(__t_hbsplit)); \
strcpy(s->next->name, aname); \
s->next->split = asplit; \
s->next->prev = s; \
s->next->next = NULL; \
}; \
}
add_split(s1, par[2]);
add_split(s2, par[3]);
};
if (!stricmp(par[0], "VSPLIT")) {
p_helpbox s1, s2, base;
l_int splity = atoi(par[1]);
o->f_split = TRUE;
if (o->f_in_split)
s1 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(0, 0, rect_sizex(VIEW(o)->bounds), splity));
else
s1 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(2, 2, rect_sizex(VIEW(o)->bounds)-2, splity));
s1->f_in_split = TRUE;
VIEW(s1)->align |= TX_ALIGN_RIGHT;
OBJECT(o)->insert(OBJECT(o), OBJECT(s1));
if (o->f_in_split)
s2 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(0, splity+1, rect_sizex(VIEW(o)->bounds), rect_sizey(VIEW(o)->bounds)));
else
s2 = helpbox_init(malloc(sizeof(t_helpbox)), rect_assign(2, splity+1, rect_sizex(VIEW(o)->bounds)-2, rect_sizey(VIEW(o)->bounds)-2));
s2->f_in_split = TRUE;
VIEW(s2)->align |= TX_ALIGN_BOTTOM+TX_ALIGN_RIGHT;
OBJECT(o)->insert(OBJECT(o), OBJECT(s2));
s1->filename = strdup(o->filename);
s2->filename = strdup(o->filename);
helpbox_navigate(s1, par[2]);
helpbox_navigate(s2, par[3]);
OBJECT(s2)->select(OBJECT(s2));
base = base_helpbox(o);
base->active_split = s2;
add_split(s1, par[2]);
add_split(s2, par[3]);
};
if (!stricmp(par[0], "STATIC")) {
o->flags |= HBF_UNSELECTABLE+HBF_NOSCROLL;
};
if (!stricmp(par[0], "SCRIPT")) {
if (!o->_script) {
o->_script = (l_text) malloc(1);
o->_script[0] = 0;
o->flags |= HBF_RESERVED1;
};
};
if (!stricmp(par[0], "BUTTON")) {
o->request(o, HBREQ_BUTTON, par[1], NULL, NULL);
};
if (!stricmp(par[0], "FONT")) {
old_font = VIEW(o)->font;
VIEW(o)->font = get_font_in_size(par[1], atoi(par[2]), atoi(par[2]));
}
if (!stricmp(par[0], "/FONT")) {
VIEW(o)->font = old_font;
}
o->f_x = x;
o->f_y = y;
*scp = sc;
}
void helpbox_draw_text(p_helpbox o, BITMAP *out, t_rect r, t_point p)
{
l_int i, x = 5, y = 5-o->f_prg;
BITMAP *d = create_bitmap(rect_sizex(r)-3, rect_sizey(r)-3);
l_int mx = rect_sizex(r)-3, my = rect_sizey(r)-3;
l_char s[1024];
l_char cmd[1024];
l_int sc = 0, cmdc = 0;
l_bool u_tag = FALSE;
l_bool u_str = FALSE;
o->f_mx = mx;
o->f_my = my;
if (!o->background) {
rectfill(d, 0, 0, mx, my, flat);
} else {
int x = 0, y, w = d->w, h = d->h;
BITMAP *bmp = o->get_bitmap(o, o->background);
if (o->flags & HBF_WATERMARK)
y = 0;
else
y = -(o->f_prg % h);
do {
blit(bmp, d, 0, 0, x, y, w, h);
x += bmp->w;
if (x >= w) {
x = 0;
y += bmp->h;
};
} while (y < h);
};
s[0]=0;
o->links = -1;
for (i=0;i<strlen(o->text);i++) {
switch (o->text[i]) {
case '\n': break;
case ' ': if (!u_tag) {
l_int xx;
s[sc] = 32;
sc++;
draw_string;
} else {
cmd[cmdc] = o->text[i];
cmdc++;
}; break;
case '<': if (!u_str && o->text[i+1] != '<') {
u_tag = TRUE;
cmd[0] = 0;
cmdc = 0;
} else {
if (o->text[i+1] == '<' && !u_str) i++;
if (u_tag) {
cmd[cmdc] = o->text[i];
cmdc++;
} else {
s[sc] = o->text[i];
sc++;
};
}; break;
case '>': if (!u_str && u_tag) {
u_tag = FALSE;
cmd[cmdc] = 0;
o->f_x = x;
o->f_y = y;
if (cmdc != 0) helpbox_parse_cmd(o, d, r, p, s, &sc, cmd);
x = o->f_x;
y = o->f_y;
} else {
if (u_tag) {
cmd[cmdc] = o->text[i];
cmdc++;
} else {
s[sc] = o->text[i];
sc++;
};
}; break;
case '"': if (u_tag) {
u_str = !u_str;
s[sc] = '"';
sc++;
} else {
s[sc] = '"';
sc++;
}; break;
default: {
if (u_tag) {
cmd[cmdc] = o->text[i];
cmdc++;
} else {
s[sc] = o->text[i];
sc++;
};
} break;
};
if (y > my && o->f_maxy > 0) break;
};
if (sc != 0) {
l_int xx;
draw_string;
};
if (o->f_maxy == 0) {
o->f_maxy = y;
};
blit(d, out, 0, 0, r.a.x+p.x+2, r.a.y+p.y+2, mx, my);
destroy_bitmap(d);
}
void helpbox_draw(p_view o)
{
t_rect r = VIEW(o)->get_local_extent(VIEW(o));
t_point p;
BITMAP *out;
out = VIEW(o)->begin_paint(VIEW(o), &p, r);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -