📄 help.c
字号:
break;
case CHAR_BOLD_OFF:
attrset (HELP_NORMAL_COLOR);
break;
case '\n':
line++;
col = 0;
break;
case '\t':
col = (col/8 + 1) * 8;
break;
case CHAR_MCLOGO:
case CHAR_TEXTONLY_START:
case CHAR_TEXTONLY_END:
break;
case CHAR_XONLY_START:
while (*p && *p != CHAR_NODE_END && *p != CHAR_XONLY_END)
p++;
if (*p == CHAR_NODE_END || !*p)
p--;
break;
default:
if (!painting)
continue;
if (col > HELP_WINDOW_WIDTH-1)
continue;
dlg_move (h, line+2, col+2);
if (acs){
if (c == ' ' || c == '.')
addch (c);
else
#ifndef OS2_NT
#ifndef HAVE_SLANG
addch (acs_map [c]);
#else
SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
#endif
#else
addch (acs2pc (c));
#endif /* OS2_NT */
} else
addch (c);
col++;
break;
}
}
last_shown = p;
end_of_node = line < help_lines;
attrset (HELP_NORMAL_COLOR);
if (selected_item >= last_shown){
if (link_area != NULL){
selected_item = link_area->link_name;
repeat_paint = 1;
}
else
selected_item = NULL;
}
} while (repeat_paint);
/* Position the cursor over a nice link */
if (active_col)
dlg_move (h, active_line, active_col);
}
static int help_event (Gpm_Event *event, Widget *w)
{
Link_Area *current_area;
if (! (event->type & GPM_UP))
return 0;
/* The event is relative to the dialog window, adjust it: */
event->y -= 2;
if (event->buttons & GPM_B_RIGHT){
currentpoint = startpoint = history [history_ptr].page;
selected_item = history [history_ptr].link;
history_ptr--;
if (history_ptr < 0)
history_ptr = HISTORY_SIZE-1;
help_callback (w->parent, 0, DLG_DRAW);
return 0;
}
/* Test whether the mouse click is inside one of the link areas */
current_area = link_area;
while (current_area)
{
/* Test one line link area */
if (event->y == current_area->y1 && event->x >= current_area->x1 &&
event->y == current_area->y2 && event->x <= current_area->x2)
break;
/* Test two line link area */
if (current_area->y1 + 1 == current_area->y2){
/* The first line */
if (event->y == current_area->y1 && event->x >= current_area->x1)
break;
/* The second line */
if (event->y == current_area->y2 && event->x <= current_area->x2)
break;
}
/* Mouse will not work with link areas of more than two lines */
current_area = current_area -> next;
}
/* Test whether a link area was found */
if (current_area){
/* The click was inside a link area -> follow the link */
history_ptr = (history_ptr+1) % HISTORY_SIZE;
history [history_ptr].page = currentpoint;
history [history_ptr].link = current_area->link_name;
currentpoint = startpoint = help_follow_link (currentpoint, current_area->link_name);
selected_item = NULL;
} else{
if (event->y < 0)
move_backward (help_lines - 1);
else if (event->y >= help_lines)
move_forward (help_lines - 1);
else if (event->y < help_lines/2)
move_backward (1);
else
move_forward (1);
}
/* Show the new node */
help_callback (w->parent, 0, DLG_DRAW);
return 0;
}
/* show help */
void help_help_cmd (Dlg_head *h)
{
history_ptr = (history_ptr+1) % HISTORY_SIZE;
history [history_ptr].page = currentpoint;
history [history_ptr].link = selected_item;
currentpoint = startpoint = search_string (data, "[How to use help]") + 1;
selected_item = NULL;
#ifndef HAVE_XVIEW
help_callback (h, 0, DLG_DRAW);
#endif
}
void help_index_cmd (Dlg_head *h)
{
char *new_item;
history_ptr = (history_ptr+1) % HISTORY_SIZE;
history [history_ptr].page = currentpoint;
history [history_ptr].link = selected_item;
currentpoint = startpoint = search_string (data, "[Help]") + 1;
if (!(new_item = search_string (data, "[Contents]")))
message (1, MSG_ERROR, _(" Can't find node [Contents] in help file "));
else
currentpoint = startpoint = new_item + 1;
selected_item = NULL;
#ifndef HAVE_XVIEW
help_callback (h, 0, DLG_DRAW);
#endif
}
static void quit_cmd (void *x)
{
Dlg_head *h = (Dlg_head *) x;
dlg_stop (x);
}
static void prev_node_cmd (Dlg_head *h)
{
currentpoint = startpoint = history [history_ptr].page;
selected_item = history [history_ptr].link;
history_ptr--;
if (history_ptr < 0)
history_ptr = HISTORY_SIZE-1;
#ifndef HAVE_XVIEW
help_callback (h, 0, DLG_DRAW);
#endif
}
static int md_callback (Dlg_head *h, Widget *w, int msg, int par)
{
return default_proc (h, msg, par);
}
static Widget *mousedispatch_new (int y, int x, int yl, int xl)
{
Widget *w = xmalloc (sizeof (Widget), "disp_new");
init_widget (w, y, x, yl, xl,
(callback_fn) md_callback, 0, (mouse_h) help_event, NULL);
return w;
}
static int help_handle_key (struct Dlg_head *h, int c)
{
char *new_item;
if (c != KEY_UP && c != KEY_DOWN &&
check_movement_keys (c, 1, help_lines, currentpoint,
(movefn) move_backward2,
(movefn) move_forward2,
(movefn) move_to_top,
(movefn) move_to_bottom))
/* Nothing */;
else switch (c){
case 'l':
case KEY_LEFT:
prev_node_cmd (h);
break;
case '\n':
case KEY_RIGHT:
/* follow link */
if (!selected_item){
#ifdef WE_WANT_TO_GO_BACKWARD_ON_KEY_RIGHT
/* Is there any reason why the right key would take us
* backward if there are no links selected?, I agree
* with Torben than doing nothing in this case is better
*/
/* If there are no links, go backward in history */
history_ptr--;
if (history_ptr < 0)
history_ptr = HISTORY_SIZE-1;
currentpoint = startpoint = history [history_ptr].page;
selected_item = history [history_ptr].link;
#endif
} else {
history_ptr = (history_ptr+1) % HISTORY_SIZE;
history [history_ptr].page = currentpoint;
history [history_ptr].link = selected_item;
currentpoint = startpoint = help_follow_link (currentpoint, selected_item) + 1;
}
selected_item = NULL;
break;
case KEY_DOWN:
case '\t':
/* select next link */
new_item = select_next_link (startpoint, selected_item);
if (new_item){
selected_item = new_item;
if (selected_item >= last_shown){
if (c == KEY_DOWN)
move_forward (1);
else
selected_item = NULL;
}
} else if (c == KEY_DOWN)
move_forward (1);
else
selected_item = NULL;
break;
case KEY_UP:
case ALT ('\t'):
/* select previous link */
new_item = select_prev_link (startpoint, selected_item);
selected_item = new_item;
if (selected_item < currentpoint || selected_item >= last_shown){
if (c == KEY_UP)
move_backward (1);
else{
if (link_area != NULL)
selected_item = link_area->link_name;
else
selected_item = NULL;
}
}
break;
case 'n':
/* Next node */
new_item = currentpoint;
while (*new_item && *new_item != CHAR_NODE_END)
new_item++;
if (*++new_item == '['){
while (*new_item != ']')
new_item++;
currentpoint = new_item + 2;
selected_item = NULL;
}
break;
case 'p':
/* Previous node */
new_item = currentpoint;
while (new_item > data + 1 && *new_item != CHAR_NODE_END)
new_item--;
new_item--;
while (new_item > data && *new_item != CHAR_NODE_END)
new_item--;
while (*new_item != ']')
new_item++;
currentpoint = new_item + 2;
selected_item = NULL;
break;
case 'c':
help_index_cmd (h);
break;
case ESC_CHAR:
case XCTRL('g'):
dlg_stop (h);
break;
default:
return 0;
}
help_callback (h, 0, DLG_DRAW);
return 1;
}
static int help_callback (struct Dlg_head *h, int id, int msg)
{
switch (msg){
case DLG_DRAW:
attrset (HELP_NORMAL_COLOR);
dlg_erase (h);
draw_box (h, 1, 1, help_lines+2, HELP_WINDOW_WIDTH+2);
attrset (COLOR_HOT_NORMAL);
dlg_move (h, 1, (HELP_WINDOW_WIDTH - 1) / 2);
addstr (_(" Help "));
attrset (HELP_NORMAL_COLOR);
show (h, currentpoint);
break;
case DLG_KEY:
return help_handle_key (h, id);
}
return 0;
}
void interactive_display_finish (void)
{
clear_link_areas ();
free (data);
}
void interactive_display (char *filename, char *node)
{
WButtonBar *help_bar;
Widget *md;
if ((data = load_file (filename)) == 0){
message (1, MSG_ERROR, _(" Can't open file %s \n %s "),
filename, unix_error_string (errno));
return;
}
if (!(main = search_string (data, node))){
message (1, MSG_ERROR, _(" Can't find node %s in help file "), node);
interactive_display_finish ();
return;
}
#ifndef HAVE_X
if (help_lines > LINES - 4)
help_lines = LINES - 4;
whelp = create_dlg (0, 0, help_lines+4, HELP_WINDOW_WIDTH+4, dialog_colors,
help_callback, "[Help]", "help", DLG_TRYUP|DLG_CENTER);
/* allow us to process the tab key */
whelp->raw = 1;
#endif
selected_item = search_string_node (main, STRING_LINK_START) - 1;
currentpoint = startpoint = main + 1;
for (history_ptr = HISTORY_SIZE; history_ptr;){
history_ptr--;
history [history_ptr].page = currentpoint;
history [history_ptr].link = selected_item;
}
#ifndef HAVE_X
help_bar = buttonbar_new (keybar_visible);
help_bar->widget.y -= whelp->y;
help_bar->widget.x -= whelp->x;
md = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH-2);
add_widget (whelp, help_bar);
add_widget (whelp, md);
define_label_data (whelp, (Widget *)NULL, 1, _("Help"),
(buttonbarfn) help_help_cmd, whelp);
define_label_data (whelp, (Widget *)NULL, 2, _("Index"),
(buttonbarfn) help_index_cmd,whelp);
define_label_data (whelp, (Widget *)NULL, 3, _("Prev"),
(buttonbarfn) prev_node_cmd, whelp);
define_label (whelp, (Widget *) NULL, 4, "", 0);
define_label (whelp, (Widget *) NULL, 5, "", 0);
define_label (whelp, (Widget *) NULL, 6, "", 0);
define_label (whelp, (Widget *) NULL, 7, "", 0);
define_label (whelp, (Widget *) NULL, 8, "", 0);
define_label (whelp, (Widget *) NULL, 9, "", 0);
define_label_data (whelp, (Widget *) NULL, 10, _("Quit"), quit_cmd, whelp);
run_dlg (whelp);
interactive_display_finish ();
destroy_dlg (whelp);
#else
x_interactive_display ();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -