home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
t_power
/
tppick.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-02-17
|
15KB
|
460 lines
{
Copyright (c) 1987 by TurboPower Software. May be freely used by and
distributed to owners of Turbo Professional 4.0.
Modified by Dan T. Davis, January 1988.
See TPDir for an example of using the TPPick unit.
}
{$R-,I-,S-,V-}
unit TpPick;
{-Manage scrolling pick windows}
{{}
interface
uses
TPString,
TPCrt,
TPWindow;
const
PickAttr : Boolean = False; {If True, special color attributes used to pick item}
PickAttrN : Byte = $00; {Special Color Attribute; normal color}
PickAttrH : Byte = $00; {Special Color Attribute; highlight color}
HideCursor : Boolean = True; {False to leave hardware cursor on screen}
PickMinRows : Word = 0; {We want at least this many rows in PickWindow}
PickMaxRows : Word = 9999; {We want at most this many rows in PickWindow}
PickMatrix : Byte = 1; {Number of Horizontal Fields in window}
PickStick : Boolean = True; {Get "stuck" at top/bottom on SCROLLING PickWindows?}
type
CharSet = set of Char;
function PickWindow
(StringFunc : Pointer; {Pointer to function to return each item string}
NumItems : Word; {Number of items to pick from}
XLow, YLow : Byte; {Window coordinates, including frame if any}
XHigh, YHigh : Byte; {Window coordinates, including frame if any}
DrawFrame : Boolean; {True to draw a frame around window}
WindowAttr : Byte; {Video attribute for body of window}
FrameAttr : Byte; {Video attribute for frame}
HeaderAttr : Byte; {Video attribute for header}
SelectAttr : Byte; {Video attribute for selected item}
Header : string; {Title for window}
PickSet : CharSet; {Selection characters}
var Choice : Word; {The item selected, in the range 1..NumItems}
var PickChar : Char {Character used to perform selection}
) : Boolean; {True if PickWindow was successful}
{-Display a window, let user scroll around in it, and return choice.
Choice returned is in the range 1..NumItems.
PickChar is an element of PickSet.}
procedure FillPickWindow
(W : WindowPtr; {Which window to display pick list}
StringFunc : Pointer; {Pointer to function to return each item string}
Choice : Word; {Choice,row tell how the items should be drawn}
Row : Word; { in a manner consistent with PickBar}
NumItems : Word); {Number of items in PickArray}
{-Display a window, fill it with choices, and return.
Choice specifies the initial item highlighted.}
procedure PickBar
(W : WindowPtr; {The window to operate in}
StringFunc : Pointer; {Pointer to function to return items}
var Choice : Word; {The item selected, range 1..numitems}
var Row : Word; {The row to draw the bar on}
NumItems : Word; {The number of items to pick from}
SelectAttr : Byte; {Video attribute for bars}
PickSet : CharSet; {Selection Characters}
var PickChar : Char; {Character used to perform selection}
EraseBar : Boolean); {Should we recolor the bar when finished?}
{-Choose from a pick list already displayed on the screen}
{=========================================================================}
(*}*)
implementation
var
XSize : Word; {Active width of pick window (no frame)}
YSize : Word; {Active height of pick window}
PickFunc : Pointer; {Pointer to function that returns each string}
Items : Word; {Total Items being considered}
ItemWidth : Byte; {Maximum width for an item}
ItemOffSet : Word; {Offset Between Item Numbers in different Columns}
ItemWrap : Boolean; {Wrap when hitting PickWindow periphery}
procedure Lower(var Source : Word; MaxVal : Word);
begin
if Source > MaxVal then
Source := MaxVal;
end;
function InitPickVars
(W : WindowPtr;
NumItems : Word;
StringFunc : Pointer) : Boolean;
{-Initialize variables we'll use for display}
begin
InitPickVars := True;
{Make sure the window is on screen; if it is, ASSUME that}
{the user has made it the top window with SETTOPWINDOW or SELECTWINDOW}
{Otherwise, assume the user wants us to turn it on}
if DisplayWindow(W) then {we had to turn it on} ;
if W <> nil then
with WindowP(W)^ do begin
XSize := Succ(XH-XL);
YSize := Succ(YH-YL);
end else ;
{ you should have already set XSize and YSize }
Items := NumItems;
ItemWidth := XSize div PickMatrix;
Lower(YSize, Items);
Lower(YSize, PickMaxRows);
ItemOffSet := (Items+Pred(PickMatrix)) div PickMatrix;
if ItemOffSet < PickMinRows then
ItemOffSet := PickMinRows;
Lower(ItemOffSet, Items);
Lower(YSize, ItemOffSet);
ItemWrap := (YSize = ItemOffSet) or not PickStick;
PickFunc := StringFunc;
{Validate item information}
if (YSize = 0) or (PickFunc = nil) then
InitPickVars := False;
{Were we able to show the window?}
if (W <> nil) and not WindowP(W)^.Active then
InitPickVars := False;
end;
procedure ReCalc(var Row : Word; var Choice : Word; var Top : Word);
var
I : Integer;
begin
{make sure that we are asking for a valid Choice/Row combination}
I := Succ(Pred(Choice) mod ItemOffSet);
Lower(Row, I);
Lower(Row, YSize);
I := YSize-(ItemOffSet-I);
if Row < I then
Row := I;
if Row < 1 then
Row := 1;
Top := Succ((Choice-Row) mod ItemOffSet);
end;
{{}
function GetString(Item : Word) : string;
{-Return the name of each item}
inline($FF/$1E/>PickFunc); {CALL DWORD PTR [>PickFunc]}
(*}*)
procedure DrawItem(ItemNum : Word; Row, Col, Attr : Byte; HiLi : Boolean);
{-Draw the specified item}
var
S : string;
begin
if ItemNum <= Items then
S := GetString(ItemNum)
else
S := '';
if Length(S) <= ItemWidth then
S := Pad(S, ItemWidth)
else
S[0] := Chr(ItemWidth);
if PickAttr then begin
if HiLi then
FastWriteWindow(S, Row, Col, PickAttrH)
else
FastWriteWindow(S, Row, Col, PickAttrN);
PickAttr := False;
end else
FastWriteWindow(S, Row, Col, Attr);
end;
procedure DrawPage(Top : Word; Attr : Byte);
{-Draw a full page of items, with Choice shown on Row}
var
I, J, BeforeTop, AtCol : Word;
begin
for I := 0 to Pred(PickMatrix) do begin
AtCol := Succ(I*ItemWidth);
BeforeTop := Pred(Top+I*ItemOffSet);
for J := 1 to YSize do
DrawItem(J+BeforeTop, J, AtCol, Attr, False);
end;
end;
procedure PickBar
(W : WindowPtr; {The window to operate in}
StringFunc : Pointer; {Pointer to function to return items}
var Choice : Word; {The item selected, range 1..numitems}
var Row : Word; {The row to draw the bar on}
NumItems : Word; {The number of items to pick from}
SelectAttr : Byte; {Video attribute for bars}
PickSet : CharSet; {Selection Characters}
var PickChar : Char; {Character used to perform selection}
EraseBar : Boolean); {Should we recolor the bar when finished?}
var
SaveBreak : Boolean;
XY, CursorScanLines : Word;
Done : Boolean;
KW : Word;
Top, PrevTop, PrevChoice, PrevRow : Word;
Column : Word;
AtLoc : Word;
MoveMax : Word;
begin
if not InitPickVars(W, NumItems, StringFunc) then
Exit;
{ Initialize PrevTop to make sure we draw page initially }
PrevTop := 0;
with WindowP(W)^ do begin
GetCursorState(XY, CursorScanLines);
if HideCursor then
HiddenCursor
else
NormalCursor;
SaveBreak := CheckBreak;
CheckBreak := False;
{Loop getting characters}
Done := False;
repeat
{Check to see if we need to redraw the page or erase the bar}
ReCalc(Row, Choice, Top);
if PrevTop <> Top then
DrawPage(Top, WAttr)
else if (PrevChoice <> Choice) or (PrevRow <> Row) then
DrawItem(PrevChoice, PrevRow, Column, WAttr, False);
PrevTop := Top;
PrevChoice := Choice;
PrevRow := Row;
Column := Succ((Pred(Choice) div ItemOffSet)*ItemWidth);
{Highlight the selected entry}
DrawItem(Choice, Row, Column, SelectAttr, True);
GoToXY(Column, Row);
{Find our relative Location in the PickList}
AtLoc := Succ(Pred(Choice) mod ItemOffSet);
{Get a command}
KW := ReadKeyWord;
{See if a pick character first}
PickChar := Char(lo(KW));
if PickChar = #0 then
PickChar := Char(hi(KW) or $80);
if PickChar in PickSet then
Done := True;
if not Done then
case KW of
$4700 : {Home}
Choice := 1;
$4800 : {Up arrow}
if AtLoc <> 1 then begin
{Move to previous item}
Dec(Choice);
{Move selection bar}
Dec(Row);
end else if ItemWrap then begin
{Wrap to previous column, if any}
if Choice > 1 then
Dec(Choice)
else
Choice := Items;
Row := YSize;
end;
$4900 : {PgUp}
begin
MoveMax := Pred(AtLoc);
Lower(MoveMax, YSize);
if MoveMax > 0 then
Dec(Choice, MoveMax)
else if ItemWrap then begin
{Wrap to previous column, if any}
if Choice > 1 then
Dec(Choice)
else
Choice := Items;
Row := YSize;
end;
end;
$4B00 : {Left Arrow}
begin
if Choice > ItemOffSet then
Dec(Choice, ItemOffSet)
else if Choice > 1 then begin
Choice := Pred(Choice)+Pred(PickMatrix)*ItemOffSet;
Dec(Row);
end else if ItemWrap then
Choice := PickMatrix*ItemOffSet;
if Choice > Items then
repeat Dec(Choice, ItemOffSet) until Choice <= Items;
end;
$4D00 : {Right Arrow}
if Choice <= Items-ItemOffSet then
Inc(Choice, ItemOffSet)
else if AtLoc <> ItemOffSet then begin
Choice := Succ(AtLoc);
Inc(Row);
end else if ItemWrap then
Choice := 1;
$4F00 : {End}
begin
Choice := Items;
Row := 1;
end;
$5000 : {Down arrow}
if (AtLoc <> ItemOffSet) and (Choice < Items) then begin
{Move to next item}
Inc(Choice);
{Move selection bar}
Inc(Row);
end else if ItemWrap then begin
{Wrap to next column, if any}
if Choice < Items then
Inc(Choice)
else
Choice := 1;
Row := 1;
end else if (Choice = Items) then
Dec(Row);
$5100 : {PgDn}
begin
MoveMax := ItemOffSet-AtLoc;
Lower(MoveMax, YSize);
if (MoveMax > 0) and (Choice < Items) then begin
Inc(Choice, MoveMax);
if Choice > Items then begin
Choice := Items;
Row := 1;
end;
end else if ItemWrap then begin
{Wrap to next column, if any}
if Choice < Items then
Inc(Choice)
else
Choice := 1;
Row := 1;
end;
end;
end;
until Done;
if EraseBar then
DrawItem(Choice, Row, Column, WAttr, False);
CheckBreak := SaveBreak;
RestoreCursorState(XY, CursorScanLines);
end;
end;
function PickWindow
(StringFunc : Pointer; {Pointer to function to return each item string}
NumItems : Word; {Number of items in PickArray}
XLow, YLow : Byte; {Window coordinates, including frame if any}
XHigh, YHigh : Byte; {Window coordinates, including frame if any}
DrawFrame : Boolean; {True to draw a frame around window}
WindowAttr : Byte; {Video attribute for body of window}
FrameAttr : Byte; {Video attribute for frame}
HeaderAttr : Byte; {Video attribute for header}
SelectAttr : Byte; {Video attribute for selected item}
Header : string; {Title for window}
PickSet : CharSet; {Selection characters}
var Choice : Word; {The item selected, in the range 1..NumItems}
var PickChar : Char {Character used to perform selection}
) : Boolean; {True if PickWindow was successful}
var
Correction : Integer;
Row : Word;
W : WindowPtr;
begin
{Assume failure}
PickWindow := False;
{Get a Value for YHigh}
if DrawFrame then
Correction := -1
else
Correction := +1;
XSize := XHigh-XLow+Correction;
YSize := YHigh-YLow+Correction;
if not InitPickVars(nil, NumItems, StringFunc) then
Exit;
if YSize >= PickMinRows then
YHigh := YLow+YSize-Correction
else
YHigh := YLow+PickMinRows-Correction;
{Initialize the window}
if not MakeWindow(W, XLow, YLow, XHigh, YHigh,
DrawFrame, True, False,
WindowAttr, FrameAttr, HeaderAttr,
Header) then Exit;
if not InitPickVars(W, NumItems, StringFunc) then
Exit;
{Initial item is the one we say if legal}
if (Choice < 1) or (Choice > NumItems) then
Choice := 1;
Row := Choice;
PickBar(W, PickFunc, Choice, Row, Items,
SelectAttr, PickSet, PickChar, False);
{Restore the screen and deallocate the window}
W := EraseTopWindow;
DisposeWindow(W);
{If we get to here, all was well}
PickWindow := True;
end;
procedure FillPickWindow
(W : WindowPtr; {Which window to display pick list}
StringFunc : Pointer; {Pointer to function to return each item string}
Choice : Word; {Choice,row tell how the items should be drawn}
Row : Word; { in a manner consistent with PickBar}
NumItems : Word); {Number of items in PickArray}
var
Top : Word;
begin
if not InitPickVars(W, NumItems, StringFunc) then
Exit;
ReCalc(Row, Choice, Top);
DrawPage(Top, WindowP(W)^.WAttr);
end;
end.