home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 372.lha / PopUpMenu_3.2 / Source / OpenWindows.c < prev    next >
C/C++ Source or Header  |  1990-05-06  |  13KB  |  454 lines

  1. #include "PopUpMenu.h"
  2.  
  3. /* these must be declared here in this silly way (lattice 5.0 bug) */
  4. IMPORT UWORD  chip GhostPattern[];
  5. IMPORT WORD   far  NormalPattern[];
  6. IMPORT struct Image chip MyAmigaKeyImage[];
  7. IMPORT struct Image far MySubItemImage[];
  8.  
  9.  
  10. /****************************************
  11.  * OpenMenuWindow()                     *
  12.  *                    *
  13.  * Input:                *
  14.  *   none                *
  15.  * Output:                *
  16.  *   return    - TRUE if window opened. *
  17.  ****************************************/
  18.  
  19. BOOL OpenMenuWindow(MenuTop)
  20.   WORD MenuTop;
  21. {
  22. /*
  23.   IMPORT UWORD far GhostPattern[2];
  24.   IMPORT UWORD far NormalPattern[2];
  25. */
  26.   IMPORT struct Window    *const ActiveWindow;
  27.   IMPORT struct Menu    *const Menues;
  28.   IMPORT struct Screen    *const Screen;
  29.   IMPORT struct RastPort      Rp;     /* Screens RastPort */
  30.   IMPORT struct WindowData    MenuWindow;
  31.   IMPORT const UWORD         MenuFontSize;
  32.  
  33.   WORD    MenuWidth     = 0;
  34.   WORD    MenuHeight    = BORDERSIZE + 1;
  35.  
  36.  /****************************************
  37.   * Find width & height of window needed *
  38.   ****************************************/
  39.   {
  40.     struct Menu *MenuPtr = Menues;
  41.  
  42.     do {
  43.       UWORD Length;
  44.  
  45.       Length = TextLength(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
  46.       if (MenuPtr->Width > Length)
  47.     Length = MenuPtr->Width;
  48.       if (Length > MenuWidth)
  49.     MenuWidth = Length;
  50.       MenuHeight += MenuFontSize;
  51.     }
  52.     while ((MenuPtr = MenuPtr->NextMenu) != NULL);
  53.  
  54.     MenuWidth  += (2 * BORDERSIZE + 1);
  55.   }
  56.  /************************************
  57.   * Position window on screen (Left) *
  58.   ************************************/
  59.   {
  60.     WORD MenuLeft = Screen->MouseX - ((UWORD)MenuWidth / 2);
  61.  
  62.     if (MenuLeft < 0)
  63.       MenuLeft = 0;
  64.     if (MenuLeft + MenuWidth > Screen->Width)
  65.       MenuLeft = Screen->Width - MenuWidth;
  66.  
  67.     MenuWindow.LeftEdge  = MenuLeft;
  68.     MenuWindow.Width     = MenuWidth;
  69.   }
  70.  /***********************************
  71.   * Position window on screen (Top) *
  72.   ***********************************/
  73.   {
  74.     if (MenuTop > MenuHeight) /* menues has changed */
  75.       MenuTop = 0;
  76.     MenuTop  = Screen->MouseY - (MenuFontSize / 2) - MenuTop;
  77.  
  78.     if (MenuTop < 0)
  79.       MenuTop = 0;
  80.     if (MenuTop + MenuHeight > Screen->Height)
  81.       MenuTop = Screen->Height - MenuHeight;
  82.  
  83.     MenuWindow.TopEdge     = MenuTop;
  84.     MenuWindow.Height     = MenuHeight;
  85.   }
  86.  /*******************************
  87.   * Open window with right size *
  88.   *******************************/
  89.  
  90.   if (BuildBitMap(&MenuWindow) == FALSE)
  91.     return (FALSE);
  92.  
  93.  /**********************
  94.   * Fill in all menues *
  95.   **********************/
  96.   {
  97.     const LONG     MenuLeft = MenuWindow.LeftEdge + BORDERSIZE;
  98.     struct Menu *MenuPtr  = Menues;
  99.  
  100.     do {
  101.       MenuTop += MenuFontSize;
  102.  
  103.       SetAPen(&Rp,(LONG)ActiveWindow->DetailPen);
  104.       Move(&Rp,MenuLeft,(LONG)MenuTop - 1);
  105.       Text(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
  106.  
  107.       /* Ghostitem ? */
  108.       if (NOT (MenuPtr->Flags & MENUENABLED)) {
  109.     SetAfPt(&Rp, GhostPattern, 1);
  110.     SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
  111.     RectFill(&Rp,MenuLeft,
  112.              (LONG)(MenuTop - MenuFontSize + BORDERSIZE),
  113.              (LONG)(MenuWindow.RightEdge - BORDERSIZE),
  114.              (LONG)MenuTop);
  115.     SetAfPt(&Rp,NormalPattern,1);
  116.       }
  117.     }
  118.     while ((MenuPtr = MenuPtr->NextMenu) != NULL);
  119.   }
  120.  
  121.   return (TRUE);
  122. }
  123.  
  124. /**************************************************************
  125.  * OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType)  *
  126.  *                                  *
  127.  * Input:                              *
  128.  *   ItemWindow   - Window to open.                  *
  129.  *   ParentWindow -                          *
  130.  *   TopPos      - Top position for new window.          *
  131.  *   WindowType   - ITEMWINDOW or SUBWINDOW              *
  132.  * Output:                              *
  133.  *   none                              *
  134.  **************************************************************/
  135. VOID OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType)
  136.   struct WindowData  *const ItemWindow;
  137.   struct WindowData  *const ParentWindow;
  138.   const WORD TopPos;
  139.   const UWORD WindowType;
  140. {
  141.   IMPORT struct Screen       *const Screen;
  142.   IMPORT struct WindowData  MenuWindow;
  143.   IMPORT const WORD  MouseX;
  144.  
  145.   struct WindowSize  Size;
  146.  
  147.  /****************************************
  148.   * Find width & height of window needed *
  149.   ****************************************/
  150.   {
  151.     struct MenuItem  *Item = ItemWindow->Items;
  152.  
  153.     Size.Left  = WORD_MAX;
  154.     Size.Top   = WindowType; /* (ITEMWINDOW -> TopPos >= 0), SUBWINDOW -> no limit */
  155.     Size.Right = Size.Bottom = WORD_MIN;
  156.  
  157.     do {
  158.       CheckItemSize(&Size,Item,(LONG)Item->ItemFill);
  159.       if ((Item->Flags & HIGHFLAGS) == HIGHIMAGE)
  160.     CheckItemSize(&Size,Item,(LONG)Item->SelectFill); /* check highlighted */
  161.     }
  162.     while (Item = Item->NextItem);
  163.   }
  164.  /**********************************************
  165.   * Position window on screen (left)           *
  166.   * Possible positions:                *
  167.   *   1. At real position (a'la intuition).    *
  168.   *   2. At right side of parent.           *
  169.   *   3. At left side of parent.           *
  170.   *   4. On the side that covers parent least. *
  171.   **********************************************/
  172.   {
  173.     WORD  WindowLeft;
  174.     WORD  LeftValue   = Size.Left - BORDERSIZE;
  175.     UWORD WindowWidth = Size.Right - LeftValue + BORDERSIZE;
  176.     WORD  LeftPos2    = ParentWindow->LeftEdge - WindowWidth + 7;
  177.     WORD  MaxLeft     = Screen->Width - WindowWidth;
  178.  
  179.     if ((WindowType == ITEMWINDOW) OR
  180.     ((WindowLeft = ParentWindow->LeftEdge + LeftValue) > MaxLeft) OR
  181.     (WindowLeft < 0))
  182.       WindowLeft = ParentWindow->RightEdge - 7;
  183.  
  184.     if (WindowLeft > MaxLeft)
  185.       if (LeftPos2 > MaxLeft - WindowLeft)
  186.     WindowLeft = (LeftPos2 > 0) ? LeftPos2 : 0;
  187.       else
  188.     WindowLeft = MaxLeft;
  189.  
  190.     if (WindowLeft + WindowWidth < ParentWindow->LeftEdge + 7)
  191.       WindowWidth = ParentWindow->LeftEdge + 7 - WindowLeft;
  192.  
  193.     ItemWindow->LeftEdge  = WindowLeft;
  194.     ItemWindow->LeftValue = LeftValue - WindowLeft;
  195.     ItemWindow->Width      = WindowWidth;
  196.   }
  197.  /***********************************
  198.   * Position Window on screen (Top) *
  199.   ***********************************/
  200.   {
  201.     WORD  TopValue     = Size.Top - BORDERSIZE;
  202.     WORD  WindowTop    = TopPos + TopValue;
  203.     UWORD WindowHeight = Size.Bottom - TopValue  + BORDERSIZE;
  204.  
  205.     if (WindowTop + WindowHeight > Screen->Height)
  206.       WindowTop = Screen->Height - WindowHeight;
  207.     if (WindowTop < 0)
  208.       WindowTop = 0;
  209.  
  210.     ItemWindow->TopEdge   = WindowTop;
  211.     ItemWindow->TopValue  = TopValue - WindowTop;
  212.     ItemWindow->Height      = WindowHeight;
  213.   }
  214.  
  215.   if (BuildBitMap(ItemWindow) == FALSE)
  216.     return;
  217.  
  218.   DrawAllItems(ItemWindow);
  219. }
  220.  
  221. /****************************************
  222.  * DrawAllItems(ItemWindow)             *
  223.  *                    *
  224.  * Input:                *
  225.  *   ItemWindow  - Window to draw into. *
  226.  *                    *
  227.  * Output                *
  228.  *   none                *
  229.  ****************************************/
  230. VOID DrawAllItems(ItemWindow)
  231.   struct WindowData *const ItemWindow;
  232. {
  233.   struct MenuItem *Item = ItemWindow->Items;
  234.  
  235.   ClearWindow(ItemWindow);
  236.  
  237.   do
  238.     DrawMenuItem(Item, ItemWindow, ITEMFILL, DONTCLEAROLD);
  239.   while ((Item = Item->NextItem) != NULL);
  240. }
  241.  
  242. /****************************************************************************
  243.  * DrawMenuItem(Item, ItemWindow, Mode, Clear)                              *
  244.  *                                        *
  245.  * Input:                                    *
  246.  *   Item -      Item to draw.                         *
  247.  *   ItemWindow - Data about window to draw item into                *
  248.  *   Mode -      ITEMFILL = Draw Item                        *
  249.  *          SELECTFILL = Draw selected item (if any)                  *
  250.  *   Clear -      Clear position before drawing  (Only used with HighImage) *
  251.  * OUTPUT                                    *
  252.  *   none                                    *
  253.  ****************************************************************************/
  254.  
  255. VOID DrawMenuItem(Item,ItemWindow,Mode,Clear)
  256.   struct MenuItem *const Item;
  257.   struct WindowData  *const ItemWindow;
  258.   const UWORD Mode;
  259.   const BOOL   Clear;
  260. {
  261. /*
  262.   IMPORT UWORD far GhostPattern[2];
  263.   IMPORT UWORD far NormalPattern[2];
  264.   IMPORT struct Image far MyAmigaKeyImage[2];
  265.   IMPORT struct Image far MySubItemImage[2];
  266. */
  267.  
  268.   IMPORT struct RastPort Rp;
  269.   IMPORT struct Window    *const ActiveWindow;
  270.   IMPORT struct Screen    *const Screen;
  271.   IMPORT const BOOL  ScreenType;
  272.  
  273.   union FillTypes Fill;
  274.   const LONG Left = Item->LeftEdge - ItemWindow->LeftValue;
  275.   const LONG Right = Left + Item->Width - 1;
  276.   const LONG Top = Item->TopEdge - ItemWindow->TopValue;
  277.   const LONG Bottom = Top + Item->Height - 1;
  278.  
  279.   /* Find what to Draw */
  280.   if (!(Fill.APTR = (Mode == SELECTFILL) ? Item->SelectFill : Item->ItemFill))
  281.     return;  /* nothing to draw */
  282.  
  283.   SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
  284.   SetDrMd(&Rp, JAM1);
  285.  
  286.   if (Clear)
  287.     /* Erase whay may already be here */
  288.     RectFill(&Rp, Left, Top, Right, Bottom);
  289.  
  290.   /* Now, draw the item itself -- depending on the Flag value, it    */
  291.   /* could be either an Image or an IntuiText */
  292.  
  293.   if (Item->Flags & ITEMTEXT)
  294.     PrintIText(&Rp, Fill.IText, Left, Top);
  295.   else
  296.     DrawImage(&Rp,  Fill.Image, Left, Top);
  297.  
  298.   /* If the item is checkmarked, draw the checkmark. */
  299.  
  300.   if ((Item->Flags & (CHECKIT | CHECKED)) == (CHECKIT | CHECKED))
  301.     DrawImage(&Rp, ActiveWindow->CheckMark, Left, Top);
  302.  
  303.   /* If the item has a commandkey, or a subitem */
  304.   {
  305.     const LONG ItemTop    = Top + ((Item->Flags & ITEMTEXT) ?
  306.                      Fill.IText->TopEdge:
  307.                      Fill.Image->TopEdge);
  308.  
  309.     if (Item->Flags & COMMSEQ) {
  310.       const LONG KeyLeft = Right - Rp.TxWidth;
  311.  
  312.       DrawImage(&Rp, &MyAmigaKeyImage[ScreenType],KeyLeft, ItemTop);
  313.  
  314.       Move(&Rp, KeyLeft, ItemTop + Rp.TxHeight - 2);
  315.       SetAPen(&Rp, (LONG)(ActiveWindow->DetailPen));
  316.       Text(&Rp,&Item->Command,1);
  317.     }
  318.  
  319.     if (Item->SubItem)
  320.       DrawImage(&Rp,&MySubItemImage[ScreenType],Right,ItemTop);
  321.   }
  322.  
  323.   /* If the ITEMENABLED flag is not set, "ghost" the item. */
  324.  
  325.   if (!(Item->Flags & ITEMENABLED)) {
  326.     SetAfPt(&Rp, GhostPattern, 1);
  327.     SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
  328.     RectFill(&Rp, Left, Top, Right, Bottom);
  329.     SetAfPt(&Rp, NormalPattern, 1);
  330.   }
  331. }
  332.  
  333. /****************************************
  334.  * BuildBitMap(Window)  - OpenWindow    *
  335.  *                    *
  336.  * Input:                *
  337.  *   Window    - Window to open.    *
  338.  * Output:                *
  339.  *   return    - TRUE if window opened. *
  340.  ****************************************/
  341. BOOL BuildBitMap(Window)
  342.   struct WindowData *const Window;
  343. {
  344.   IMPORT struct Screen     *const Screen;
  345.   IMPORT struct RastPort Rp;
  346.  
  347.   const LONG WindowWidth  = Window->Width;
  348.   const LONG WindowHeight = Window->Height;
  349.  
  350.   /* is window to big for screen ? */
  351.  
  352.   if ((WindowWidth > Screen->Width) OR
  353.       (WindowHeight > Screen->Height))
  354.     return (FALSE);
  355.  
  356.   Window->RightEdge = Window->LeftEdge + WindowWidth  - 1;
  357.   Window->Bottom    = Window->TopEdge  + WindowHeight - 1;
  358.  
  359.   /* init bitmap */
  360.   {
  361.     const ULONG Depth = Screen->BitMap.Depth;
  362.     UWORD i;
  363.  
  364.     InitBitMap(&Window->Bm,Depth,WindowWidth,WindowHeight);
  365.  
  366.     /* allocate raster for all bitplanes */
  367.  
  368.     for (i = 0; i < Depth; i++)
  369.       if ((Window->Bm.Planes[i] = AllocRaster(WindowWidth,WindowHeight)) == NULL) {
  370.     RemoveBitMap(Window);
  371.     return(FALSE);
  372.       }
  373.   }
  374.  
  375.   Window->BitMapOk = TRUE;
  376.  
  377.   /* make window visible */
  378.   SwapBits(Window);
  379.  
  380.   ClearWindow(Window);
  381.  
  382.   return (TRUE);
  383. }
  384.  
  385. /*********************************
  386.  * ClearWindow(window)           *
  387.  *                 *
  388.  * Input:             *
  389.  *   Window   - Window to clear. *
  390.  * OutPut:             *
  391.  *   none             *
  392.  *********************************/
  393. VOID ClearWindow(Window)
  394.   struct WindowData *const Window;
  395. {
  396.   IMPORT struct RastPort Rp;
  397.   IMPORT struct Window *const ActiveWindow;
  398.  
  399.   /* window should look like intuitionmenues */
  400.   SetDrMd(&Rp, JAM1);
  401.  
  402.   SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
  403.   SetOPen(&Rp,(LONG)ActiveWindow->DetailPen);
  404.  
  405.   RectFill(&Rp,(LONG)Window->LeftEdge,
  406.            (LONG)Window->TopEdge,
  407.            (LONG)Window->RightEdge,
  408.            (LONG)Window->Bottom);
  409.   BNDRYOFF(&Rp);
  410. }
  411.  
  412. /******************************
  413.  * CloseItemWindow(Window)    *
  414.  *                  *
  415.  *INPUT               *
  416.  *  Window - Window to close. *
  417.  *OUTPUT              *
  418.  *  none              *
  419.  ******************************/
  420. VOID CloseItemWindow(Window)
  421.   struct WindowData *const Window;
  422. {
  423.   if (Window->BitMapOk) {
  424.     /* remove window from screen */
  425.     SwapBits(Window);
  426.  
  427.     /* remove all bitplanes */
  428.     RemoveBitMap(Window);
  429.   }
  430. }
  431.  
  432. /****************************************************************************
  433.  * RemoveBitMap(Window) - Remove allocated rasters in the BitMap structure. *
  434.  *                                        *
  435.  * Input:                                    *
  436.  *   Window   - Window with bitmap-                        *
  437.  * Output:                                    *
  438.  *   none                                    *
  439.  ****************************************************************************/
  440. VOID RemoveBitMap(Window)
  441.   struct WindowData *const Window;
  442. {
  443.   struct BitMap *const Bm = &Window->Bm;
  444.   UWORD  i;
  445.  
  446.   /* remove all allocated rasters */
  447.   for (i = 0; i < Bm->Depth; i++)
  448.     if (Bm->Planes[i])
  449.       FreeRaster(Bm->Planes[i],(LONG)Window->Width,(LONG)Window->Height);
  450.  
  451.   Window->BitMapOk = FALSE;
  452. }
  453.  
  454.