[Back to ENTRY SWAG index] [Back to Main SWAG index] [Original]
{
Attached is a very simple single line editor, possibly for inclusion in the
SWAG archive. It is written using Turbo/Borland Pascal object oriented
extensions so should, in theory, be easy to use and modify :)
It supports the following keystrokes:
Backspace : Delete previous character
Ctrl Backspace : Delete string upto cursor
Delete : Delete next character
Ctrl Delete : Delete string after cursor
Home : Start of string
End : End of string
Left arrow : Left one character
Right arrow : Right one character
Ctrl+Left arrow : Left one word
Ctrl+Right arrow : Right one word
It is setup by passing the coordinates where the field should be
displayed, the maximum length of the field and the character to use
for padding the field.
It is then called, passing in an initial value for the field which is
then amended, returning true if the enter key is pressed and false
if escape key is pressed.
}
UNIT Edit;
INTERFACE
TYPE
TextLine = Object
Details : String;
CPos : Byte;
XPos : Byte;
YPos : Byte;
MaxLen : Byte;
PaddingChar : Char;
{ ********************************************************}
{ PUBLIC METHODS }
{
SetupLimits - Set up initial values to be used:
X : X position for the field
Y : Y position for the field
Max : Max length of the field
PadChar : Character to use for padding the line
}
CONSTRUCTOR SetupLimits
(
X : Byte;
Y : Byte;
Max : Byte;
PadChar : Char
);
{
EditLine - Edit the line.
Supports
Backspace : Delete previous character
Ctrl Backspace : Delete string upto cursor
Delete : Delete next character
Ctrl Delete : Delete string after cursor
Home : Start of string
End : End of string
Left arrow : Left one character
Right arrow : Right one character
Ctrl+Left arrow : Left one word
Ctrl+Right arrow : Right one word
StrEntered : String to use. Set with start value then
returns value entered.
Function returns true if enter pressed, false if escape
pressed.
}
FUNCTION EditLine (VAR StrEntered : String) : Boolean;
{ ********************************************************}
{ PRIVATE METHODS - Do not call }
PROCEDURE DisplayLine;
FUNCTION AddChar (Ch : Char) : Boolean;
FUNCTION DeletePrevChar : Boolean;
FUNCTION DeleteNextChar : Boolean;
{ ********************************************************}
END;
IMPLEMENTATION
USES
Crt, Dos;
CONST
End_Key = #79;
Left = #75;
Right = #77;
HomeKey = #71;
Backspace = #8;
CtrlBackspace = #127;
DeleteKey = #83;
CtrlDelete = #6;
CarrRet = #13;
Escape = #27;
CtrlLeft = #115;
CtrlRight = #116;
CONSTRUCTOR TextLine.SetupLimits
(
X : Byte;
Y : Byte;
Max : Byte;
PadChar : Char
);
BEGIN
CPos := 1;
XPos := X;
YPos := Y;
MaxLen := Max;
PaddingChar := PadChar;
END; { SetupLimits }
PROCEDURE TextLine.DisplayLine;
VAR
Index : Byte;
BEGIN
GotoXY (XPos, YPos);
Write (Details);
FOR Index := 1 TO MaxLen - Length (Details) DO
Write (PaddingChar);
GotoXY (XPos+CPos, YPos);
END; { DisplayLine }
FUNCTION TextLine.AddChar (Ch : Char) : Boolean;
VAR
AddedChar : Boolean;
BEGIN
AddedChar := TRUE;
IF (CPos = Length (Details)) THEN
BEGIN
IF Length (Details) < MaxLen THEN
BEGIN
Details := Concat (Details, Ch);
Inc (CPos);
END { If }
ELSE
AddedChar := FALSE;
END { If }
ELSE
BEGIN
Inc (CPos);
Insert (Ch, Details, CPos);
IF Length (Details) > MaxLen THEN
Delete (Details, Length(Details), 1);
END; { Else }
AddChar := AddedChar;
END; { AddChar }
FUNCTION TextLine.DeletePrevChar : Boolean;
VAR
DeletedChar : Boolean;
BEGIN
DeletedChar := TRUE;
IF CPos < 1 THEN
DeletedChar := FALSE
ELSE
IF CPos = Length (Details) THEN
BEGIN
Delete (Details, CPos, 1);
Dec (CPos);
END { If }
ELSE
BEGIN
Delete (Details, CPos, 1);
Dec (CPos);
END; { Else }
DeletePrevChar := DeletedChar;
END; { DeletePrevChar }
FUNCTION TextLine.DeleteNextChar : Boolean;
VAR
DeletedChar : Boolean;
BEGIN
DeletedChar := TRUE;
IF (CPos >= Length (Details)) THEN
DeletedChar := FALSE
ELSE
Delete (Details, CPos+1, 1);
DeleteNextChar := DeletedChar;
END; { DeleteNextChar }
FUNCTION Textline.EditLine (VAR StrEntered : String) : Boolean;
VAR
Ch : Char;
Changed : Boolean;
Accepted : Boolean;
Finished : Boolean;
BEGIN
Accepted := TRUE;
Finished := FALSE;
{ If they send in a string that is too large then trim it }
IF Length (StrEntered) > MaxLen THEN
Delete (StrEntered, MaxLen+1, Length (StrEntered));
Details := StrEntered;
CPos := Length (Details);
DisplayLine;
REPEAT
Ch := Readkey;
Changed := FALSE;
IF Ch = #0 THEN
BEGIN
Ch := Readkey;
CASE Ch OF
End_Key : BEGIN
CPos := Length (Details);
Changed := TRUE;
END; { End_Key }
HomeKey : BEGIN
CPos := 0;
Changed := TRUE;
END; { HomeKey }
Left : BEGIN
IF CPos > 0 THEN
BEGIN
Dec (CPos);
Changed := TRUE;
END; { If }
END; { Left }
Right : BEGIN
IF CPos < Length (Details) THEN
BEGIN
Inc (CPos);
Changed := TRUE;
END; { If }
END; { Right }
CtrlLeft : BEGIN
IF (CPos > 0) THEN
Dec (CPos);
WHILE (CPos > 0) AND (Details [CPos] <> ' ') DO
Dec (CPos);
Changed := TRUE;
END; { CtrlLeft }
CtrlRight : BEGIN
IF (CPos < Length(Details)) THEN
Inc (CPos);
WHILE (CPos < Length(Details)) AND (Details [CPos] <> ' ') DO
Inc (CPos);
Changed := TRUE;
END; { CtrlRight }
CtrlDelete : BEGIN
Delete (Details, CPos+1, Length (Details));
Changed := TRUE;
END; { CtrlDelete }
DeleteKey : BEGIN
Changed := DeleteNextChar;
END; { DeleteKey }
END; { Case }
END { If }
ELSE
BEGIN
CASE Ch OF
CtrlBackspace : BEGIN
Delete (Details, 1, CPos);
CPos := 0;
Changed := TRUE;
END; { CtrlBackspace }
Backspace : BEGIN
Changed := DeletePrevChar;
END; { Backspace }
CarrRet : Finished := TRUE;
Escape : BEGIN
Finished := TRUE;
Accepted := FALSE;
END; { Escape }
' '..'}' : BEGIN
Changed := AddChar (Ch);
END; { Ord (' ') }
END; { Case }
END; { Else }
IF Changed THEN
DisplayLine;
UNTIL Finished;
IF Accepted THEN
StrEntered := Details;
EditLine := Accepted;
END; { EditLine }
BEGIN
END.
[Back to ENTRY SWAG index] [Back to Main SWAG index] [Original]