[comp.sources.amiga] v90i137: PopUpMenu 3.2 - make intuition menus into pop up menus, Part03/03

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (04/14/90)

Submitted-by: d5adria@dtek.chalmers.se (Martin Adrian)
Posting-number: Volume 90, Issue 137
Archive-name: util/popupmenu-3.2/part03

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  Source/OpenWindows.c
# Wrapped by tadguy@xanth on Fri Apr 13 19:45:21 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Source/OpenWindows.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/OpenWindows.c'\"
else
echo shar: Extracting \"'Source/OpenWindows.c'\" \(12815 characters\)
sed "s/^X//" >'Source/OpenWindows.c' <<'END_OF_FILE'
X#include "PopUpMenu.h"
X
X/* these must be declared here in this silly way (lattice 5.0 bug) */
XIMPORT UWORD  chip GhostPattern[];
XIMPORT WORD   far  NormalPattern[];
XIMPORT struct Image chip MyAmigaKeyImage[];
XIMPORT struct Image far MySubItemImage[];
X
X
X/****************************************
X * OpenMenuWindow()                     *
X *					*
X * Input:				*
X *   none				*
X * Output:				*
X *   return    - TRUE if window opened. *
X ****************************************/
X
XBOOL OpenMenuWindow(MenuTop)
X  WORD MenuTop;
X{
X/*
X  IMPORT UWORD far GhostPattern[2];
X  IMPORT UWORD far NormalPattern[2];
X*/
X  IMPORT struct Window	*const ActiveWindow;
X  IMPORT struct Menu	*const Menues;
X  IMPORT struct Screen	*const Screen;
X  IMPORT struct RastPort      Rp;     /* Screens RastPort */
X  IMPORT struct WindowData    MenuWindow;
X  IMPORT const UWORD	     MenuFontSize;
X
X  WORD	MenuWidth     = 0;
X  WORD	MenuHeight    = BORDERSIZE + 1;
X
X /****************************************
X  * Find width & height of window needed *
X  ****************************************/
X  {
X    struct Menu *MenuPtr = Menues;
X
X    do {
X      UWORD Length;
X
X      Length = TextLength(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
X      if (MenuPtr->Width > Length)
X	Length = MenuPtr->Width;
X      if (Length > MenuWidth)
X	MenuWidth = Length;
X      MenuHeight += MenuFontSize;
X    }
X    while ((MenuPtr = MenuPtr->NextMenu) != NULL);
X
X    MenuWidth  += (2 * BORDERSIZE + 1);
X  }
X /************************************
X  * Position window on screen (Left) *
X  ************************************/
X  {
X    WORD MenuLeft = Screen->MouseX - ((UWORD)MenuWidth / 2);
X
X    if (MenuLeft < 0)
X      MenuLeft = 0;
X    if (MenuLeft + MenuWidth > Screen->Width)
X      MenuLeft = Screen->Width - MenuWidth;
X
X    MenuWindow.LeftEdge  = MenuLeft;
X    MenuWindow.Width	 = MenuWidth;
X  }
X /***********************************
X  * Position window on screen (Top) *
X  ***********************************/
X  {
X    if (MenuTop > MenuHeight) /* menues has changed */
X      MenuTop = 0;
X    MenuTop  = Screen->MouseY - (MenuFontSize / 2) - MenuTop;
X
X    if (MenuTop < 0)
X      MenuTop = 0;
X    if (MenuTop + MenuHeight > Screen->Height)
X      MenuTop = Screen->Height - MenuHeight;
X
X    MenuWindow.TopEdge	 = MenuTop;
X    MenuWindow.Height	 = MenuHeight;
X  }
X /*******************************
X  * Open window with right size *
X  *******************************/
X
X  if (BuildBitMap(&MenuWindow) == FALSE)
X    return (FALSE);
X
X /**********************
X  * Fill in all menues *
X  **********************/
X  {
X    const LONG	 MenuLeft = MenuWindow.LeftEdge + BORDERSIZE;
X    struct Menu *MenuPtr  = Menues;
X
X    do {
X      MenuTop += MenuFontSize;
X
X      SetAPen(&Rp,(LONG)ActiveWindow->DetailPen);
X      Move(&Rp,MenuLeft,(LONG)MenuTop - 1);
X      Text(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
X
X      /* Ghostitem ? */
X      if (NOT (MenuPtr->Flags & MENUENABLED)) {
X	SetAfPt(&Rp, GhostPattern, 1);
X	SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
X	RectFill(&Rp,MenuLeft,
X		     (LONG)(MenuTop - MenuFontSize + BORDERSIZE),
X		     (LONG)(MenuWindow.RightEdge - BORDERSIZE),
X		     (LONG)MenuTop);
X	SetAfPt(&Rp,NormalPattern,1);
X      }
X    }
X    while ((MenuPtr = MenuPtr->NextMenu) != NULL);
X  }
X
X  return (TRUE);
X}
X
X/**************************************************************
X * OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType)  *
X *							      *
X * Input:						      *
X *   ItemWindow   - Window to open.			      *
X *   ParentWindow -					      *
X *   TopPos	  - Top position for new window.	      *
X *   WindowType   - ITEMWINDOW or SUBWINDOW		      *
X * Output:						      *
X *   none						      *
X **************************************************************/
XVOID OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType)
X  struct WindowData  *const ItemWindow;
X  struct WindowData  *const ParentWindow;
X  const WORD TopPos;
X  const UWORD WindowType;
X{
X  IMPORT struct Screen	   *const Screen;
X  IMPORT struct WindowData  MenuWindow;
X  IMPORT const WORD  MouseX;
X
X  struct WindowSize  Size;
X
X /****************************************
X  * Find width & height of window needed *
X  ****************************************/
X  {
X    struct MenuItem  *Item = ItemWindow->Items;
X
X    Size.Left  = WORD_MAX;
X    Size.Top   = WindowType; /* (ITEMWINDOW -> TopPos >= 0), SUBWINDOW -> no limit */
X    Size.Right = Size.Bottom = WORD_MIN;
X
X    do {
X      CheckItemSize(&Size,Item,(LONG)Item->ItemFill);
X      if ((Item->Flags & HIGHFLAGS) == HIGHIMAGE)
X	CheckItemSize(&Size,Item,(LONG)Item->SelectFill); /* check highlighted */
X    }
X    while (Item = Item->NextItem);
X  }
X /**********************************************
X  * Position window on screen (left)           *
X  * Possible positions: 		       *
X  *   1. At real position (a'la intuition).    *
X  *   2. At right side of parent.	       *
X  *   3. At left side of parent.	       *
X  *   4. On the side that covers parent least. *
X  **********************************************/
X  {
X    WORD  WindowLeft;
X    WORD  LeftValue   = Size.Left - BORDERSIZE;
X    UWORD WindowWidth = Size.Right - LeftValue + BORDERSIZE;
X    WORD  LeftPos2    = ParentWindow->LeftEdge - WindowWidth + 7;
X    WORD  MaxLeft     = Screen->Width - WindowWidth;
X
X    if ((WindowType == ITEMWINDOW) OR
X	((WindowLeft = ParentWindow->LeftEdge + LeftValue) > MaxLeft) OR
X	(WindowLeft < 0))
X      WindowLeft = ParentWindow->RightEdge - 7;
X
X    if (WindowLeft > MaxLeft)
X      if (LeftPos2 > MaxLeft - WindowLeft)
X	WindowLeft = (LeftPos2 > 0) ? LeftPos2 : 0;
X      else
X	WindowLeft = MaxLeft;
X
X    if (WindowLeft + WindowWidth < ParentWindow->LeftEdge + 7)
X      WindowWidth = ParentWindow->LeftEdge + 7 - WindowLeft;
X
X    ItemWindow->LeftEdge  = WindowLeft;
X    ItemWindow->LeftValue = LeftValue - WindowLeft;
X    ItemWindow->Width	  = WindowWidth;
X  }
X /***********************************
X  * Position Window on screen (Top) *
X  ***********************************/
X  {
X    WORD  TopValue     = Size.Top - BORDERSIZE;
X    WORD  WindowTop    = TopPos + TopValue;
X    UWORD WindowHeight = Size.Bottom - TopValue  + BORDERSIZE;
X
X    if (WindowTop + WindowHeight > Screen->Height)
X      WindowTop = Screen->Height - WindowHeight;
X    if (WindowTop < 0)
X      WindowTop = 0;
X
X    ItemWindow->TopEdge   = WindowTop;
X    ItemWindow->TopValue  = TopValue - WindowTop;
X    ItemWindow->Height	  = WindowHeight;
X  }
X
X  if (BuildBitMap(ItemWindow) == FALSE)
X    return;
X
X  DrawAllItems(ItemWindow);
X}
X
X/****************************************
X * DrawAllItems(ItemWindow)             *
X *					*
X * Input:				*
X *   ItemWindow  - Window to draw into. *
X *					*
X * Output				*
X *   none				*
X ****************************************/
XVOID DrawAllItems(ItemWindow)
X  struct WindowData *const ItemWindow;
X{
X  struct MenuItem *Item = ItemWindow->Items;
X
X  ClearWindow(ItemWindow);
X
X  do
X    DrawMenuItem(Item, ItemWindow, ITEMFILL, DONTCLEAROLD);
X  while ((Item = Item->NextItem) != NULL);
X}
X
X/****************************************************************************
X * DrawMenuItem(Item, ItemWindow, Mode, Clear)                              *
X *									    *
X * Input:								    *
X *   Item -	  Item to draw. 					    *
X *   ItemWindow - Data about window to draw item into			    *
X *   Mode -	  ITEMFILL = Draw Item					    *
X *		  SELECTFILL = Draw selected item (if any)                  *
X *   Clear -	  Clear position before drawing  (Only used with HighImage) *
X * OUTPUT								    *
X *   none								    *
X ****************************************************************************/
X
XVOID DrawMenuItem(Item,ItemWindow,Mode,Clear)
X  struct MenuItem *const Item;
X  struct WindowData  *const ItemWindow;
X  const UWORD Mode;
X  const BOOL   Clear;
X{
X/*
X  IMPORT UWORD far GhostPattern[2];
X  IMPORT UWORD far NormalPattern[2];
X  IMPORT struct Image far MyAmigaKeyImage[2];
X  IMPORT struct Image far MySubItemImage[2];
X*/
X
X  IMPORT struct RastPort Rp;
X  IMPORT struct Window	*const ActiveWindow;
X  IMPORT struct Screen	*const Screen;
X  IMPORT const BOOL  ScreenType;
X
X  union FillTypes Fill;
X  const LONG Left = Item->LeftEdge - ItemWindow->LeftValue;
X  const LONG Right = Left + Item->Width - 1;
X  const LONG Top = Item->TopEdge - ItemWindow->TopValue;
X  const LONG Bottom = Top + Item->Height - 1;
X
X  /* Find what to Draw */
X  if (!(Fill.APTR = (Mode == SELECTFILL) ? Item->SelectFill : Item->ItemFill))
X    return;  /* nothing to draw */
X
X  SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
X  SetDrMd(&Rp, JAM1);
X
X  if (Clear)
X    /* Erase whay may already be here */
X    RectFill(&Rp, Left, Top, Right, Bottom);
X
X  /* Now, draw the item itself -- depending on the Flag value, it    */
X  /* could be either an Image or an IntuiText */
X
X  if (Item->Flags & ITEMTEXT)
X    PrintIText(&Rp, Fill.IText, Left, Top);
X  else
X    DrawImage(&Rp,  Fill.Image, Left, Top);
X
X  /* If the item is checkmarked, draw the checkmark. */
X
X  if ((Item->Flags & (CHECKIT | CHECKED)) == (CHECKIT | CHECKED))
X    DrawImage(&Rp, ActiveWindow->CheckMark, Left, Top);
X
X  /* If the item has a commandkey, or a subitem */
X  {
X    const LONG ItemTop	= Top + ((Item->Flags & ITEMTEXT) ?
X					 Fill.IText->TopEdge:
X					 Fill.Image->TopEdge);
X
X    if (Item->Flags & COMMSEQ) {
X      const LONG KeyLeft = Right - Rp.TxWidth;
X
X      DrawImage(&Rp, &MyAmigaKeyImage[ScreenType],KeyLeft, ItemTop);
X
X      Move(&Rp, KeyLeft, ItemTop + Rp.TxHeight - 2);
X      SetAPen(&Rp, (LONG)(ActiveWindow->DetailPen));
X      Text(&Rp,&Item->Command,1);
X    }
X
X    if (Item->SubItem)
X      DrawImage(&Rp,&MySubItemImage[ScreenType],Right,ItemTop);
X  }
X
X  /* If the ITEMENABLED flag is not set, "ghost" the item. */
X
X  if (!(Item->Flags & ITEMENABLED)) {
X    SetAfPt(&Rp, GhostPattern, 1);
X    SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
X    RectFill(&Rp, Left, Top, Right, Bottom);
X    SetAfPt(&Rp, NormalPattern, 1);
X  }
X}
X
X/****************************************
X * BuildBitMap(Window)  - OpenWindow    *
X *					*
X * Input:				*
X *   Window    - Window to open.	*
X * Output:				*
X *   return    - TRUE if window opened. *
X ****************************************/
XBOOL BuildBitMap(Window)
X  struct WindowData *const Window;
X{
X  IMPORT struct Screen	 *const Screen;
X  IMPORT struct RastPort Rp;
X
X  const LONG WindowWidth  = Window->Width;
X  const LONG WindowHeight = Window->Height;
X
X  /* is window to big for screen ? */
X
X  if ((WindowWidth > Screen->Width) OR
X      (WindowHeight > Screen->Height))
X    return (FALSE);
X
X  Window->RightEdge = Window->LeftEdge + WindowWidth  - 1;
X  Window->Bottom    = Window->TopEdge  + WindowHeight - 1;
X
X  /* init bitmap */
X  {
X    const ULONG Depth = Screen->BitMap.Depth;
X    UWORD i;
X
X    InitBitMap(&Window->Bm,Depth,WindowWidth,WindowHeight);
X
X    /* allocate raster for all bitplanes */
X
X    for (i = 0; i < Depth; i++)
X      if ((Window->Bm.Planes[i] = AllocRaster(WindowWidth,WindowHeight)) == NULL) {
X	RemoveBitMap(Window);
X	return(FALSE);
X      }
X  }
X
X  Window->BitMapOk = TRUE;
X
X  /* make window visible */
X  SwapBits(Window);
X
X  ClearWindow(Window);
X
X  return (TRUE);
X}
X
X/*********************************
X * ClearWindow(window)           *
X *				 *
X * Input:			 *
X *   Window   - Window to clear. *
X * OutPut:			 *
X *   none			 *
X *********************************/
XVOID ClearWindow(Window)
X  struct WindowData *const Window;
X{
X  IMPORT struct RastPort Rp;
X  IMPORT struct Window *const ActiveWindow;
X
X  /* window should look like intuitionmenues */
X  SetDrMd(&Rp, JAM1);
X
X  SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
X  SetOPen(&Rp,(LONG)ActiveWindow->DetailPen);
X
X  RectFill(&Rp,(LONG)Window->LeftEdge,
X	       (LONG)Window->TopEdge,
X	       (LONG)Window->RightEdge,
X	       (LONG)Window->Bottom);
X  BNDRYOFF(&Rp);
X}
X
X/******************************
X * CloseItemWindow(Window)    *
X *			      *
X *INPUT 		      *
X *  Window - Window to close. *
X *OUTPUT		      *
X *  none		      *
X ******************************/
XVOID CloseItemWindow(Window)
X  struct WindowData *const Window;
X{
X  if (Window->BitMapOk) {
X    /* remove window from screen */
X    SwapBits(Window);
X
X    /* remove all bitplanes */
X    RemoveBitMap(Window);
X  }
X}
X
X/****************************************************************************
X * RemoveBitMap(Window) - Remove allocated rasters in the BitMap structure. *
X *									    *
X * Input:								    *
X *   Window   - Window with bitmap-					    *
X * Output:								    *
X *   none								    *
X ****************************************************************************/
XVOID RemoveBitMap(Window)
X  struct WindowData *const Window;
X{
X  struct BitMap *const Bm = &Window->Bm;
X  UWORD  i;
X
X  /* remove all allocated rasters */
X  for (i = 0; i < Bm->Depth; i++)
X    if (Bm->Planes[i])
X      FreeRaster(Bm->Planes[i],(LONG)Window->Width,(LONG)Window->Height);
X
X  Window->BitMapOk = FALSE;
X}
X
END_OF_FILE
if test 12815 -ne `wc -c <'Source/OpenWindows.c'`; then
    echo shar: \"'Source/OpenWindows.c'\" unpacked with wrong size!
fi
# end of 'Source/OpenWindows.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.