home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
tptools.zip
/
FIRSTED.ZIP
/
EDSCRN2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-12-21
|
14KB
|
456 lines
{ EDSCRN2.PAS
ED 4.0
Copyright (c) 1985, 87 by Borland International, Inc. }
{$I eddirect.inc}
unit EdScrn2;
{-Screen updating routines specific to FirstEd}
interface
uses
crt, {Basic video operations - standard unit}
Dos, {DOS calls - standard unit}
Errors, {Runtime error handler}
EdVars, {Global types and declarations}
EdScrn1, {Fast screen writing routines}
EdString, {String primitives}
EdPtrOp, {Primitive pointer operations}
EdCmds, {Maps keystrokes to commands}
int24, {DOS critical error handler}
Message, {Message system}
EdUser; {User keyboard input, line editing and error reporting}
procedure EdUpdateStatusLine(W : PwinDesc);
{-Update window status line for specified window}
procedure EdUpdateLine(P : PlineDesc; Row, LeftEdge, LeftCol : Integer; Attribs : Boolean);
{-Update one row of the screen}
procedure EdBiosScroll;
{-Use the IBM BIOS to scroll up or down one line rapidly}
procedure EdUpdateScreen;
{-Update physical screen}
procedure EdHighlightScreen(Col1, Col2 : Integer; Attr : Byte; WaitForKey : Boolean);
{-Change attribute of a screen string and wait for keystroke}
procedure EdInterruptibleDelay(Time : Integer);
{-Generate a delay which can be interrupted by a keystroke}
{==========================================================================}
implementation
const
{Positions on Window status line}
NameCol = 4; {Uses columns 04-16}
LineTitleCol = 22; {22-26}
LineNumCol = 27; {27-32}
ColTitleCol = 33; {33-36}
ColNumCol = 37; {37-40}
ByteTitleCol = 41; {41-45}
ByteNumCol = 46; {46-49}
InsertFlagCol = 55; {55-60, or Overwrite}
IndentFlagCol = 64; {64-69}
ModifiedFlagCol = 75; {75-78}
{Strings for Window status line}
StLine : string[4] = 'Line';
StCol : string[3] = 'Col';
StByte : string[4] = 'Byte';
StAi : string[6] = 'Indent';
StIns : string[6] = 'Insert';
StOvr : string[6] = 'Over';
StSave : string[4] = 'Save';
{***}
procedure EdUpdateStatusLine(W : PwinDesc);
{-Update window status line for specified window}
var
St : VarString;
begin {EdUpdateStatusLine}
if EdKeyInterrupt then
Exit;
with W^ do begin
{Initialize the screen attribute of the status line}
FillChar(Aline, PhyScrCols, ScreenAttr[BordColor]);
{Fill status line with blanks}
FillChar(Tline[0], PhyScrCols, Blank);
{Print the file name}
St := EdEndOfPath(Filename);
Move(St[1], Tline[NameCol], Length(St));
{Line number}
Move(StLine[1], Tline[LineTitleCol], Ord(StLine[0]));
Str(Clineno:1, St);
Move(St[1], Tline[LineNumCol], Length(St));
{Column number}
Move(StCol[1], Tline[ColTitleCol], Ord(StCol[0]));
Str(ColNo:1, St);
Move(St[1], Tline[ColNumCol], Length(St));
{Byte number}
Move(StByte[1], Tline[ByteTitleCol], Ord(StByte[0]));
Str(TcharNo, St);
Move(St[1], Tline[ByteNumCol], Length(St));
{Insert/overtype symbol}
if InsertFlag then
Move(StIns[1], Tline[InsertFlagCol], Ord(StIns[0]))
else
Move(StOvr[1], Tline[InsertFlagCol], Ord(StOvr[0]));
{Autoindent mode symbol}
if AI then
Move(StAi[1], Tline[IndentFlagCol], Ord(StAi[0]));
{File modified symbol}
if Modified then
Move(StSave[1], Tline[ModifiedFlagCol], Ord(StSave[0]));
{Write it to the screen}
EdWrline(FirstLineNo);
end;
end; {EdUpdateStatusLine}
{***}
procedure EdUpdateLine(P : PlineDesc; Row, LeftEdge, LeftCol : Integer; Attribs : Boolean);
{-Update one row of the screen}
var
Fl, ScrCols : Integer;
procedure EdBuildLineNoAttribs(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer; Attr : Byte);
{-Build TLINE and ALINE without text attribute display}
var
Len : Integer;
begin {EdBuildLineNoAttribs}
{Get the displayed part of the text}
Len := Succ(EdTextLength(P)-LeftEdge);
if Len > 0 then begin
if Len >= ScrCols then begin
{Line covers full width of screen}
Move(P^.Txt^[LeftEdge], Tline[LeftCol], ScrCols);
FillChar(Aline[LeftCol], ScrCols, Attr);
end else begin
{Line covers part of screen, right fill with blanks}
Move(P^.Txt^[LeftEdge], Tline[LeftCol], Len);
FillChar(Tline[LeftCol+Len], ScrCols-Len, Blank);
FillChar(Aline[LeftCol], Len, Attr);
FillChar(Aline[LeftCol+Len], ScrCols-Len, ScreenAttr[TxtColor]);
end;
end else begin
{Text scrolled off left edge of screen}
FillChar(Tline[LeftCol], ScrCols, Blank);
FillChar(Aline[LeftCol], ScrCols, ScreenAttr[TxtColor]);
end;
end; {EdBuildLineNoAttribs}
procedure EdShowBlockMarkers(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer);
{-Set up attributes for block marked lines}
var
M, N : Integer;
Attr : Byte;
begin {EdShowBlockMarkers}
Attr := ScreenAttr[BlockColor];
{Special cases for partially marked lines}
if P = Blockfrom.Line then begin
M := Blockfrom.Col-LeftEdge;
if (P = Blockto.Line) then begin
{Block is totally within one line}
if M <= ScrCols then begin
{Block shows on screen}
if M <= 0 then
M := 0;
N := Blockto.Col-LeftEdge;
if N > ScrCols then
{Right edge of block off of screen}
FillChar(Aline[M+LeftCol], ScrCols-M, Attr)
else begin
if N < 0 then
N := 0;
FillChar(Aline[M+LeftCol], N-M, Attr);
end;
end;
end else begin
{First line of block}
if M <= ScrCols then begin
{Block shows on screen}
if M <= 0 then
M := 0;
FillChar(Aline[M+LeftCol], ScrCols-M, Attr);
end;
end;
end else if P = Blockto.Line then begin
{Last line of block}
N := Blockto.Col-LeftEdge;
if N > ScrCols then
{Whole visible line in block}
FillChar(Aline[LeftCol], ScrCols, Attr)
else if N > 0 then
FillChar(Aline[LeftCol], N, Attr);
end else
{Line fully in block}
FillChar(Aline[LeftCol], ScrCols, Attr);
end; {EdShowBlockMarkers}
procedure EdShowTextMarkers(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer);
{-Display the text markers}
var
M, N : Integer;
begin {EdShowTextMarkers}
for M := 0 to MaxMarker do
with Marker[M] do
if P = Line then begin
{Change the marked position to the mark number in border color}
N := Col-LeftEdge;
if (N >= 0) and (N < ScrCols) then begin
{Change the displayed character}
Tline[N+LeftCol] := Chr(M+Ord('0'));
{Change the attribute}
Aline[N+LeftCol] := Chr(ScreenAttr[BordColor]);
end;
end;
end; {EdShowTextMarkers}
begin {EdUpdateLine}
{Screen columns available for text display}
ScrCols := PhyScrCols-LeftCol;
if EdPtrIsNil(P) then begin
{Blank line at end of file}
FillChar(Tline[LeftCol], ScrCols, Blank);
FillChar(Aline[LeftCol], ScrCols, ScreenAttr[TxtColor]);
Fl := 0;
end else begin
Fl := P^.Flags;
EdBuildLineNoAttribs(P, LeftEdge, LeftCol, ScrCols, ScreenAttr[TxtColor]);
{Show block markers}
if (Fl and InBlock) <> 0 then
EdShowBlockMarkers(P, LeftEdge, LeftCol, ScrCols);
{Display text markers}
if (Fl and InMark) <> 0 then
EdShowTextMarkers(P, LeftEdge, LeftCol, ScrCols);
end;
{Write the line to screen after translating control characters}
EdWrlineCtrl(Row);
end; {EdUpdateLine}
procedure EdUpdatewindow(W : PwinDesc);
{-Update a single window on the screen}
var
P : PlineDesc;
I, R, Le, Lc : Integer;
Attribs : Boolean;
begin {EdUpdateWindow}
with W^ do begin
Le := LeftEdge;
Lc := LeftCol;
Attribs := AT;
I := 0;
{Update from one past the current line to bottom of window}
P := CurLine^.FwdLink;
for R := (FirstTextNo+LineNo) to LastLineNo do begin
EdUpdateLine(P, R, Le, Lc, Attribs);
Inc(I);
{Check every 4th line for a keyboard interrupt}
if I and 3 = 0 then
if EdKeyInterrupt then
Exit;
if EdPtrNotNil(P) then
EdFwdPtr(P);
end;
{Now update from top of window to current line}
P := TopLine;
for R := FirstTextNo to Pred(FirstTextNo+LineNo) do begin
EdUpdateLine(P, R, Le, Lc, Attribs);
Inc(I);
if I and 3 = 0 then
if EdKeyInterrupt then
Exit;
if EdPtrNotNil(P) then
EdFwdPtr(P);
end;
end;
end; {EdUpdateWindow}
procedure EdBiosScroll;
{-use the IBM BIOS to scroll up or down one line rapidly}
var
P : PlineDesc;
R : Integer;
Delta : Integer;
regs : registers;
begin {EdBiosScroll}
with CurWin^ do begin
{Scroll the current window up or down via BIOS call}
with regs do begin
Al := 1;
if FullScroll < 0 then begin
Ah := 6;
Delta := 1;
end else begin
Ah := 7;
Delta := -1;
end;
Ch := Pred(FirstTextNo);
Cl := 0;
Dh := Pred(LastLineNo);
dl := 79;
Bh := lo(ScreenAttr[TxtColor]);
end;
intr($10, regs);
{Write the newly scrolled line}
if FullScroll > 0 then
EdUpdateLine(TopLine, FirstTextNo, LeftEdge, LeftCol, AT)
else begin
{Get pointer to last line on screen}
P := TopLine;
for R := FirstTextNo to Pred(LastLineNo) do
if EdPtrNotNil(P) then
EdFwdPtr(P);
EdUpdateLine(P, LastLineNo, LeftEdge, LeftCol, AT);
end;
end;
if UpdateCursor then
EdUpdateCursor;
FullScroll := FullScroll+Delta;
end; {EdBiosScroll}
procedure EdUpdateScreen;
{-Update physical screen}
var
W : PwinDesc;
begin {EdUpdateScreen}
{Update the current line}
with CurWin^ do
EdUpdateLine(CurLine, Pred(FirstTextNo+LineNo), LeftEdge, LeftCol, AT);
{Get out if keys are waiting}
if EdKeyInterrupt then
Exit;
{Update the rest of the screen window by window, starting with current}
W := CurWin;
repeat
EdUpdatewindow(W);
if EdKeyInterrupt then
Exit;
EdUpdateStatusLine(W);
EdFwdPtr(W);
until W = CurWin;
{Update the command line}
EdUpdateCmdLine;
{Indicate that the screen has been fully updated}
UpdateScreen := False;
FullScroll := 0;
IntrFlag := Interr;
end; {EdUpdateScreen}
{***}
procedure EdHighlightScreen(Col1, Col2 : Integer; Attr : Byte; WaitForKey : Boolean);
{-Change attribute of a screen string and wait for keystroke}
var
Dis, Len : Integer;
begin {EdHighLightScreen}
with CurWin^ do begin
{Horizontal scroll to display both ends of highlighted range}
if Col1 <= LeftEdge then begin
if Col1 > 1 then
LeftEdge := Pred(Col1)
else
LeftEdge := Col1;
end else if Col2 >= (LeftEdge+PhyScrCols-2-LeftCol) then
LeftEdge := Col2-PhyScrCols+LeftCol+2;
{Update the screen}
EdUpdateCursor;
EdZapPromptLine;
EdUpdateScreen;
{Change attribute of selected string}
Dis := Succ(Col1-LeftEdge+LeftCol);
Len := Succ(Col2-Col1);
if Pred(Dis+Len) > DefNoCols then
{Avoid overwriting edge of screen}
Len := Succ(DefNoCols-Dis);
EdChangeAttribute(Len, Pred(FirstTextNo+LineNo), Dis, Attr);
end;
if WaitForKey then
{Wait for a keystroke}
repeat
until Abortcmd or EdKeyPressed;
end; {EdHighLightScreen}
procedure EdInterruptibleDelay(Time : Integer);
{-Generate a delay which can be interrupted by a keystroke}
var
Total : Integer;
begin {EdInterruptibleDelay}
EdUpdateScreen;
Total := 0;
while (Total < Time) do begin
if EdKeyPressed or Abortcmd then
Exit;
Delay(5);
Total := Total+5;
end;
end; {EdInterruptibleDelay}
end.