Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
629 lines
16 KiB
Plaintext
629 lines
16 KiB
Plaintext
/*
|
|
** BRIEF -- Basic Reconfigurable Interactive Editing Facility
|
|
**
|
|
** Written by Dave Nanian and Michael Strickman.
|
|
*/
|
|
|
|
#include "dialog.h"
|
|
#include "win_ctrl.h"
|
|
|
|
/*
|
|
** help.cb:
|
|
**
|
|
** This macro contains the BRIEF help system. Display of menus and the like
|
|
** is handled by the BRIEF dialog manager.
|
|
*/
|
|
|
|
#define FIRST_MENU_LINE 3
|
|
#define FIRST_MENU_COL 20
|
|
|
|
int _user_kbd;
|
|
string prev_func; // name of the previous menu action function
|
|
|
|
int process_help_menu (string buf_name, string file_name, ~int height, ~int width);
|
|
int _help_add_button (~string buffer_name);
|
|
void to_top (void);
|
|
string search_path (string path, string name);
|
|
int display_help (string topic, ~string help_file);
|
|
void mouse_help(int event, int modifier, int parm2, int parm3);
|
|
void mouse_help_menu(int event, int modifier, int parm2, int parm3);
|
|
void _help_down();
|
|
void _help_up();
|
|
void _help_exit ();
|
|
|
|
/*
|
|
** help:
|
|
**
|
|
** This macro is used as the main help command. It's called when
|
|
** the user presses Alt-h.
|
|
*/
|
|
|
|
void help ()
|
|
{
|
|
_user_kbd = inq_keyboard ();
|
|
process_help_menu ("Help Menu", "help.mnu");
|
|
}
|
|
|
|
/*
|
|
** _context_help:
|
|
**
|
|
** This macro is used as the "help" registered macro. It is called
|
|
** when a prompt is displayed on the status line and the user presses
|
|
** Alt-h. Write a replacement macro if you want your own help to be
|
|
** be available for your own commands. The macro should check if the
|
|
** last command is one of your macros, and if so call display_help
|
|
** with the name of your help file; if not, just call _context_help
|
|
** (so that all replacement macros are eventually called).
|
|
*/
|
|
|
|
void _context_help ()
|
|
{
|
|
_user_kbd = inq_keyboard ();
|
|
display_help (inq_command ());
|
|
}
|
|
|
|
/*
|
|
** process_help_menu:
|
|
**
|
|
** This macro takes four parameters: the buffer name, file name,
|
|
** height and width of the menu. It sets things up and calls the
|
|
** dialog manager to deal with the actual display and manipulation of
|
|
** the menus. (If height & width are omitted, menu is sized
|
|
** automatically based on the contents of the menu buffer.)
|
|
*/
|
|
|
|
int process_help_menu (string buf_name, string file_name, ~int height, ~int width)
|
|
{
|
|
int startline,
|
|
startcol;
|
|
|
|
/*
|
|
** Successive menus are offset by a constant amount from the
|
|
** first one. The dialog manager automatically keeps track of
|
|
** the current menu level. Note that if height and width are
|
|
** omitted, height == startline and width == startcol.
|
|
*/
|
|
|
|
height += startline = FIRST_MENU_LINE + _dialog_level;
|
|
width += startcol = FIRST_MENU_COL + _dialog_level * 2;
|
|
|
|
/*
|
|
** Here we call the dialog manager to create the help menu.
|
|
** Whenever an interesting event occurs, the dialog manager will
|
|
** call process_help_event.
|
|
**
|
|
** Note that process_help_event function may call this
|
|
** routine to display an additional menu.
|
|
*/
|
|
|
|
_process_menu (startcol, height, width, startline, buf_name, "Select a Category", file_name, NULL, "process_help_event", TRUE);
|
|
|
|
returns (TRUE);
|
|
}
|
|
|
|
/*
|
|
** process_help_event:
|
|
**
|
|
** Action macro called by the dialog manager. Used to add buttons
|
|
** to the menu or handle picking from the menu.
|
|
*/
|
|
|
|
int process_help_event (int key, ...)
|
|
{
|
|
string action;
|
|
|
|
/*
|
|
** If a menu button was picked, we parse the action off
|
|
** the menu button and execute it.
|
|
*/
|
|
|
|
if (key == DIALOG_INIT)
|
|
{
|
|
/*
|
|
** Setup a mouse event handler to allow button 2 click to
|
|
** exit the current menu and Ctrl+ button 2 click to exit help
|
|
*/
|
|
prev_func = inq_mouse_action();
|
|
set_mouse_action( "mouse_help_menu" );
|
|
}
|
|
else if (key == DIALOG_PICK_MENU)
|
|
{
|
|
get_parm (2, action);
|
|
execute_macro (substr (action, index (action, ";") + 1));
|
|
}
|
|
else if (key == DIALOG_CREATE_MENU)
|
|
{
|
|
get_parm (2, action);
|
|
_help_add_button (action);
|
|
}
|
|
returns (TRUE);
|
|
}
|
|
|
|
/*
|
|
** display_help:
|
|
**
|
|
** display_help takes a help keyword and displays the appropriate
|
|
** help information in an overlapping window. It uses the global
|
|
** variable _dialog_level to tie the grey - and Esc keystrokes in
|
|
** with the rest of the menu package (grey - will remove the window,
|
|
** and Esc will remove windows until the _dialog_level is 0).
|
|
**
|
|
** The optional second parameter is the name of the help file.
|
|
*/
|
|
|
|
int display_help (string, ~string)
|
|
{
|
|
int displayed_help,
|
|
orig_buffer,
|
|
file_buffer;
|
|
|
|
string commands = "help.txt";
|
|
|
|
get_parm (1, commands);
|
|
|
|
if (file_buffer = create_buffer ("Help File", search_path (_dialog_dir, commands), 1))
|
|
{
|
|
string topic;
|
|
|
|
get_parm (0, topic);
|
|
message ("Locating help text...");
|
|
|
|
orig_buffer = set_buffer (file_buffer);
|
|
tabs (3);
|
|
|
|
if (search_fwd (("\xc" + topic) + "\xc") || search_back (("\xc" + topic) + "\xc"))
|
|
{
|
|
int loc;
|
|
|
|
message ("Help display for %s.", topic);
|
|
|
|
if (loc = index (commands = read (), "\xc\""))
|
|
commands = substr (commands, loc + 1, strlen (commands) - (loc + 2));
|
|
else
|
|
commands = "";
|
|
|
|
beginning_of_line ();
|
|
down ();
|
|
|
|
/*
|
|
** hide the zoom button and horizontial scroll bars for the help
|
|
** information windows
|
|
*/
|
|
set_ctrl_state( ZOOM_BTN, HIDE_CTRL ); // dont display a zoom button
|
|
set_ctrl_state( HORZ_SCROLL, HIDE_CTRL ); // dont display a horizontial scroll bar
|
|
|
|
if (inq_called () == "_context_help") {
|
|
create_window (2, 21, 76, 2, "<Alt-h> for assignment, <Esc> or <Keypad-minus> to exit help");
|
|
} else {
|
|
create_window (2, 21, 76, 2, "<Keypad-minus> for menu, <Alt-h> for assignment, <Esc> to exit help");
|
|
}
|
|
|
|
attach_buffer (file_buffer);
|
|
|
|
keyboard_push ();
|
|
assign_to_key ("<Keypad-minus>", "_exit");
|
|
assign_to_key ("<Esc>", "_help_exit");
|
|
assign_to_key ("<PgUp>", "_help_up");
|
|
assign_to_key ("<PgDn>", "_help_down");
|
|
assign_to_key ("<Alt-h>", "_help_assignment " + commands);
|
|
|
|
/* establish the mouse action handler for help */
|
|
set_mouse_action( "mouse_help" );
|
|
|
|
refresh ();
|
|
|
|
process ();
|
|
keyboard_pop ();
|
|
delete_window ();
|
|
search_back (("\xc" + topic) + "\xc");
|
|
beginning_of_line ();
|
|
displayed_help++;
|
|
/*
|
|
** allow display of zoom button and horizontial scroll bar
|
|
** for subsequent window creation
|
|
*/
|
|
set_ctrl_state( ZOOM_BTN, SHOW_CTRL ); // display a zoom button
|
|
set_ctrl_state( HORZ_SCROLL, SHOW_CTRL ); // display a horizontial scroll bar
|
|
|
|
}
|
|
else
|
|
error ("No help available for %s.", topic);
|
|
|
|
set_buffer (orig_buffer);
|
|
}
|
|
else
|
|
error ("Help file not found.");
|
|
|
|
returns (displayed_help);
|
|
}
|
|
|
|
/*
|
|
** mouse_help
|
|
**
|
|
** Handle all the mouse events of interest for help text windows
|
|
**
|
|
** Mouse assignments
|
|
** BTN1_CLICK - display key assignment i.e. <Alt-h>
|
|
** BTN2_CLICK - to previous screen i.e. <Keypad-minus>
|
|
** BTN2_CLICK + CTRL - exit help i.e. <Esc>
|
|
** SET_WIN outside text window - close the window
|
|
**
|
|
*/
|
|
void mouse_help ( int event, // the event code
|
|
int modifier, // modifier keys
|
|
int parm2, // line or scroll bar code
|
|
int parm3 ) // column or thumb position
|
|
{
|
|
|
|
/* handle the events of interest */
|
|
|
|
switch ( event ){
|
|
case BTN1_CLICK: // display key assignment
|
|
execute_macro( inq_assignment( "<Alt-h>" ));
|
|
|
|
case CLOSE_WIN: // close the window
|
|
case BTN2_CLICK: // to previous screen
|
|
switch ( modifier ){
|
|
case 0: // to previous screen
|
|
exit();
|
|
case KB_CTRL: // exit the help system
|
|
_help_exit();
|
|
|
|
}
|
|
|
|
case SET_WIN: // click outside window is close window
|
|
if ( parm2 != inq_window() ) exit();
|
|
|
|
case VSCROLL: // vertical scroll bar event
|
|
switch ( parm2 ){
|
|
case SB_BOTTOM: // end of this help text
|
|
{
|
|
int old_line, line;
|
|
inq_position (old_line); // save current position
|
|
search_fwd ("\xc"); // look for next topic in help file
|
|
inq_position (line); // get its position
|
|
if (line - old_line <= 18) {
|
|
/* current topic is only one "page", go to original position */
|
|
move_abs (old_line);
|
|
} else {
|
|
/* current topic is more than one "page" go to last page */
|
|
move_abs ( line - 18 );
|
|
}
|
|
}
|
|
|
|
case SB_TOP: // top of this help text
|
|
{
|
|
int old_line, line;
|
|
inq_position (old_line); // save current position
|
|
search_back ("\xc"); // look for next topic in help file
|
|
inq_position (line); // get its position
|
|
if (old_line - line <= 18) {
|
|
/* current topic is only one "page", go to original position */
|
|
move_abs (old_line);
|
|
} else {
|
|
/* current topic is more than one "page" go to first page */
|
|
move_abs ( line+1 );
|
|
}
|
|
}
|
|
|
|
case SB_LINEDOWN:
|
|
case SB_PAGEDOWN: // page down request
|
|
_help_down();
|
|
case SB_LINEUP:
|
|
case SB_PAGEUP: // page up request
|
|
_help_up();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
** _help_down:
|
|
**
|
|
** _help_down is called when the PgDn key is pressed: it ensures that
|
|
** the user does not go past the end of the help file. Since the command
|
|
** name begins with an underscore, the current command is not reassigned.
|
|
*/
|
|
|
|
void _help_down ()
|
|
{
|
|
int line,
|
|
col,
|
|
old_line,
|
|
old_col;
|
|
|
|
inq_position (old_line, old_col);
|
|
search_fwd ("\xc");
|
|
inq_position (line, col);
|
|
move_abs (old_line, old_col);
|
|
|
|
page_down ();
|
|
|
|
if (line - old_line <= 18)
|
|
move_abs (old_line, old_col);
|
|
}
|
|
|
|
/*
|
|
** _help_up:
|
|
**
|
|
** Goes up a page in the help file. Since the command name begins
|
|
** with an underscore, the current command is not reassigned.
|
|
*/
|
|
|
|
void _help_up ()
|
|
{
|
|
int line,
|
|
col,
|
|
old_line,
|
|
old_col;
|
|
|
|
inq_position (old_line, old_col);
|
|
search_back ("\xc");
|
|
inq_position (line, col);
|
|
move_abs (old_line, old_col);
|
|
|
|
page_up ();
|
|
|
|
if (old_line - line <= 18)
|
|
move_abs (old_line, old_col);
|
|
}
|
|
|
|
/*
|
|
** key_specific_help:
|
|
**
|
|
** Gets help for the user using the keys, not the menus.
|
|
*/
|
|
|
|
void key_specific_help ()
|
|
{
|
|
int saved_level = _dialog_level,
|
|
key_value;
|
|
|
|
string sequence,
|
|
assignment;
|
|
|
|
/*
|
|
** The dialog level is saved and restored when we enter and exit
|
|
** key-specific help. During execution, we set the _dialog_level to
|
|
** 0; a press of Esc will then only remove the help screen.
|
|
**
|
|
** If this wasn't done, extra "exit" calls would be done, and
|
|
** the next time a window came up it would be removed immediately.
|
|
*/
|
|
|
|
_dialog_level = 0;
|
|
keyboard_push (_user_kbd);
|
|
message ("Press the key you want help on, <Esc> to exit.");
|
|
|
|
while (key_value != key_to_int ("<Esc>"))
|
|
{
|
|
while ((key_value = read_char ()) == -1);
|
|
sprintf (sequence, "#%u", key_value);
|
|
|
|
/*
|
|
** If the key assignment we have obtained is ambiguous, we keep
|
|
** appending additional key assignments to it until we find a
|
|
** command (or fail).
|
|
*/
|
|
|
|
while ((assignment = inq_assignment (sequence)) == "ambiguous")
|
|
{
|
|
message ("Press next key in sequence, <Esc> to exit.");
|
|
|
|
while ((key_value = read_char ()) == -1);
|
|
|
|
if (key_value == key_to_int ("<Esc>"))
|
|
break;
|
|
|
|
sprintf (sequence, "%s#%u", sequence, key_value);
|
|
}
|
|
if (key_value == key_to_int ("<Esc>"))
|
|
break;
|
|
|
|
if (display_help (assignment))
|
|
message ("Press the key you want help on, <Esc> to exit.");
|
|
}
|
|
_dialog_level = saved_level;
|
|
keyboard_pop (1);
|
|
message ("");
|
|
}
|
|
|
|
/*
|
|
** _help_assignment:
|
|
**
|
|
** This macro takes a command name as a parameter, creates a window
|
|
** and displays the keys assigned to that command.
|
|
*/
|
|
|
|
_help_assignment (string commands)
|
|
{
|
|
string this_command,
|
|
keys;
|
|
|
|
int old_buf,
|
|
key_buf,
|
|
loc,
|
|
comma_loc,
|
|
semi_loc,
|
|
key_read,
|
|
have_assignment;
|
|
|
|
keyboard_push (_user_kbd);
|
|
|
|
old_buf = set_buffer (key_buf = create_buffer ("Keys", NULL, 1));
|
|
tabs (4);
|
|
|
|
while (strlen (commands))
|
|
{
|
|
if (semi_loc && (semi_loc < comma_loc || !comma_loc))
|
|
insert ("\n\nSee also:\n");
|
|
|
|
comma_loc = index (commands, ",");
|
|
semi_loc = index (commands, ";");
|
|
|
|
if (semi_loc && (semi_loc < comma_loc || !comma_loc))
|
|
loc = semi_loc;
|
|
else
|
|
loc = comma_loc;
|
|
|
|
if (loc)
|
|
{
|
|
this_command = substr (commands, 1, loc - 1);
|
|
commands = substr (commands, loc + 1);
|
|
}
|
|
else
|
|
{
|
|
this_command = commands;
|
|
commands = "";
|
|
}
|
|
if (this_command != "")
|
|
{
|
|
++have_assignment;
|
|
|
|
if ((keys = inq_assignment (this_command, 1)) == "")
|
|
keys = inq_assignment ("execute_macro", 1) + "<-and> " + this_command;
|
|
|
|
insert ("\n \"" + this_command + "\" is assigned to:\n\t\t");
|
|
|
|
while (loc = index (keys, "<-"))
|
|
{
|
|
insert (substr (keys, 1, loc - 1));
|
|
keys = substr (keys, loc);
|
|
|
|
switch (substr (keys, 1, index (keys, ">")))
|
|
{
|
|
case "<-and>":
|
|
keys = substr (keys, 7);
|
|
|
|
case "<-also>":
|
|
{
|
|
insert ("\n\t\t");
|
|
keys = substr (keys, 8);
|
|
}
|
|
default:
|
|
{
|
|
keys = "";
|
|
|
|
/*
|
|
** Note: this breaks from the loop, not the switch.
|
|
*/
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
insert (keys + "\n");
|
|
}
|
|
}
|
|
|
|
/*
|
|
** If any assignments were found, we display them in a window.
|
|
*/
|
|
|
|
if (have_assignment)
|
|
{
|
|
keyboard_push ();
|
|
assign_to_key ("<Esc>", "_exit");
|
|
assign_to_key ("<Keypad-minus>", "_exit");
|
|
assign_to_key ("<PgUp>", "_assign_up");
|
|
assign_to_key ("<PgDn>", "_assign_down");
|
|
top_of_buffer ();
|
|
create_window (6, 15, 72, 4, "<Esc> or <Keypad-minus> to exit, <PgUp> or <PgDn> to scroll");
|
|
attach_buffer (key_buf);
|
|
/* establish the mouse action handler for this help window */
|
|
set_mouse_action( "mouse_help" );
|
|
|
|
refresh ();
|
|
process ();
|
|
keyboard_pop ();
|
|
delete_window ();
|
|
}
|
|
if (!have_assignment)
|
|
beep ();
|
|
|
|
delete_buffer (key_buf);
|
|
set_buffer (old_buf);
|
|
keyboard_pop (1);
|
|
}
|
|
|
|
void _assign_up ()
|
|
{
|
|
page_up ();
|
|
}
|
|
|
|
void _assign_down ()
|
|
{
|
|
page_down ();
|
|
move_rel (inq_position () * -1);
|
|
}
|
|
|
|
/*
|
|
** _help_exit:
|
|
**
|
|
** Exits from the help system; calls exit to remove the help
|
|
** window, and pushes back an <Esc> if the dialog manager is active
|
|
** to remove the other (menu) windows.
|
|
*/
|
|
|
|
void _help_exit ()
|
|
{
|
|
if (_dialog_level)
|
|
push_back (key_to_int ("<Esc>"));
|
|
|
|
exit ();
|
|
}
|
|
|
|
/*
|
|
** _help_add_button:
|
|
**
|
|
** Used to add buttons to existing menus. This macro does nothing,
|
|
** but you can write a replacement macro for it that checks the only
|
|
** parameter (the buffer name) and adds buttons. When your replacement
|
|
** macro is called, the menu buffer will be current and the menu will
|
|
** be unformatted (just as it is on disk).
|
|
** Make sure your replacement calls _help_add_button so that all
|
|
** other replacement macros eventually get called.
|
|
*/
|
|
|
|
int _help_add_button (~string)
|
|
{
|
|
returns (TRUE);
|
|
}
|
|
|
|
/*
|
|
** mouse_help_menu
|
|
**
|
|
** Sub-class the default menu handler for the help system
|
|
**
|
|
** Mouse action assignments:
|
|
** default menu actions plus
|
|
** Click 2 - exit this menu
|
|
** Dbl Click 2 - exit the help system
|
|
**
|
|
*/
|
|
void mouse_help_menu(int event, // the event code
|
|
int modifier, // modifier keys
|
|
int parm2, // line or scroll bar code
|
|
int parm3 ) // column or thumb position
|
|
{
|
|
/* handle the events of interest */
|
|
switch ( event ){
|
|
case BTN2_CLICK: // to previous screen
|
|
switch ( modifier ){
|
|
case 0: // exit this menu
|
|
exit();
|
|
case KB_CTRL: // exit the help system
|
|
_help_exit();
|
|
|
|
}
|
|
|
|
default:
|
|
/* let the previous event handler for menus process the event */
|
|
execute_macro( prev_func, event, modifier, parm2, parm3 );
|
|
|
|
}
|
|
}
|
|
|
|
|