home *** CD-ROM | disk | FTP | other *** search
-
- { Copyright (c) 1989,90 by Borland International, Inc. }
-
- unit TCMenu;
- { Turbo Pascal 6.0 object-oriented example command line menu system.
- This unit is used by TCALC.PAS.
- See TCALC.DOC for an more information about this example.
- }
-
- {$S-}
-
- interface
-
- uses Crt, TCUtil, TCScreen;
-
- { The menus in this unit are very simple. Each menu points to a parent (so
- that ESC will take you back to the previous menu) and a list of items.
- Each item is either a pointer to a procedure that will be executed when
- you choose the item, or is a pointer to a new menu.
- }
-
- type
- MenuItemPtr = ^MenuItem;
- MenuPtr = ^Menu;
- Menu = object
- MenuString, CommandString : StringPtr;
- MenuItems, LastItem : MenuItemPtr;
- Parent : MenuPtr;
- constructor Init(InitMenuString : String; InitParent : MenuPtr);
- procedure AddItem(NewItem : MenuItemPtr);
- function AddItemProc(NewProc : ProcPtr) : Boolean;
- function AddItemMenu(NewMenu : MenuPtr) : Boolean;
- procedure RunMenu;
- destructor Done;
- end;
- MenuItem = object
- Next : MenuItemPtr;
- constructor Init;
- procedure RunItem(var CurrMenu : MenuPtr); virtual;
- end;
- MenuItemProcPtr = ^MenuItemProc;
- MenuItemProc = object(MenuItem)
- Proc : ProcPtr;
- constructor Init(InitProc : ProcPtr);
- procedure RunItem(var CurrMenu : MenuPtr); virtual;
- end;
- MenuItemMenuPtr = ^MenuItemMenu;
- MenuItemMenu = object(MenuItem)
- NewMenu : MenuPtr;
- constructor Init(InitMenu : MenuPtr);
- procedure RunItem(var CurrMenu : MenuPtr); virtual;
- end;
-
- implementation
-
- constructor Menu.Init(InitMenuString : String; InitParent : MenuPtr);
- { Initializes a new menu }
- var
- S : String;
- Counter : Word;
- begin
- MenuItems := nil;
- LastItem := nil;
- GetMem(MenuString, Succ(Length(InitMenuString)));
- if MenuString = nil then
- Fail;
- MenuString^ := InitMenuString;
- S := '';
- for Counter := 1 to Length(InitMenuString) do
- begin
- if (InitMenuString[Counter] in ['A'..'Z']) then
- { Build command string based on upper case letters in mwenu string }
- S := S + InitMenuString[Counter];
- end;
- GetMem(CommandString, Succ(Length(S)));
- if CommandString = nil then
- begin
- Done;
- Fail;
- end;
- CommandString^ := S;
- Parent := InitParent;
- end; { Menu.Init }
-
- destructor Menu.Done;
- { Removes a menu from memory }
- begin
- if MenuString <> nil then
- FreeMem(MenuString, Succ(Length(MenuString^)));
- if CommandString <> nil then
- FreeMem(CommandString, Succ(Length(CommandString^)));
- LastItem := MenuItems;
- while LastItem <> nil do
- begin
- MenuItems := LastItem;
- LastItem := LastItem^.Next;
- Dispose(MenuItems);
- end;
- end; { Menu.Done }
-
- procedure Menu.AddItem(NewItem : MenuItemPtr);
- { Adds a new item to a menu }
- begin
- if MenuItems = nil then
- begin
- MenuItems := NewItem;
- LastItem := MenuItems;
- end
- else begin
- LastItem^.Next := NewItem;
- LastItem := LastItem^.Next;
- end;
- end; { Menu.AddItem }
-
- function Menu.AddItemProc(NewProc : ProcPtr) : Boolean;
- { Adds a procedure item to a menu }
- var
- NewItem : MenuItemProcPtr;
- begin
- NewItem := New(MenuItemProcPtr, Init(NewProc));
- if NewItem <> nil then
- begin
- AddItem(NewItem);
- AddItemProc := True;
- end
- else
- AddItemProc := False;
- end; { Menu.AddItemProc }
-
- function Menu.AddItemMenu(NewMenu : MenuPtr) : Boolean;
- { Adds a new menu item to a menu }
- var
- NewItem : MenuItemMenuPtr;
- begin
- NewItem := New(MenuItemMenuPtr, Init(NewMenu));
- if NewItem <> nil then
- begin
- AddItem(NewItem);
- AddItemMenu := True;
- end
- else
- AddItemMenu := False;
- end; { Menu.AddItemMenu }
-
- procedure Menu.RunMenu;
- { Run a menu system }
- var
- Ch, Counter, P : Word;
- CurrMenu : MenuPtr;
- I : MenuItemPtr;
- begin
- CurrMenu := @Self;
- repeat
- with CurrMenu^ do
- begin
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor); { Print the menu }
- for Counter := 1 to Length(MenuString^) do
- begin
- if MenuString^[Counter] in ['A'..'Z'] then
- WriteColor(MenuString^[Counter], Colors.MenuHiColor)
- else
- WriteColor(MenuString^[Counter], Colors.MenuLoColor);
- end;
- repeat
- Ch := GetKeyUpCase;
- case Ch of
- ESC : CurrMenu := Parent;
- Ord(' ')..Ord('~') : begin
- P := Pos(Chr(Lo(Ch)), CommandString^);
- if P <> 0 then { A menu item has been chosen }
- begin
- I := MenuItems;
- for Counter := 2 to P do
- begin
- if I <> nil then
- I := I^.Next;
- end;
- if I <> nil then
- begin
- I^.RunItem(CurrMenu); { Run the procedure or switch menus }
- Ch := ESC;
- end;
- end;
- end;
- end; { case }
- until Ch = ESC;
- end; { with }
- until CurrMenu = nil;
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
- end; { Menu.RunMenu }
-
- constructor MenuItem.Init;
- { Initializes a menu item }
- begin
- Next := nil;
- end; { MenuItem.Init }
-
- procedure MenuItem.RunItem(var CurrMenu : MenuPtr);
- begin
- Abstract('MenuItem.RunItem');
- end; { MenuItem.RunItem }
-
- constructor MenuItemProc.Init(InitProc : ProcPtr);
- { Initializes a procedure menu item }
- begin
- MenuItem.Init;
- Proc := InitProc;
- end; { MenuItemProc.Init }
-
- procedure MenuItemProc.RunItem(var CurrMenu : MenuPtr);
- { Runs the procedure that a procedure menu item points to }
- begin
- ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
- if @Proc <> nil then
- Proc;
- CurrMenu := nil;
- end; { MenuItemProc.RunItem }
-
- constructor MenuItemMenu.Init(InitMenu : MenuPtr);
- { Initializes a new menu menu item }
- begin
- MenuItem.Init;
- NewMenu := InitMenu;
- end; { MenuItemMenu.Init }
-
- procedure MenuItemMenu.RunItem(var CurrMenu : MenuPtr);
- { Changes CurrMenu so that the menu that the item points to becomes the new
- current menu }
- begin
- CurrMenu := NewMenu;
- end; { MenuItemMenu.RunItem }
-
- end.
-