home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / c / fli106c / popup.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-11  |  10.8 KB  |  409 lines

  1. //
  2. // The Fusion Library Interface for DOS
  3. // Version 1.06c
  4. // Copyright (C) 1990, 1991, 1992
  5. // Software Dimensions
  6. //
  7. // PopUpMenu
  8. //
  9.  
  10. #include "fli.h"
  11. #include "colors.h"
  12.  
  13. #ifdef __BCPLUSPLUS__
  14. #pragma hdrstop
  15. #endif
  16.  
  17. #include <alloc.h>
  18. #include <string.h>
  19. #include <dos.h>
  20. #include <ctype.h>
  21.  
  22. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  23. //
  24. // PopUpMenu()
  25. //
  26. // Constructor for PopUpMenu class
  27. //
  28. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  29.  
  30. PopUpMenu::PopUpMenu()
  31. {
  32.   AllocationError=0;
  33.   AutoSeek=1;
  34.   FusionHelpStorage=NULL;
  35.   HelpStorage=NULL;
  36.   NumberOfOptions=0;
  37.   OptionAvailable=NULL;
  38.   OptionStorage=NULL;
  39.   QuickKeyStorage=NULL;
  40.   TitleOfMenu=NULL;
  41.   FlushMouseQueue();
  42. }
  43.  
  44. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  45. //
  46. // ~PopUpMenu()
  47. //
  48. // Destructor for PopUpMenu class
  49. //
  50. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  51.  
  52. PopUpMenu::~PopUpMenu()
  53. {
  54.   if (OptionStorage)
  55.     free(OptionStorage);
  56.  
  57.   if (HelpStorage)
  58.     free(HelpStorage);
  59.  
  60.   if (FusionHelpStorage)
  61.     free(FusionHelpStorage);
  62.  
  63.   if (OptionAvailable)
  64.     free(OptionAvailable);
  65.  
  66.   if (QuickKeyStorage)
  67.     free(QuickKeyStorage);
  68.  
  69.   FlushMouseQueue();
  70. }
  71.  
  72. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  73. //
  74. // Location()
  75. //
  76. // Define position of menu.  If this function is not called by the
  77. // caller (programmer) than the class will automatically place the
  78. // menu in the center of the screen.
  79. //
  80. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  81.  
  82. void PopUpMenu::Location(int X,int Y)
  83. {
  84.   Event::X=X;
  85.   Event::Y=Y;
  86.   AutoSeek=0;
  87. }
  88.  
  89. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  90. //
  91. // NoCloseIcon()
  92. //
  93. // Gets rid of close icon.
  94. //
  95. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  96.  
  97. void PopUpMenu::NoCloseIcon()
  98. {
  99.   CloseIcon=0;
  100. }
  101.  
  102. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  103. //
  104. // Option()
  105. //
  106. // Define a menu option.  This defines a menu option for the menu.
  107. //
  108. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  109.  
  110. void PopUpMenu::Option(char *Option,char *HelpLine,int FusionHelp)
  111. {
  112.   if (!AllocationError)
  113.   {
  114.     NumberOfOptions++;
  115.  
  116.     if (!(OptionStorage=(char **)realloc(OptionStorage,sizeof(char *)*NumberOfOptions)))
  117.       AllocationError++;
  118.  
  119.     if (!(HelpStorage=(char **)realloc(HelpStorage,sizeof(char *)*NumberOfOptions)))
  120.       AllocationError++;
  121.  
  122.     if (!(OptionAvailable=(int **)realloc(OptionAvailable,sizeof(int *)*NumberOfOptions)))
  123.       AllocationError++;
  124.  
  125.     if (!(FusionHelpStorage=(int *)realloc(FusionHelpStorage,sizeof(int)*NumberOfOptions)))
  126.       AllocationError++;
  127.  
  128.     if (!(QuickKeyStorage=(int *)realloc(QuickKeyStorage,sizeof(int)*NumberOfOptions)))
  129.       AllocationError++;
  130.  
  131.     if (AllocationError)
  132.       return;
  133.  
  134.     static int Available=1;
  135.  
  136.     OptionAvailable[NumberOfOptions-1]=&Available;
  137.     OptionStorage[NumberOfOptions-1]=Option;
  138.     HelpStorage[NumberOfOptions-1]=HelpLine;
  139.     *(FusionHelpStorage+NumberOfOptions-1)=FusionHelp;
  140.   }
  141. }
  142.  
  143. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  144. //
  145. // Available()
  146. //
  147. // Passes a pointer which indicates if an option is dead or alive
  148. //
  149. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  150.  
  151. void PopUpMenu::Available(int &Available)
  152. {
  153.   if (!AllocationError)
  154.     OptionAvailable[NumberOfOptions-1]=&Available;
  155. }
  156.  
  157. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  158. //
  159. // Title()
  160. //
  161. // Defines title for menu
  162. //
  163. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  164.  
  165. void PopUpMenu::Title(char *Title)
  166. {
  167.   TitleOfMenu=Title;
  168. }
  169.  
  170. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  171. //
  172. // UseMenu()
  173. //
  174. // Activate the menu and pass control to PopUpMenu class.
  175. //
  176. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  177.  
  178. int PopUpMenu::UseMenu()
  179. {
  180.   if (AllocationError)
  181.     return MemoryAllocationError;
  182.  
  183.   if (!NumberOfOptions)
  184.     return NoAvailableOptions;
  185.  
  186.   int Option=0;
  187.  
  188.   while (OptionAvailable[Option] && !*OptionAvailable[Option])
  189.   {
  190.     Option++;
  191.     if (Option==NumberOfOptions)
  192.       return 700;
  193.   }
  194.  
  195.   int ComputedWidth=0;
  196.  
  197.   for (register int i=0, j;i<NumberOfOptions;i++)
  198.     if ((j=strlen(OptionStorage[i])-((strchr(OptionStorage[i],'~'))?1:0))
  199.       >ComputedWidth)
  200.       ComputedWidth=j;
  201.  
  202.   if (AutoSeek)
  203.   {
  204.     X=(Blaze.WhatWidth()-ComputedWidth-4)/2;
  205.     Y=(Blaze.WhatHeight()-NumberOfOptions-2)/2;
  206.   }
  207.  
  208.   if ((X+ComputedWidth+4)>Blaze.WhatWidth())
  209.     X=Blaze.WhatWidth()-ComputedWidth-4;
  210.   if ((Y+NumberOfOptions+2)>Blaze.WhatHeight()-1)
  211.     Y=Blaze.WhatHeight()-NumberOfOptions-1;
  212.  
  213.   Width=ComputedWidth+4;
  214.   Height=NumberOfOptions+2;
  215.  
  216.   MouseHide();
  217.  
  218.   SpecifyWindow(X,Y,Width,Height);
  219.  
  220.   if (!ScreenSave)
  221.     return 800;
  222.  
  223. PlopMenu:
  224.  
  225.   MouseHide();
  226.  
  227.   Blaze.InvisibleCursor();
  228.  
  229.   Blaze.Box(X,Y,Width,Height,Colors.MenuBorder);
  230.   Blaze.EraseArea(X+1,Y+1,ComputedWidth+2,NumberOfOptions,Colors.MenuInsides);
  231.   if (CloseIcon)
  232.     Blaze (X+1,Y) << Colors.MenuBorder << '['
  233.       << Colors.MenuCloseIcon << '\x7'
  234.       << Colors.MenuBorder << ']';
  235.  
  236.   if (TitleOfMenu && strlen(TitleOfMenu)<=(ComputedWidth-2))
  237.     Blaze ((CloseIcon)?(X+5):(X+1),Y) << Colors.MenuTitle << TitleOfMenu;
  238.  
  239.   Blaze.Window(X+1,Y+1,ComputedWidth+2,NumberOfOptions);
  240.  
  241. InsideAgain:
  242.  
  243.   for (i=0;i<NumberOfOptions;i++)
  244.   {
  245.     int Insides, QuickKey;
  246.  
  247.     if (!*OptionAvailable[i])
  248.       Insides=QuickKey=Colors.MenuDeadOption;
  249.     else
  250.     {
  251.       Insides=Colors.MenuInsides;
  252.       QuickKey=Colors.MenuQuickKey;
  253.     }
  254.  
  255.     *(QuickKeyStorage+i)=Blaze.QuickDisplay(1,i,QuickKey,Insides,OptionStorage[i]);
  256.     *(QuickKeyStorage+i)-=(islower(*(QuickKeyStorage+i)))?32:0;
  257.   }
  258.  
  259.   Blaze.Window(X+1,Y+1,ComputedWidth+2,NumberOfOptions);
  260.  
  261.   for (int EventCode;;)
  262.   {
  263.     HelpId=*(FusionHelpStorage+Option);
  264.     MouseHide();
  265.     Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuHiLite);
  266.     Blaze.HelpLine(*(FusionHelpStorage+Option),HelpStorage[Option]);
  267.     MouseShow();
  268.  
  269.     switch (EventCode=GetEvent())
  270.     {
  271.       case kbDown:
  272.         MouseHide();
  273.         Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuInsides);
  274.         MouseShow();
  275.         do Option=(Option==NumberOfOptions-1)?0:(++Option);
  276.           while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  277.         continue;
  278.  
  279.       case kbUp:
  280.         MouseHide();
  281.         Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuInsides);
  282.         MouseShow();
  283.         do Option=(!Option)?(NumberOfOptions-1):(--Option);
  284.           while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  285.         continue;
  286.  
  287.       case kbEsc:
  288.         if (CloseIcon)
  289.         {
  290.           RestoreWindow();
  291.           return 0;
  292.         }
  293.         continue;
  294.  
  295.       case kbCr:
  296.         switch (EventHandler(*(FusionHelpStorage+Option)))
  297.         {
  298.           case RemoveMenu:
  299.             RestoreWindow();
  300.             return 0;
  301.           case KeepMenu:
  302.             if (OptionAvailable[Option] && !*OptionAvailable[Option])
  303.             {
  304.               do Option=(Option==NumberOfOptions-1)?0:(++Option);
  305.                 while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  306.             }
  307.             goto InsideAgain;
  308.         }
  309.         continue;
  310.  
  311.       case MoveEvent:
  312.         Blaze.Window(0,0,Blaze.WhatWidth(),Blaze.WhatHeight());
  313.         goto PlopMenu;
  314.  
  315.       case MousedEvent:
  316.         if (MouseEvent&MouseLeftButtonRelease && MouseVertical>Y &&
  317.           MouseVertical<=Y+NumberOfOptions &&
  318.           MouseHorizontal>X && MouseHorizontal<=X+ComputedWidth+2)
  319.         {
  320.           if (OptionAvailable[MouseVertical-Y-1]
  321.             && !*OptionAvailable[MouseVertical-Y-1])
  322.               continue;
  323.           MouseHide();
  324.           Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuInsides);
  325.           Option=MouseVertical-Y-1;
  326.           Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuHiLite);
  327.           Blaze.HelpLine(*(FusionHelpStorage+Option),HelpStorage[Option]);
  328.           MouseShow();
  329.           switch (EventHandler(*(FusionHelpStorage+Option)))
  330.           {
  331.             case RemoveMenu:
  332.               RestoreWindow();
  333.               return 0;
  334.             case KeepMenu:
  335.               if (OptionAvailable[Option] && !*OptionAvailable[Option])
  336.               {
  337.                 do Option=(Option==NumberOfOptions-1)?0:(++Option);
  338.                   while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  339.               }
  340.               goto InsideAgain;
  341.           }
  342.           goto InsideAgain;
  343.         }
  344.  
  345.         continue;
  346.  
  347.       case CloseEvent:
  348.       case OutsideEvent:
  349.         if (CloseIcon)
  350.         {
  351.           RestoreWindow();
  352.           return 0;
  353.         }
  354.         continue;
  355.  
  356.       default:
  357.         if (EventCode<128)
  358.         {
  359.           EventCode-=((islower(EventCode))?32:0);
  360.           for (i=0;i<NumberOfOptions;i++)
  361.             if (*(QuickKeyStorage+i)==EventCode)
  362.             {
  363.               if (OptionAvailable[i])
  364.               {
  365.                 MouseHide();
  366.                 Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuInsides);
  367.                 Option=i;
  368.                 Blaze.ChangeBackground(0,Option,ComputedWidth+2,1,Colors.MenuHiLite);
  369.                 Blaze.HelpLine(*(FusionHelpStorage+Option),HelpStorage[Option]);
  370.                 MouseShow();
  371.                 switch (EventHandler(*(FusionHelpStorage+Option)))
  372.                 {
  373.                   case RemoveMenu:
  374.                     RestoreWindow();
  375.                     return 0;
  376.                   case KeepMenu:
  377.                     if (OptionAvailable[Option] && !*OptionAvailable[Option])
  378.                     {
  379.                       do Option=(Option==NumberOfOptions-1)?0:(++Option);
  380.                         while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  381.                     }
  382.                     goto InsideAgain;
  383.                 }
  384.                 continue;
  385.               }
  386.             }
  387.           continue;
  388.         }
  389.  
  390.         if (EventCode>=1000) // User event (i.e. button)
  391.         {
  392.           switch (EventHandler(Option))
  393.           {
  394.             case RemoveMenu:
  395.               RestoreWindow();
  396.               return 0;
  397.             case KeepMenu:
  398.               if (OptionAvailable[Option] && !*OptionAvailable[Option])
  399.               {
  400.                 do Option=(Option==NumberOfOptions-1)?0:(++Option);
  401.                   while (OptionAvailable[Option] && !*OptionAvailable[Option]);
  402.               }
  403.               goto InsideAgain;
  404.           }
  405.         }
  406.     }
  407.   }
  408. }
  409.