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>
249 lines
4.8 KiB
Plaintext
249 lines
4.8 KiB
Plaintext
/*
|
|
** BRIEF -- Basic Reconfigurable Interactive Editing Facility
|
|
**
|
|
**
|
|
** dlg_fld.cb:
|
|
**
|
|
** This file contains all BRIEF macros for managing dialog box fields.
|
|
*/
|
|
|
|
#include <dialog.h>
|
|
#include <dlg.h>
|
|
|
|
/*
|
|
** _field_insert:
|
|
**
|
|
** Makes sure that there's still room left in the window; if not,
|
|
** removes the last key inserted, beeps and prints an error message.
|
|
** Handles both insert and overstrike mode.
|
|
*/
|
|
|
|
void _field_insert (int key)
|
|
{
|
|
int last_col;
|
|
|
|
if (inq_marked ())
|
|
{
|
|
raise_anchor ();
|
|
delete_to_eol ();
|
|
}
|
|
save_position ();
|
|
|
|
if (inq_mode ())
|
|
end_of_line ();
|
|
|
|
inq_position (NULL, last_col);
|
|
restore_position ();
|
|
|
|
if (last_col < _dialog_size)
|
|
self_insert (key);
|
|
else
|
|
{
|
|
error ("Field is full.");
|
|
beep ();
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _field_bksp:
|
|
**
|
|
** Backs the cursor up in a typed field (if it's not already at
|
|
** the beginning of the field) and deletes it. In overstrike
|
|
** mode, this function replaces the deleted character with a space.
|
|
*/
|
|
|
|
void _field_bksp ()
|
|
{
|
|
int cur_col;
|
|
|
|
inq_position (NULL, cur_col);
|
|
|
|
if (inq_marked ())
|
|
{
|
|
raise_anchor ();
|
|
delete_to_eol ();
|
|
}
|
|
if (cur_col > _dialog_col)
|
|
{
|
|
left ();
|
|
|
|
if (!at_eol ())
|
|
{
|
|
delete_char ();
|
|
|
|
if (!inq_mode ())
|
|
{
|
|
insert (" ");
|
|
prev_char ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _field_left, _field_right:
|
|
**
|
|
** Moves the cursor to the left or to the right in the field, if
|
|
** possible. If the field is marked (which implies that the cursor
|
|
** is still at the beginning of the field), the highlight is removed.
|
|
*/
|
|
|
|
void _field_left ()
|
|
{
|
|
int cur_col;
|
|
|
|
raise_anchor ();
|
|
inq_position (NULL, cur_col);
|
|
|
|
if (cur_col > _dialog_col)
|
|
left ();
|
|
}
|
|
|
|
void _field_right ()
|
|
{
|
|
int cur_col;
|
|
|
|
raise_anchor ();
|
|
inq_position (NULL, cur_col);
|
|
|
|
if (cur_col < _dialog_size - 1)
|
|
right ();
|
|
}
|
|
|
|
/*
|
|
** _field_del:
|
|
**
|
|
** Deletes a character, as long as it's not a newline. Works the
|
|
** same way in both insert and overstrike modes. If the field is still
|
|
** marked, deletes the whole thing.
|
|
*/
|
|
|
|
void _field_del ()
|
|
{
|
|
if (!at_eol ())
|
|
if (inq_marked ())
|
|
{
|
|
raise_anchor ();
|
|
delete_to_eol ();
|
|
}
|
|
else
|
|
delete_char ();
|
|
}
|
|
|
|
/*
|
|
** _field_end, _field_home:
|
|
**
|
|
** Removes the mark if there is one, then positions the cursor
|
|
** at the end or beginning of the field.
|
|
*/
|
|
|
|
void _field_end ()
|
|
{
|
|
raise_anchor ();
|
|
end_of_line ();
|
|
}
|
|
|
|
void _field_home ()
|
|
{
|
|
raise_anchor ();
|
|
move_abs (0, _dialog_col);
|
|
}
|
|
|
|
/*
|
|
** _field_del_line, _field_delete_to_eol:
|
|
**
|
|
** Deletes either the entire field or the field contents after the
|
|
** cursor position, removing any mark first.
|
|
*/
|
|
|
|
void _field_del_line (void)
|
|
{
|
|
move_abs (0, _dialog_col);
|
|
_field_delete_to_eol ();
|
|
}
|
|
|
|
void _field_delete_to_eol (void)
|
|
{
|
|
raise_anchor ();
|
|
delete_to_eol ();
|
|
}
|
|
|
|
/*
|
|
** _dialog_validate:
|
|
**
|
|
** Determines if the current field meets predefined criteria for
|
|
** being a nonblank string, integer, or file name. (Used for all typed
|
|
** fields.) Returns TRUE if the string satisfied the criteria for
|
|
** the current type, _dialog_type, or if the current type was not
|
|
** a nonblank string, integer, or file name type.
|
|
*/
|
|
|
|
int _dialog_validate (string value)
|
|
{
|
|
int retval = TRUE;
|
|
|
|
switch (_dialog_type)
|
|
{
|
|
case FILENAME:
|
|
if (!(retval = is_filename (value)))
|
|
error ("This field must be a filename.");
|
|
|
|
case INTEGER:
|
|
if (!(retval = search_string ("<[ \\t]@{[\\-+][0-9]+}|{[0-9]+}[ \t]@\n", value + "\n", NULL, TRUE)))
|
|
error ("This field must be an integer.");
|
|
|
|
case NONBLANK:
|
|
if (!(retval = search_string ("[~ \\t\\n]", value, NULL, TRUE)))
|
|
error ("This field may not be blank.");
|
|
}
|
|
if (!retval)
|
|
beep ();
|
|
|
|
returns (retval);
|
|
}
|
|
|
|
/*
|
|
** is_filename:
|
|
**
|
|
** Returns TRUE if a string contains a syntactically correct
|
|
** filename. Note: this regular expression will catch most, but
|
|
** not all, incorrect file names. Among the cases that it will not
|
|
** catch are two drive specifiers, extra or misplaced periods, omitted
|
|
** filename (just extension), and name or extension too long.
|
|
*/
|
|
|
|
int is_filename (string name)
|
|
{
|
|
returns (search_string ("<{[a-z]:}@[\\\\/]@{[~- \"%*-,/:-?\\[-\\]|]+[\\\\/]}@[~- \"%*-,/:-?\\[-\\]|]+>", name + "\n", NULL, TRUE, FALSE));
|
|
}
|
|
|
|
/*
|
|
** at_eol:
|
|
**
|
|
** Returns TRUE if the current position is at the end of a line,
|
|
** FALSE otherwise.
|
|
*/
|
|
|
|
int at_eol ()
|
|
{
|
|
returns (read (1) == "\n");
|
|
}
|
|
|
|
/*
|
|
** _field_contents:
|
|
**
|
|
** Returns the contents of the current field, not including the
|
|
** newline, and regardless of the cursor position.
|
|
*/
|
|
|
|
string _field_contents ()
|
|
{
|
|
string field;
|
|
|
|
save_position ();
|
|
move_abs (0, _dialog_col);
|
|
field = read ();
|
|
restore_position ();
|
|
returns (substr (field, 1, strlen (field) - 1));
|
|
}
|