home *** CD-ROM | disk | FTP | other *** search
- {
- **************************************************************************
- BOXES.PAS -- Box objects for screen-oriented programs
- Copyright 1989 L. Brett Glass -- All rights reserved.
- **************************************************************************
- }
- unit Boxes;
-
- interface
-
- uses CRT, CharScrn, StrUtil;
-
- type
- BoxTypes = (THINBOX, THICKBOX);
- BoxHDividers = set of RowType;
- BoxVDividers = set of ColType;
- Box = object (TitledCharObject)
- width : WidthType;
- height : HeightType;
- boxType : BoxTypes;
- hDividers : BoxHDividers;
- vDividers : BoxVDividers;
-
- procedure Draw; virtual;
- {Draw a box with upper left corner, width, and height specified. The
- box can be thick or thin, the interior is cleared, and a title
- may be written on the top row.}
- procedure DispTitle; virtual;
- {Display the box's title}
- end;
-
- implementation
-
- type
- BoxRec =
- record
- ul, ur, ll, lr, horiz, vert, toptee, btmtee, ltee, rtee, cross : Char
- end;
-
- const
- boxChars : array[BoxTypes] of BoxRec =
- ((ul : '┌'; ur : '┐'; ll : '└'; { THINBOX }
- lr : '┘'; horiz : '─'; vert : '│';
- toptee : '┬'; btmtee : '┴';
- ltee : '├'; rtee : '┤'; cross : '┼'),
- (ul : '╔'; ur : '╗'; ll : '╚'; { THICKBOX }
- lr : '╝'; horiz : '═'; vert : '║';
- toptee : '╦'; btmtee : '╩';
- ltee : '╠'; rtee : '╣'; cross : '╬'));
-
-
-
-
- procedure Box.DispTitle;
- const
- leftBracket : Char = '[';
- rightBracket : Char = ']';
- var
- tLen : Byte absolute title;
- begin {Box,DispTitle}
- Ellipsis(title,width-4);
- CharToScreen(Succ(x),y,leftBracket);
- CharToScreen(x + 2 + tLen,y,rightBracket);
- CharsToScreen(x+2,y,tLen,title[1])
- end; {Box.DispTitle}
-
- procedure VertDivider(col : ColType;
- top : RowType;
- height : HeightType;
- boxType : BoxTypes);
- {Divide a box vertically along the specified column, given the row of
- the top of the box and its height.}
- begin {VertDivider}
- CharToScreen(col,top,boxChars[boxType].toptee);
- FillBox(col,Succ(top),1,height-2,boxChars[boxType].vert);
- CharToScreen(col,Pred(top+height),boxChars[boxType].btmtee)
- end; {VertDivider}
-
- procedure HorizDivider(left : ColType;
- row : RowType;
- width : WidthType;
- boxType : BoxTypes);
- {Divide a box horizontally along the specified row, given the column of
- the left edge of the box and its width.}
- begin {HorizDivider}
- CharToScreen(left,row,boxChars[boxType].ltee);
- FillBox(Succ(left),row,width-2,1,boxChars[boxType].horiz);
- CharToScreen(Pred(left+width),row,boxChars[boxType].rtee)
- end; {HorizDivider}
-
- {Public routines}
-
- procedure Box.Draw;
- type
- HDivNumber = 0..SCREENHEIGHT;
- HDivRange = 1..SCREENHEIGHT;
- var
- i : RowType;
- j : ColType;
- k : HDivNumber;
- p : ScreenParms;
- hDivs : array [HDivRange] of RowType;
- hDivCount : HDivNumber;
- begin {Box.Draw}
- p.Save;
- TextAttr := color;
- CharToScreen(x,y,boxChars[boxType].ul); {Upper left corner}
- FillBox(Succ(x),y,width-2,1,boxChars[boxType].horiz); {Top}
- CharToScreen(Pred(x+width),y,boxChars[boxType].ur); {Upper right corner}
- FillBox(x,Succ(y),1,height-2,boxChars[boxType].vert); {Left}
- FillBox(Pred(x+width),Succ(y),1,height-2,boxChars[boxType].vert); {Right}
- CharToScreen(x,Pred(y+height),boxChars[boxType].ll); {Lower left corner}
- FillBox(Succ(x),Pred(y+height),width-2,1,boxChars[boxType].horiz); {Bottom}
- CharToScreen(Pred(x+width),Pred(y+height),boxChars[boxType].lr); {Lower right corner}
- FillBox(Succ(x),Succ(y),width-2,height-2,' '); {Clear innards}
- hDivCount := 0;
- FillChar(hDivs,SizeOf(hDivs),FALSE);
- for i := FIRSTROW to LASTROW do
- if i in hDividers then
- begin
- HorizDivider(x,i,width,boxType);
- Inc(hDivCount);
- hDivs[hDivCount] := i;
- end;
- for j := FIRSTCOL to LASTCOL do
- if j in vDividers then
- begin
- VertDivider(j,y,height,boxType);
- for k := 1 to hDivCount do
- CharsToScreen(j,hDivs[k],1,boxChars[boxType].cross)
- end;
- if Length(title) <> 0 then
- Self.DispTitle;
- p.Restore;
- dirty := FALSE;
- end; {Box.Draw}
-
- end. {Boxes}