home *** CD-ROM | disk | FTP | other *** search
-
- { Copyright (c) 1989,90 by Borland International, Inc. }
-
- unit TCInput;
- { Turbo Pascal 6.0 object-oriented example input routines.
- This unit is used by TCALC.PAS.
- See TCALC.DOC for an more information about this example.
- }
-
- {$S-}
-
- interface
-
- uses Crt, TCUtil, TCScreen, TCLStr;
-
- const
- LeftInputArrow = #17;
- RightInputArrow = #16;
- YesNo = 'Y/N';
- LegalYesNo = ['Y', 'N'];
- AllUpper = True;
- NotUpper = False;
- ErrNumberError1 = 'You must enter a number from ';
- ErrNumberError2 = ' to ';
- ErrColumnError1 = 'You must enter a column from ';
- ErrColumnError2 = ' to ';
- ErrCellError = 'You must enter a legal cell';
-
- type
- InputField = object
- StartCol : ScreenColRange;
- StopCol : Integer;
- InputRow : Integer;
- MaxInputLen : Word;
- Quit : Boolean;
- InputData : LStringPtr;
- UCase : Boolean;
- InputArea : ScreenArea;
- constructor Init(C1 : ScreenColRange; C2 : Integer; R : Integer;
- InitMaxInputLen : Word; InitUCase : Boolean);
- destructor Done;
- function GetQuit : Boolean;
- procedure Edit(StartCursor : Word);
- procedure ClearInput;
- end;
-
- function ReadString(Prompt : String; Len : Word;
- var ESCPressed : Boolean) : String;
-
- function GetLegalChar(Prompt : String; Legal : CharSet;
- var ESCPressed : Boolean) : Char;
-
- function GetYesNo(Prompt : String; var ESCPressed : Boolean) : Boolean;
-
- function GetNumber(Prompt : String; Low, High : Longint;
- var Result : Boolean) : Longint;
-
- implementation
-
- constructor InputField.Init(C1 : ScreenColRange; C2 : Integer; R : Integer;
- InitMaxInputLen : Word; InitUCase : Boolean);
- { Sets up an input field }
- begin
- InputData := New(LStringPtr, Init);
- if InputData = nil then
- Fail;
- StartCol := C1;
- StopCol := C2;
- InputRow := R;
- if InitMaxInputLen = 0 then
- MaxInputLen := 65521 { Maximum area that a pointer can allocate }
- else
- MaxInputLen := InitMaxInputLen;
- UCase := InitUCase;
- Quit := False;
- end; { InputField.Init }
-
- destructor InputField.Done;
- { Remove memory used by an input field }
- begin
- Dispose(InputData, Done);
- end; { InputField.Done }
-
- function InputField.GetQuit : Boolean;
- { Check to see if an input field has been exited with ESC }
- begin
- GetQuit := Quit;
- end; { InputField.GetQuit }
-
- procedure InputField.Edit(StartCursor : Word);
- { Edits the input field }
- var
- CursorPos, Start, Cursor : Word;
- Ch : Word;
- Good, InsMode, Finished : Boolean;
- R : ScreenRowRange;
- SCol, ECol, EndCol : ScreenColRange;
- begin
- with InputData^ do
- begin
- Quit := False;
- SCol := StartCol; { Figure out where the field starts and stops }
- if StopCol <= 0 then
- EndCol := Scr.CurrCols + StopCol
- else
- EndCol := StopCol;
- if InputRow <= 0 then
- R := Scr.CurrRows + InputRow
- else
- R := InputRow;
- if (R = Scr.CurrRows) and (ECol = Scr.CurrCols) then
- Dec(EndCol);
- ECol := EndCol;
- InputArea.Init(SCol, R, ECol, R, Colors.InputColor);
- InputArea.Clear;
- if StartCursor = 0 then
- CursorPos := Succ(Length)
- else
- CursorPos := StartCursor;
- Finished := False;
- InsMode := True;
- Cursor := Scr.InsCursor;
- Start := Max(Longint(CursorPos) - ECol - SCol + 2, 1);
- repeat
- if CursorPos > Length then
- ECol := EndCol;
- if (CursorPos < Start) or (CursorPos > Start + ECol - SCol) then
- Start := Max(Longint(CursorPos) - ECol + SCol, 1);
- if (Start = 2) and (SCol <> StartCol) then
- begin
- SCol := StartCol;
- Start := 1;
- end;
- if Start > 1 then
- begin
- if SCol = StartCol then
- begin
- Inc(Start);
- SCol := Succ(StartCol); { Text is off left side of line }
- end;
- end
- else
- SCol := StartCol;
- if Length > Start + ECol - SCol then
- begin
- if ECol = EndCol then
- begin
- if SCol <> StartCol then
- Inc(Start);
- ECol := Pred(EndCol); { Text is off right side of line }
- end;
- end
- else
- ECol := EndCol;
- GotoXY(StartCol, R);
- if SCol <> StartCol then { Text is off left side of line }
- WriteColor(LeftInputArrow, Colors.InputArrowColor);
- WriteColor(LeftJustStr(InputData^.Copy(Start, Succ(ECol - SCol)),
- Succ(ECol - SCol)), Colors.InputColor);
- if ECol <> EndCol then { Text is off right side of line }
- WriteColor(RightInputArrow, Colors.InputArrowColor);
- GotoXY(CursorPos - Start + SCol, R);
- SetCursor(Cursor);
- Ch := GetKey;
- SetCursor(NoCursor);
- case Ch of
- Ord(' ')..Ord('~') : begin
- if not (InsMode and (Length = MaxInputLen)) then
- begin
- if UCase then
- Ch := Ord(UpCase(Chr(Ch)));
- if InsMode or (CursorPos > Length) then
- Good := Insert(Chr(Ch), CursorPos)
- else begin
- Good := True;
- Change(Chr(Ch), CursorPos);
- end;
- if Good then
- Inc(CursorPos);
- end;
- end;
- HomeKey : CursorPos := 1;
- EndKey : CursorPos := Succ(Length);
- BS : begin
- if CursorPos > 1 then
- begin
- Delete(Pred(CursorPos), 1);
- Dec(CursorPos);
- end;
- end;
- DelKey : begin
- if CursorPos <= Length then
- Delete(CursorPos, 1);
- end;
- LeftKey : begin
- if CursorPos > 1 then
- Dec(CursorPos);
- end;
- RightKey : begin
- if CursorPos <= Length then
- Inc(CursorPos);
- end;
- InsKey : begin
- InsMode := not InsMode;
- if InsMode then
- Cursor := Scr.InsCursor
- else
- Cursor := Scr.OldCursor;
- end;
- CtrlLeftKey : begin { Move back one word }
- if (CursorPos > 1) and (Data^[CursorPos] <> ' ') then
- Dec(CursorPos);
- while (CursorPos > 1) and (Data^[CursorPos] = ' ') do
- Dec(CursorPos);
- while (CursorPos > 1) and (Data^[Pred(CursorPos)] <> ' ') do
- Dec(CursorPos);
- end;
- CtrlRightKey : begin { Move forward one word }
- while (CursorPos <= Length) and (Data^[CursorPos] <> ' ') do
- Inc(CursorPos);
- while (CursorPos <= Length) and (Data^[CursorPos] = ' ') do
- Inc(CursorPos);
- end;
- ESC : begin
- ClearInput;
- Quit := True;
- Finished := True;
- end;
- CR : Finished := True;
- end; { case }
- until Finished;
- end; { with }
- end; { InputField.Edit }
-
- procedure InputField.ClearInput;
- { Makes the input field data a null long string }
- var
- Good : Boolean;
- begin
- Good := InputData^.FromString('');
- end; { InputField.ClearInput }
-
- function ReadString(Prompt : String; Len : Word;
- var ESCPressed : Boolean) : String;
- { Read a string from the input area }
- var
- I : InputField;
- begin
- with I do
- begin
- if not Init(Length(Prompt) + 3, 0, -1, Len, NotUpper) then
- begin
- ESCPressed := True;
- ReadString := '';
- end;
- WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
- Edit(0);
- ReadString := InputData^.ToString;
- ESCPressed := GetQuit;
- Done;
- end; { with }
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
- end; { ReadString }
-
- function GetLegalChar(Prompt : String; Legal : CharSet;
- var ESCPressed : Boolean) : Char;
- { Read a chanracter from the input area, only reading certain ones }
- var
- Ch : Char;
- begin
- WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
- Ch := GetKeyChar(Legal);
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
- GetLegalChar := Ch;
- end; { GetLegalChar }
-
- function GetYesNo(Prompt : String; var ESCPressed : Boolean) : Boolean;
- { Prints a "Yes/No" prompt, allowing the user to type Y or N to answer the
- question }
- var
- Ch : Char;
- begin
- WriteXY(Prompt + ' (' + YesNo + ')?', 1, Pred(Scr.CurrRows),
- Colors.PromptColor);
- Ch := GetKeyChar(LegalYesNo);
- ESCPressed := Ch = Chr(ESC);
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
- GetYesNo := Ch = 'Y';
- end; { GetYesNo }
-
- function GetNumber(Prompt : String; Low, High : Longint;
- var Result : Boolean) : Longint;
- { Prompts for a numeric value within a certain range }
- var
- I : InputField;
- S : String;
- Error : Integer;
- L : Longint;
- begin
- with I do
- begin
- if not Init(Length(Prompt) + 3, 0, -1,
- Max(Length(NumToString(Low)),
- Length(NumToString(High))), NotUpper) then
- begin
- Result := False;
- GetNumber := 0;
- Exit;
- end;
- WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
- repeat
- Edit(0);
- S := InputData^.ToString;
- if (not GetQuit) and (S <> '') then
- begin
- Val(S, L, Error);
- Result := (Error = 0) and (L >= Low) and (L <= High);
- if not Result then
- Scr.PrintError(ErrNumberError1 + NumToString(Low) +
- ErrNumberError2 + NumToString(High));
- end
- else begin
- Result := False;
- L := 0;
- end;
- until Result or (S = '');
- Done;
- end; { with }
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
- GetNumber := L;
- end; { GetNumber }
-
- end.
-