home *** CD-ROM | disk | FTP | other *** search
- { MSSCRN2.PAS
- MS 4.0
- Copyright (c) 1985, 87 by Borland International, Inc. }
-
- {$I msdirect.inc}
-
- unit MsScrn2;
- {-Screen updating routines specific to MicroStar}
-
- interface
-
- uses
- Crt, {Basic video operations - standard unit}
- Dos, {DOS interface - standard unit}
- Errors, {Runtime error handler}
- MsVars, {Global types and declarations}
- MsScrn1, {Fast screen writing routines}
- MsString, {String primitives}
- MsPtrOp, {Primitive pointer operations}
- EscSeq, {Returns text string for extended scan codes}
- MsCmds, {Maps keystrokes to commands}
- Int24, {DOS critical error handler}
- Message, {Message system}
- MsUser, {User keyboard input, line editing and error reporting}
- MsBack; {Background processes}
-
- 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 EdUpdatewindow(W : Pwindesc);
- {-Update a single window on 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}
-
- function EdCmdAccessible(Menu : Menuptr; Sub : Byte) : Boolean;
- {-Return true if command is currently accessible from the menu}
-
- procedure EdDrawItem(Menu : Menuptr; Sub : Byte);
- {-Draw menu item "sub" of the chosen menu}
-
- procedure EdUndrawMenu(Menu : Menuptr);
- {-remove the menu and its children from the screen}
-
- procedure EdDrawMenu(Menu : Menuptr);
- {-Draw a menu and its selected children on the screen}
-
- procedure EdEraseMenus;
- {-Remove the menu system from the screen}
-
- {==========================================================================}
-
- implementation
-
- const
- {Positions on Window status line}
- ZoomFlagCol = 0; {Uses columns 00-03}
- NameCol = 4; {04-16}
- PercentCol = 17; {17-21}
- LineTitleCol = 22; {22-26}
- LineNumCol = 27; {27-32}
- ColTitleCol = 33; {33-36}
- ColNumCol = 37; {37-40}
- PageTitleCol = 41; {41-45}
- PageNumCol = 46; {46-49}
- InsertFlagCol = 50; {50-56, or Overwrite}
- IndentFlagCol = 57; {57-63}
- WordWrapFlagCol = 64; {64-68, or Margin Release}
- JustifyFlagCol = 69; {69-76}
- MacroFlagCol = 77; {77-79, or Printing, or Attribute}
-
- {Strings for Window status line}
- StLine : string[4] = 'Line';
- StCol : string[3] = 'Col';
- Stai : string[6] = 'Indent';
- StIns : string[6] = 'Insert';
- StOvr : string[6] = 'Over';
- StPage : string[4] = 'Page';
- StMr : string[3] = ^P'R'^Q;
- StPr : string[3] = ^P'P'^Q;
- StWw : string[4] = 'Wrap';
- StRel : string[12] = 'Marg Release';
- StJu : string[7] = 'Justify';
- StZoom : string[3] = ^P'Z'^Q;
- StCarat : string[3] = '^ ';
-
- procedure EdUpdateStatusLine(W : Pwindesc);
- {-Update window status line}
- var
- St : VarString;
- Ch : Char;
- Pnum : Integer;
- Percent : Integer;
-
- procedure EdUpdateTabLine(W : Pwindesc);
- {-Write the tab line to the screen}
- const
- DashChar : Char = #196;
- TabChar : Char = #31;
- LeftChar : Char = 'L';
- WrapChar : Char = #16;
- RightChar : Char = 'R';
- var
- T, L, I, ScrCols : Integer;
- Tpos : Integer;
-
- procedure EdBuildTabLine(Tpos : Integer; C : Char);
- {-Set the tab display to the specified character}
-
- begin {EdBuildTabLine}
- if (Tpos >= 0) and (Tpos < ScrCols) then
- Tline[Tpos] := C;
- end; {EdBuildTabLine}
-
- begin {EdUpdateTabLine}
-
- with W^ do begin
-
- {Initialize the text line}
- FillChar(Tline, PhyScrCols, DashChar);
- L := Leftedge;
- ScrCols := PhyScrCols-Leftcol;
-
- {Fill in the tab markers}
- I := 1;
- repeat
- T := Tabs[I];
- Tpos := T-L;
- if not(WW) or ((T >= Lmargin) and (T <= Rmargin)) then
- EdBuildTabLine(Leftcol+Tpos, TabChar);
- Inc(I);
- until (I > MaxNumTabs) or (Tpos >= ScrCols);
-
- if WW then begin
- {Display the margins}
- EdBuildTabLine(Leftcol-L+Wmargin, WrapChar);
- EdBuildTabLine(Leftcol-L+Lmargin, LeftChar);
- EdBuildTabLine(Leftcol-L+Rmargin, RightChar);
- end;
-
- {Write it to screen}
- EdWrline(Succ(Firstlineno));
-
- end;
- end; {EdUpdateTabLine}
-
- 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, PhyScrCols, Blank);
-
- {Display the zoom marker}
- if Zoomed then
- Move(StZoom[1], Tline[ZoomFlagCol], Length(StZoom));
-
- {Print the file name}
- St := EdEndOfPath(Filename);
- Move(St[1], Tline[NameCol], Length(St));
-
- {Relative position in file}
- if (Crelpos >= 1000) then
- {Only show 100 at very end of file}
- St := '100'
- else if (Crelpos > 990) then
- St := '99'
- else if (Crelpos > 0) and (Crelpos < 10) then
- {Only show 0 at very beginning of file}
- St := '1'
- else begin
- {Round to nearest percent}
- Percent := Crelpos div 10;
- if Crelpos mod 10 >= 5 then
- Inc(Percent);
- Str(Percent, St);
- end;
- Move(St[1], Tline[PercentCol], Length(St));
- Tline[PercentCol+Length(St)] := '%';
-
- {Line number}
- Move(StLine[1], Tline[LineTitleCol], Length(StLine));
- if Clineno <= 0 then
- St := '..'
- else if PA and (Clineno > PageLen) then
- St := '..'
- else
- Str(Clineno:1, St);
- Move(St[1], Tline[LineNumCol], Length(St));
-
- {Column number}
- Move(StCol[1], Tline[ColTitleCol], Length(StCol));
- Str(Colno:1, St);
- Move(St[1], Tline[ColNumCol], Length(St));
-
- {Page number}
- if PA then begin
- {Show current page number}
- Move(StPage[1], Tline[PageTitleCol], Length(StPage));
- Pnum := EdGetPageNum(Curline);
- if Pnum <= 0 then
- St := '..'
- else
- Str(Pnum, St);
- Move(St[1], Tline[PageNumCol], Length(St));
- end;
-
- {Insert/overtype symbol}
- if Insertflag then
- Move(StIns[1], Tline[InsertFlagCol], Length(StIns))
- else
- Move(StOvr[1], Tline[InsertFlagCol], Length(StOvr));
-
- {Autoindent mode symbol}
- if AI then
- Move(Stai[1], Tline[IndentFlagCol], Length(Stai));
-
- {Word wrap and Justify symbols}
- if WW then
- if MarginRelease then
- Move(StRel[1], Tline[WordWrapFlagCol], Length(StRel))
- else begin
- Move(StWw[1], Tline[WordWrapFlagCol], Length(StWw));
- if JU then
- Move(StJu[1], Tline[JustifyFlagCol], Length(StJu));
- end;
-
- if Recording then
- {Macro recording symbol}
- Move(StMr[1], Tline[MacroFlagCol], Length(StMr))
- else if Printing then
- {Printing symbol}
- Move(StPr[1], Tline[MacroFlagCol], Length(StPr));
-
- if AT then
- if (W = Curwin) and (Colno <= Curline^.Bufflen) then begin
- {Character type symbol - distinguishes control characters when hidden}
- Ch := Curline^.Txt^[Colno];
- if Ch < Blank then begin
- StCarat[2] := Chr(Ord(Ch)+64);
- Move(StCarat[1], Tline[MacroFlagCol], 3);
- end;
- end;
-
- {Write it to the screen}
- EdWrline(Firstlineno);
-
- {Write the tab line if selected}
- if TL then
- EdUpdateTabLine(W);
-
- end;
- end; {EdUpdateStatusLine}
-
- {***}
- procedure EdUpdateLine(P : PlineDesc; Row, Leftedge, Leftcol : Integer; Attribs : Boolean);
- {-Update one row of the screen}
- var
- Fl : Word;
- 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 EdBuildLineAttribs(P : PlineDesc; Leftedge,
- Leftcol, ScrCols : Integer;
- Fl : Word);
- {-Build TLINE and ALINE when attributes are activated}
- var
- Attr, FontByte : Byte;
- Ipos, Epos, Opos, Len : Integer;
- Ch : Char;
- C : PrintCommandtype;
-
- begin {EdBuildLineAttribs}
-
- {Get the font descriptor at start of line, computed by a background process}
- FontByte := P^.Font;
- Attr := FontAttribute[FontByte];
-
- if (Fl and NewAttr) = 0 then
-
- {Line is all of one attribute}
- EdBuildLineNoAttribs(P, Leftedge, Leftcol, ScrCols, Attr)
-
- else begin
-
- {Line contains font toggles}
-
- {Build the line character by character}
- Len := EdTextLength(P);
- Opos := Leftcol;
- Ipos := 1;
- Epos := 0;
-
- with P^ do
- while (Opos < PhyScrCols) do begin
-
- if Ipos <= Len then begin
- {Evaluate next character from text line}
- Ch := Txt^[Ipos];
- C := PrintMap[Ch];
- end else begin
- {Beyond end of line, use nominal attribute}
- Ch := Blank;
- Attr := ScreenAttr[TxtColor];
- C := PrtNone;
- end;
-
- if C = PrtNone then begin
- {Fill in text and attribute lines}
- Inc(Epos);
- if Epos >= Leftedge then begin
- Tline[Opos] := Ch;
- Aline[Opos] := Chr(Attr);
- Inc(Opos);
- end;
- end else begin
- {Change font attribute}
- EdUpdateFont(C, FontByte);
- Attr := FontAttribute[FontByte];
- end;
-
- Inc(Ipos);
-
- end;
- end;
- end; {EdBuildLineAttribs}
-
- procedure EdShowBlockMarkers(P : PlineDesc; Leftedge, Leftcol, ScrCols : Integer; Attribs : Boolean);
- {-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 := EdComputeEffectiveColNo(Attribs, Blockfrom.Line, 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 := EdComputeEffectiveColNo(Attribs, Blockto.Line, Blockto.Col)-Leftedge;
- if N > ScrCols then
- {Right edge of block off of screen}
- FillChar(Aline[M+Leftcol], ScrCols-M, Attr)
- else begin
- if Attribs then
- if PrintMap[P^.Txt^[Blockto.Col]] <> PrtNone then
- N := Succ(N);
- 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 := EdComputeEffectiveColNo(Attribs, Blockto.Line, Blockto.Col)-Leftedge;
- if N > ScrCols then
- {Whole visible line in block}
- FillChar(Aline[Leftcol], ScrCols, Attr)
- else if N > 0 then begin
- if Attribs then
- if PrintMap[P^.Txt^[Blockto.Col]] <> PrtNone then
- N := Succ(N);
- FillChar(Aline[Leftcol], N, Attr);
- end;
-
- end else
-
- {Line fully in block}
- FillChar(Aline[Leftcol], ScrCols, Attr);
-
- end; {EdShowBlockMarkers}
-
- procedure EdShowTextMarkers(P : PlineDesc; Leftedge, Leftcol, ScrCols : Integer; Attribs : Boolean);
- {-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 := EdComputeEffectiveColNo(Attribs, P, 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}
-
- procedure EdShowPageMarkers(Fl, Leftcol : Integer);
- {-Display page breaks}
-
- begin {EdShowPageMarkers}
- FillChar(Aline, Leftcol, ScreenAttr[BordColor]);
- {Insert new page marker}
- if (Fl and NewPage) <> 0 then
- FillChar(Tline, Leftcol, #175)
- else
- FillChar(Tline, Leftcol, Blank);
- end; {EdShowPageMarkers}
-
- 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;
-
- if Attribs then
- EdBuildLineAttribs(P, Leftedge, Leftcol, ScrCols, Fl)
- else
- EdBuildLineNoAttribs(P, Leftedge, Leftcol, ScrCols, ScreenAttr[TxtColor]);
-
- {Show block markers}
- if (Fl and InBlock) <> 0 then
- EdShowBlockMarkers(P, Leftedge, Leftcol, ScrCols, Attribs);
-
- {Display text markers}
- if (Fl and InMark) <> 0 then
- EdShowTextMarkers(P, Leftedge, Leftcol, ScrCols, Attribs);
-
- end;
-
- {Display pagination marks}
- if Leftcol <> 0 then
- EdShowPageMarkers(Fl, Leftcol);
-
- {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
- regs : registers;
- P : PlineDesc;
- R : Integer;
- Delta : Integer;
-
- begin {EdBiosScroll}
- with Curwin^ do begin
-
- {Avoid a snake of solid cursor appearing during fast scroll}
- if SolidCursor then
- EdEraseSolidCursor;
-
- {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
- if W^.Visible then begin
- EdUpdatewindow(W);
- if EdKeyInterrupt then
- Exit;
- EdUpdateStatusLine(W);
- end;
- 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, C1, C2, Len : Integer;
- CenterWindow, Cwb, Cwt : Integer;
- GenLine : Boolean;
-
- begin {EdHighLightScreen}
-
- {Remove menus from screen}
- if EdPtrNotNil(CurrMenu) then begin
- EdEraseMenus;
- ExitMenu := True;
- end;
-
- with Curwin^ do begin
-
- {Compute effective column numbers on display}
- C1 := EdComputeEffectiveColNo(AT, Curline, Col1);
- C2 := EdComputeEffectiveColNo(AT, Curline, Col2);
-
- {Horizontal scroll}
- if C1 <= Leftedge then begin
- if C1 > 1 then
- Leftedge := Pred(C1)
- else
- Leftedge := C1;
- end else if C2 >= (Leftedge+PhyScrCols-2-Leftcol) then
- Leftedge := C2-PhyScrCols+Leftcol+2;
-
- {Vertical scroll to keep highlight somewhat centered in window}
- CenterWindow := Succ((Lastlineno-Firsttextno) shr 1);
- Cwt := CenterWindow-(CenterWindow shr 1);
- Cwb := CenterWindow+(CenterWindow shr 1);
- while EdPtrNotNil(TopLine^.Fwdlink) and (Lineno > Cwb) do begin
- EdFwdPtr(TopLine);
- Dec(Lineno);
- end;
- while EdPtrNotNil(TopLine^.Backlink) and (Lineno < Cwt) do begin
- EdBackPtr(TopLine);
- Inc(Lineno);
- end;
-
- {Update the screen}
- EdUpdateCursor;
- EdZapPromptLine;
- EdUpdateScreen;
-
- {Change attribute of selected string}
- Dis := Succ(C1-Leftedge+Leftcol);
- Len := Succ(C2-C1);
- if Pred(Dis+Len) > DefNoCols then
- {Avoid overwriting edge of screen}
- Len := Succ(DefNoCols-Dis);
- EdChangeAttribute(Len, Pred(Firsttextno+Lineno), Dis, Attr);
- if SolidCursor then
- EdDrawSolidCursor;
-
- end;
-
- if WaitForKey then begin
- {Wait for a keystroke}
- GenLine := True;
- repeat
- if GenLine then begin
- EdGenLineOne(Curwin);
- if UpdateScreen then begin
- EdUpdateStatusLine(Curwin);
- UpdateScreen := False;
- GenLine := False;
- end;
- end;
- if Printing then
- EdPrintNext(PrintChars);
- until Abortcmd or EdKeyPressed;
- end;
- 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}
-
- function EdCmdAccessible(Menu : Menuptr; Sub : Byte) : Boolean;
- {-Return true if command is currently accessible from the menu}
-
- begin {EdCmdAccessible}
- if WindowCount = 0 then
- EdCmdAccessible := (Menu^.SubMenus^[Sub].Command in MainCommands)
- else
- EdCmdAccessible := True;
- end; {EdCmdAccessible}
-
- procedure EdDrawItem(Menu : Menuptr; Sub : Byte);
- {-Draw menu item "sub" of the chosen menu}
- const
- {Flags used for status display in menu system}
- NoStat = 0; {Entry displays no status}
- BoolStat = 1; {Entry displays boolean - ON/OFF - status}
- NumStat = 2; {Entry displays numeric status}
- StrStat = 3; {Entry displays string status}
- var
- R, C, Len : Byte;
- S : VarString;
- Orient : MenuOrientation;
-
- procedure EdEvaluateSpecial(C : CommandType; Stat : Byte; var S : VarString);
- {-Modify s to contain special status info}
- var
- Ss : VarString;
- BoolVal : Boolean;
- NumVal : Integer;
-
- function EdTruncateString(S : Filepath; Maxlen : Integer) : Filepath;
- {-Truncate a string if it exceeds maxlen}
-
- begin {EdTruncateString}
- if Length(S) <= Maxlen then
- EdTruncateString := S
- else
- EdTruncateString := Copy(S, 1, Maxlen-3)+'...';
- end; {EdTruncateString}
-
- begin {EdEvaluateSpecial}
- with Curwin^ do
- case Stat of
-
- BoolStat : {Status is a boolean}
- begin
- case C of
- CmdToggleInsert : BoolVal := Insertflag;
- CmdToggleWordWrap : BoolVal := WW;
- CmdToggleAutoindent : BoolVal := AI;
- CmdToggleTabLine : BoolVal := TL;
- CmdToggleJustify : BoolVal := JU;
- CmdTogglePaginate : BoolVal := PA;
- CmdToggleAttribute : BoolVal := AT;
- CmdToggleTabMode : BoolVal := FT;
- CmdToggleTabExpansion : BoolVal := ReadExpandTabs;
- CmdZoomWindow : BoolVal := Zoomed;
- CmdToggleStripMode : BoolVal := SaveStripMode;
- CmdToggleKeyHelp : BoolVal := SaveKeyHelpMode;
- CmdToggleRetraceMode : BoolVal := RetraceMode;
- CmdToggleSolidCursor : BoolVal := SolidCursor;
- CmdToggleEga43Line : BoolVal := Ega43lineMode;
- CmdToggleInitZoomState : BoolVal := SaveInitZoomState;
- CmdToggleWriteTabs : BoolVal := WriteCompressTabs;
- CmdToggleCompressWrap : BoolVal := CW;
- end;
- Ss := OnOff[BoolVal];
- end;
-
- NumStat : {Status is a number}
- begin
- case C of
- CmdSetLeftMargin : NumVal := Lmargin;
- CmdSetRightMargin : NumVal := Rmargin;
- CmdSetTopMargin : NumVal := Tmargin;
- CmdSetBotMargin : NumVal := Bmargin;
- CmdSetPageLength : NumVal := PageLen;
- CmdSetTabSize : NumVal := SaveTabSize;
- CmdSetUndoLimit : NumVal := UndoLimit;
- end;
- Str(NumVal, Ss);
- end;
-
- StrStat : {Status is a string}
- case C of
- CmdGetDefaultExtension : Ss := DefExtension;
- CmdSetSupportPath : Ss := EdTruncateString(SaveSupportPath, 14);
- end;
- end;
-
- {Right justify the substring in the already padded main string}
- Move(Ss[1], S[Length(S)-Length(Ss)], Length(Ss));
- end; {EdEvaluateSpecial}
-
- begin {EdDrawItem}
-
- {Get the orientation of the current menu}
- Orient := MenuDesc[Menu^.MenuLev].Orientation;
-
- with Menu^, SubMenus^[Sub] do begin
-
- {Copy the prompt to a work string}
- Len := Ord(Prompt^[0]);
- R := YPosn;
- C := XPosn;
-
- {Pad with blanks left and right}
- if Orient = Vertical then begin
- S[0] := Chr(XSize);
- R := R+Doffset;
- end else begin
- S[0] := Chr(Len+2);
- C := C+Doffset;
- end;
-
- FillChar(S[1], Length(S), Blank);
- Move(Prompt^[1], S[2], Len);
-
- if StatVal <> NoStat then
- {Special cases to display status items, etc}
- EdEvaluateSpecial(Command, StatVal, S);
-
- if Menu^.SubCur <> Sub then begin
- if EdCmdAccessible(Menu, Sub) then begin
- {Write item with highlighted selection character}
- EdFastWrite(Copy(S, 1, Soffset), R, C, ScreenAttr[MnColor]);
- EdFastWrite(S[Succ(Soffset)], R, C+Soffset, ScreenAttr[MhColor]);
- EdFastWrite(Copy(S, Soffset+2, Length(S)), R, Succ(C+Soffset), ScreenAttr[MnColor]);
- end else
- EdFastWrite(S, R, C, ScreenAttr[MnColor]);
- end else
- {Write the selected prompt}
- EdFastWrite(S, R, C, ScreenAttr[MsColor]);
- end;
- end; {EdDrawItem}
-
- procedure EdUndrawMenu(Menu : Menuptr);
- {-remove the menu and its children from the screen}
-
- begin {EdUndrawmenu}
-
- if EdPtrIsNil(Menu) then
- Exit;
-
- with Menu^ do begin
- {Undraw any submenus - must do first to get proper screen restore}
- if SubOn then begin
- EdUndrawMenu(SubMenus^[SubCur].SubMenu);
- SubOn := False;
- end;
-
- with MenuDesc[MenuLev] do
- {Restore whatever the menu overlapped on the screen}
- EdRestoreWindow(Overlap, Pred(XPosn), Pred(YPosn), XSize+2, YSize+2);
- end;
- end; {EdUndrawmenu}
-
- procedure EdEraseMenus;
- {-Remove the menu system from the screen}
-
- begin {EdEraseMenus}
- EdUndrawMenu(RootMenu);
- EdSetPtrNil(CurrMenu);
- EdShowMenuHelp;
- end; {EdEraseMenus}
-
- procedure EdDrawMenu(Menu : Menuptr);
- {-Draw a menu and its selected children on the screen}
- var
- I : Byte;
- S : VarString;
-
- begin {EdDrawMenu}
-
- if EdPtrIsNil(Menu) then
- Exit;
-
- with Menu^ do begin
-
- with MenuDesc[MenuLev] do begin
- {Store current screen to be overlapped and draw border for window}
- Overlap :=
- EdSetupWindow(Border, Pred(XPosn), Pred(YPosn), XPosn+XSize, YPosn+YSize, NormalBox);
-
- {For horizontal windows, clear out the box}
- if Orientation = Horizontal then begin
- FillChar(S[1], XSize, Blank);
- S[0] := Chr(XSize);
- for I := 0 to Pred(YSize) do
- EdFastWrite(S, YPosn+I, XPosn, ScreenAttr[MnColor]);
- end;
- end;
-
- {Draw each item in the menu}
- for I := 1 to SubMax do
- EdDrawItem(Menu, I);
-
- {Draw any submenus}
- if SubOn then
- EdDrawMenu(SubMenus^[SubCur].SubMenu);
-
- end;
- end; {EdDrawmenu}
-
- end.