home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_PAS
/
XLIB_TP5.ZIP
/
UNITS
/
X_MENU.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-11-26
|
8KB
|
280 lines
unit X_Menu;
(*
procedures to make a pull-down-menu for mouse and/or keys
****** XLIB - Mode X graphics library ****************
****** ****************
****** Converted By Christian Harms in TP ****************
Harms : harms@minnie.informatik.uni-stuttgart.de
*)
interface
type ID_Typ = Word;
Line_List = ^Line_Typ;
Line_Typ = record
next : Line_List;
ID : ID_Typ;
S : ^String;
k : Char;
end;
Menu_Typ = record
{ on_display : Boolean;}
x1,y1,x2,y2 : Word;
c1,c2,c3,sC,TextHi,TextLo : Byte;
Line_Count : Byte;
max_width : Word;
Last_Line : Byte;
MouseMask : Byte;
SS : Pointer;
end;
(* set values to your M:Menu_Typ
C1 is the upper,left Shadow
C2 Background of Menu
C3 is the lower,right Shadow
Selected_C Color of scrollbar
Text_Hi Text-Color
Text_Lo Shadow of Text
MouseMask look in const - part of X_Button *)
procedure X_Init_Menu(var M:Menu_Typ; (* Menu-Variable *)
C1,C2,C3,Selected_C,TextHi,TextLo:Byte; (* Colors *)
MouseMask:Byte); (* s.X_Button *)
(* After X_Init_Menu, you can add some textlines. *)
(* For Color Text, see syntax in E_WriteColor in X_Text. *)
procedure X_Add_Menu (var M:Menu_Typ;ID:ID_Typ;S:String;KeyChar:Char);
(* Deallocate all line of M:Mynu_Typ. *)
procedure X_Kill_Menu(var M:Menu_Typ);
(* Draw Menu on Screen. *)
procedure X_Show_Menu(var M:Menu_Typ;x,y:Word);
(* return ID, if in this moment one line selected by mouse , esle return 0.*)
function Get_Selected_MenuLine(var M:Menu_Typ):ID_Typ;
(* wait for selecting any line and return ID, or 0 if breaked by ESC. *)
(* This works with key or mouse ! *)
function Wait_Selected_MenuLine(var M:Menu_Typ):ID_Typ;
implementation
uses X_Main,X_Rect,X_Text,X_Mouse,x_Keys;
procedure X_Init_Menu;
begin;
M.C1:=C1;M.C2:=C2;M.C3:=C3;M.sC:=Selected_C;
M.TextHi:=TextHi;M.TextLo:=TextLo;
M.MouseMask:=MouseMask;
{ M.On_Display:=False;}
M.SS:=NIL;
M.Line_Count:=0;
M.Max_Width:=0;
end;
procedure X_Add_Menu(var M:Menu_Typ;ID:ID_Typ;S:String;KeyChar:Char);
var Run,P:Line_List;
begin;
if M.SS=NIL then
begin;
GetMEM(P,sizeof(Line_Typ));
P^.ID:=ID;
P^.k :=KeyChar;
GetMEM(P^.s,length(s)+1);
P^.S^:=S;
if x_Length(S)>M.Max_Width then M.Max_Width:=x_Length(S);
P^.next:=NIL;
M.SS:=P;
end else
begin;
Run:=M.SS;
while (Run^.next<>NIL) do Run:=Run^.next;
GetMEM(P,sizeof(Line_Typ));
P^.ID:=ID;
P^.k :=KeyChar;
GetMEM(P^.s,length(s)+1);
P^.S^:=S;
if x_Length(S)>M.Max_Width then M.Max_Width:=x_Length(S);
P^.next:=NIL;
Run^.next:=P;
end;
Inc(M.Line_Count);
end;
procedure X_Kill_Menu;
var Run,P:Line_List;
begin;
if M.SS=Nil then Exit;
Run:=M.SS;
while (Run<>NIL) do
begin;
P:=Run;
Run:=Run^.next;
FreeMEM(P^.S,length(P^.S^)+1);
FreeMEM(P,sizeof(Line_Typ));
end;
M.SS:=NIL;
end;
function Get_S(M:Menu_Typ;Nr:Byte):String;
var Run:Line_List;c:Byte;
begin;
C:=1;
Run:=M.SS;
while (C<>Nr) do begin;Run:=Run^.next;Inc(C);end;
Get_S:=Run^.S^;
end;
function Get_ID(M:Menu_Typ;Nr:Byte):ID_Typ;
var Run:Line_List;c:Byte;
begin;
C:=1;
Run:=M.SS;
while (C<>Nr) do begin;Run:=Run^.next;Inc(C);end;
Get_ID:=Run^.ID;
end;
function Get_key(M:Menu_Typ;Nr:Byte):Char;
var Run:Line_List;c:Byte;
begin;
C:=1;
Run:=M.SS;
while (C<>Nr) do begin;Run:=Run^.next;Inc(C);end;
Get_key:=Run^.k;
end;
procedure X_Show_Menu;
var i:Byte;
j:Word;
s :String;
begin;
with M do
begin;
x1:=x; x2:=Max_Width+x+4;
y1:=y; y2:=y+x_font_Height*Line_Count+4;
Shadow_Box(x1+1,y1+1,x2-1,y2-1,C1,C2,C3);
for i:=1 to Line_Count do
E_WriteColor(x1+2,y1+2+(i-1)*x_font_Height,TextHi,TextLo,center(Max_Width,Get_S(M,i)));
Last_Line:=1;
Box(x1+2,y1+2,x2-2,y1+1+x_font_Height,SC);
E_WriteColor(x1+2,y1+2,TextHi,TextLo,center(Max_Width,Get_S(M,1)));
end;
end;
procedure New_Line(var M:Menu_Typ;LineOld,LineNew:Byte);
begin;
with M do
begin;
Box(x1+2,y1+2+(LineOld-1)*x_font_Height,x2-2,y1+2+LineOld*x_font_Height,C2);
E_WriteColor(x1+2,y1+2+(LineOld-1)*x_font_Height,TextHi,TextLo,center(Max_Width,Get_S(M,LineOld)));
Box(x1+2,y1+2+(LineNew-1)*x_font_Height,x2-2,y1+2+LineNew*x_font_Height,SC);
E_WriteColor(x1+2,y1+2+(LineNew-1)*x_font_Height,TextHi,TextLo,center(Max_Width,Get_S(M,LineNew)));
end;
end;
function Get_Selected_MenuLine;
var Line:Byte;
MS:Boolean;
begin;
with M do
begin;
if not InBox(x1,y1,x2,y2) then begin;Get_Selected_MenuLine:=0;exit;end;
Line:=(MouseY-y1)div x_font_Height+1;
if (Line>=0)and(Line<=Line_Count)and(Line<>Last_Line) then
begin;
MS:=IsMouseHidden;
if not MS then HideMouse;
New_Line(M,Last_Line,Line);
Last_Line:=Line;
if not MS then ShowMouse;
end;
if (ButtonStatus and MouseMask)>0
then Get_Selected_MenuLine:=Get_ID(M,Last_Line)
else Get_Selected_MenuLine:=0;
end;
end;
function Wait_Selected_MenuLine;
var Ok:Boolean;
erg,i,j:ID_Typ;
a:Char;
begin;
Ok:=False;
erg:=0;
ShowMouse;
MouseAction:=False;
repeat
if MouseAction then erg:=Get_Selected_MenuLine(M);
if erg<>0 then Ok:=True;
if (erg=0) and KeysPressed then
begin;
HideMouse;
a:=UpCase(ReadKeys);
case a of
#0:begin;
a:=ReadKeys;
case a of
Up:if M.Last_Line>0 then
begin;
i:=M.Last_Line-1;
if i=0 then i:=M.Line_Count;
New_line(M,M.Last_Line,i);
M.Last_Line:=i;
end;
Down:If M.Last_Line<=M.Line_Count then
begin;
i:=M.Last_Line+1;
if i>M.Line_Count then i:=1;
New_Line(M,M.Last_Line,i);
M.Last_Line:=i;
end;
end;
end;
Enter,Space:begin;
erg:=Get_ID(M,M.Last_Line);
Ok:=True;
end;
ESC:begin;
erg:=0;
Ok:=True;
end;
else begin; (* search for a hot key , init in x_add_menu *)
j:=0;
a:=UpCase(a);
for i:=1 to M.Line_Count do
if (Get_key(M,i)=a)or(UpCase(Get_key(M,i))=a) then j:=i;
if (j>0) then
begin;
New_Line(M,M.Last_Line,j);
M.Last_Line:=j;
end;
end;
end;
ShowMouse;
MouseAction:=False;
end;
until Ok;
Wait_Selected_MenuLine:=erg;
end;
end.