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 >
Wrap
C/C++ Source or Header
|
1990-05-06
|
13KB
|
454 lines
#include "PopUpMenu.h"
/* these must be declared here in this silly way (lattice 5.0 bug) */
IMPORT UWORD chip GhostPattern[];
IMPORT WORD far NormalPattern[];
IMPORT struct Image chip MyAmigaKeyImage[];
IMPORT struct Image far MySubItemImage[];
/****************************************
* OpenMenuWindow() *
* *
* Input: *
* none *
* Output: *
* return - TRUE if window opened. *
****************************************/
BOOL OpenMenuWindow(MenuTop)
WORD MenuTop;
{
/*
IMPORT UWORD far GhostPattern[2];
IMPORT UWORD far NormalPattern[2];
*/
IMPORT struct Window *const ActiveWindow;
IMPORT struct Menu *const Menues;
IMPORT struct Screen *const Screen;
IMPORT struct RastPort Rp; /* Screens RastPort */
IMPORT struct WindowData MenuWindow;
IMPORT const UWORD MenuFontSize;
WORD MenuWidth = 0;
WORD MenuHeight = BORDERSIZE + 1;
/****************************************
* Find width & height of window needed *
****************************************/
{
struct Menu *MenuPtr = Menues;
do {
UWORD Length;
Length = TextLength(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
if (MenuPtr->Width > Length)
Length = MenuPtr->Width;
if (Length > MenuWidth)
MenuWidth = Length;
MenuHeight += MenuFontSize;
}
while ((MenuPtr = MenuPtr->NextMenu) != NULL);
MenuWidth += (2 * BORDERSIZE + 1);
}
/************************************
* Position window on screen (Left) *
************************************/
{
WORD MenuLeft = Screen->MouseX - ((UWORD)MenuWidth / 2);
if (MenuLeft < 0)
MenuLeft = 0;
if (MenuLeft + MenuWidth > Screen->Width)
MenuLeft = Screen->Width - MenuWidth;
MenuWindow.LeftEdge = MenuLeft;
MenuWindow.Width = MenuWidth;
}
/***********************************
* Position window on screen (Top) *
***********************************/
{
if (MenuTop > MenuHeight) /* menues has changed */
MenuTop = 0;
MenuTop = Screen->MouseY - (MenuFontSize / 2) - MenuTop;
if (MenuTop < 0)
MenuTop = 0;
if (MenuTop + MenuHeight > Screen->Height)
MenuTop = Screen->Height - MenuHeight;
MenuWindow.TopEdge = MenuTop;
MenuWindow.Height = MenuHeight;
}
/*******************************
* Open window with right size *
*******************************/
if (BuildBitMap(&MenuWindow) == FALSE)
return (FALSE);
/**********************
* Fill in all menues *
**********************/
{
const LONG MenuLeft = MenuWindow.LeftEdge + BORDERSIZE;
struct Menu *MenuPtr = Menues;
do {
MenuTop += MenuFontSize;
SetAPen(&Rp,(LONG)ActiveWindow->DetailPen);
Move(&Rp,MenuLeft,(LONG)MenuTop - 1);
Text(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName));
/* Ghostitem ? */
if (NOT (MenuPtr->Flags & MENUENABLED)) {
SetAfPt(&Rp, GhostPattern, 1);
SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
RectFill(&Rp,MenuLeft,
(LONG)(MenuTop - MenuFontSize + BORDERSIZE),
(LONG)(MenuWindow.RightEdge - BORDERSIZE),
(LONG)MenuTop);
SetAfPt(&Rp,NormalPattern,1);
}
}
while ((MenuPtr = MenuPtr->NextMenu) != NULL);
}
return (TRUE);
}
/**************************************************************
* OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType) *
* *
* Input: *
* ItemWindow - Window to open. *
* ParentWindow - *
* TopPos - Top position for new window. *
* WindowType - ITEMWINDOW or SUBWINDOW *
* Output: *
* none *
**************************************************************/
VOID OpenItemWindow(ItemWindow,ParentWindow,TopPos,WindowType)
struct WindowData *const ItemWindow;
struct WindowData *const ParentWindow;
const WORD TopPos;
const UWORD WindowType;
{
IMPORT struct Screen *const Screen;
IMPORT struct WindowData MenuWindow;
IMPORT const WORD MouseX;
struct WindowSize Size;
/****************************************
* Find width & height of window needed *
****************************************/
{
struct MenuItem *Item = ItemWindow->Items;
Size.Left = WORD_MAX;
Size.Top = WindowType; /* (ITEMWINDOW -> TopPos >= 0), SUBWINDOW -> no limit */
Size.Right = Size.Bottom = WORD_MIN;
do {
CheckItemSize(&Size,Item,(LONG)Item->ItemFill);
if ((Item->Flags & HIGHFLAGS) == HIGHIMAGE)
CheckItemSize(&Size,Item,(LONG)Item->SelectFill); /* check highlighted */
}
while (Item = Item->NextItem);
}
/**********************************************
* Position window on screen (left) *
* Possible positions: *
* 1. At real position (a'la intuition). *
* 2. At right side of parent. *
* 3. At left side of parent. *
* 4. On the side that covers parent least. *
**********************************************/
{
WORD WindowLeft;
WORD LeftValue = Size.Left - BORDERSIZE;
UWORD WindowWidth = Size.Right - LeftValue + BORDERSIZE;
WORD LeftPos2 = ParentWindow->LeftEdge - WindowWidth + 7;
WORD MaxLeft = Screen->Width - WindowWidth;
if ((WindowType == ITEMWINDOW) OR
((WindowLeft = ParentWindow->LeftEdge + LeftValue) > MaxLeft) OR
(WindowLeft < 0))
WindowLeft = ParentWindow->RightEdge - 7;
if (WindowLeft > MaxLeft)
if (LeftPos2 > MaxLeft - WindowLeft)
WindowLeft = (LeftPos2 > 0) ? LeftPos2 : 0;
else
WindowLeft = MaxLeft;
if (WindowLeft + WindowWidth < ParentWindow->LeftEdge + 7)
WindowWidth = ParentWindow->LeftEdge + 7 - WindowLeft;
ItemWindow->LeftEdge = WindowLeft;
ItemWindow->LeftValue = LeftValue - WindowLeft;
ItemWindow->Width = WindowWidth;
}
/***********************************
* Position Window on screen (Top) *
***********************************/
{
WORD TopValue = Size.Top - BORDERSIZE;
WORD WindowTop = TopPos + TopValue;
UWORD WindowHeight = Size.Bottom - TopValue + BORDERSIZE;
if (WindowTop + WindowHeight > Screen->Height)
WindowTop = Screen->Height - WindowHeight;
if (WindowTop < 0)
WindowTop = 0;
ItemWindow->TopEdge = WindowTop;
ItemWindow->TopValue = TopValue - WindowTop;
ItemWindow->Height = WindowHeight;
}
if (BuildBitMap(ItemWindow) == FALSE)
return;
DrawAllItems(ItemWindow);
}
/****************************************
* DrawAllItems(ItemWindow) *
* *
* Input: *
* ItemWindow - Window to draw into. *
* *
* Output *
* none *
****************************************/
VOID DrawAllItems(ItemWindow)
struct WindowData *const ItemWindow;
{
struct MenuItem *Item = ItemWindow->Items;
ClearWindow(ItemWindow);
do
DrawMenuItem(Item, ItemWindow, ITEMFILL, DONTCLEAROLD);
while ((Item = Item->NextItem) != NULL);
}
/****************************************************************************
* DrawMenuItem(Item, ItemWindow, Mode, Clear) *
* *
* Input: *
* Item - Item to draw. *
* ItemWindow - Data about window to draw item into *
* Mode - ITEMFILL = Draw Item *
* SELECTFILL = Draw selected item (if any) *
* Clear - Clear position before drawing (Only used with HighImage) *
* OUTPUT *
* none *
****************************************************************************/
VOID DrawMenuItem(Item,ItemWindow,Mode,Clear)
struct MenuItem *const Item;
struct WindowData *const ItemWindow;
const UWORD Mode;
const BOOL Clear;
{
/*
IMPORT UWORD far GhostPattern[2];
IMPORT UWORD far NormalPattern[2];
IMPORT struct Image far MyAmigaKeyImage[2];
IMPORT struct Image far MySubItemImage[2];
*/
IMPORT struct RastPort Rp;
IMPORT struct Window *const ActiveWindow;
IMPORT struct Screen *const Screen;
IMPORT const BOOL ScreenType;
union FillTypes Fill;
const LONG Left = Item->LeftEdge - ItemWindow->LeftValue;
const LONG Right = Left + Item->Width - 1;
const LONG Top = Item->TopEdge - ItemWindow->TopValue;
const LONG Bottom = Top + Item->Height - 1;
/* Find what to Draw */
if (!(Fill.APTR = (Mode == SELECTFILL) ? Item->SelectFill : Item->ItemFill))
return; /* nothing to draw */
SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
SetDrMd(&Rp, JAM1);
if (Clear)
/* Erase whay may already be here */
RectFill(&Rp, Left, Top, Right, Bottom);
/* Now, draw the item itself -- depending on the Flag value, it */
/* could be either an Image or an IntuiText */
if (Item->Flags & ITEMTEXT)
PrintIText(&Rp, Fill.IText, Left, Top);
else
DrawImage(&Rp, Fill.Image, Left, Top);
/* If the item is checkmarked, draw the checkmark. */
if ((Item->Flags & (CHECKIT | CHECKED)) == (CHECKIT | CHECKED))
DrawImage(&Rp, ActiveWindow->CheckMark, Left, Top);
/* If the item has a commandkey, or a subitem */
{
const LONG ItemTop = Top + ((Item->Flags & ITEMTEXT) ?
Fill.IText->TopEdge:
Fill.Image->TopEdge);
if (Item->Flags & COMMSEQ) {
const LONG KeyLeft = Right - Rp.TxWidth;
DrawImage(&Rp, &MyAmigaKeyImage[ScreenType],KeyLeft, ItemTop);
Move(&Rp, KeyLeft, ItemTop + Rp.TxHeight - 2);
SetAPen(&Rp, (LONG)(ActiveWindow->DetailPen));
Text(&Rp,&Item->Command,1);
}
if (Item->SubItem)
DrawImage(&Rp,&MySubItemImage[ScreenType],Right,ItemTop);
}
/* If the ITEMENABLED flag is not set, "ghost" the item. */
if (!(Item->Flags & ITEMENABLED)) {
SetAfPt(&Rp, GhostPattern, 1);
SetAPen(&Rp, (LONG)(ActiveWindow->BlockPen));
RectFill(&Rp, Left, Top, Right, Bottom);
SetAfPt(&Rp, NormalPattern, 1);
}
}
/****************************************
* BuildBitMap(Window) - OpenWindow *
* *
* Input: *
* Window - Window to open. *
* Output: *
* return - TRUE if window opened. *
****************************************/
BOOL BuildBitMap(Window)
struct WindowData *const Window;
{
IMPORT struct Screen *const Screen;
IMPORT struct RastPort Rp;
const LONG WindowWidth = Window->Width;
const LONG WindowHeight = Window->Height;
/* is window to big for screen ? */
if ((WindowWidth > Screen->Width) OR
(WindowHeight > Screen->Height))
return (FALSE);
Window->RightEdge = Window->LeftEdge + WindowWidth - 1;
Window->Bottom = Window->TopEdge + WindowHeight - 1;
/* init bitmap */
{
const ULONG Depth = Screen->BitMap.Depth;
UWORD i;
InitBitMap(&Window->Bm,Depth,WindowWidth,WindowHeight);
/* allocate raster for all bitplanes */
for (i = 0; i < Depth; i++)
if ((Window->Bm.Planes[i] = AllocRaster(WindowWidth,WindowHeight)) == NULL) {
RemoveBitMap(Window);
return(FALSE);
}
}
Window->BitMapOk = TRUE;
/* make window visible */
SwapBits(Window);
ClearWindow(Window);
return (TRUE);
}
/*********************************
* ClearWindow(window) *
* *
* Input: *
* Window - Window to clear. *
* OutPut: *
* none *
*********************************/
VOID ClearWindow(Window)
struct WindowData *const Window;
{
IMPORT struct RastPort Rp;
IMPORT struct Window *const ActiveWindow;
/* window should look like intuitionmenues */
SetDrMd(&Rp, JAM1);
SetAPen(&Rp,(LONG)ActiveWindow->BlockPen);
SetOPen(&Rp,(LONG)ActiveWindow->DetailPen);
RectFill(&Rp,(LONG)Window->LeftEdge,
(LONG)Window->TopEdge,
(LONG)Window->RightEdge,
(LONG)Window->Bottom);
BNDRYOFF(&Rp);
}
/******************************
* CloseItemWindow(Window) *
* *
*INPUT *
* Window - Window to close. *
*OUTPUT *
* none *
******************************/
VOID CloseItemWindow(Window)
struct WindowData *const Window;
{
if (Window->BitMapOk) {
/* remove window from screen */
SwapBits(Window);
/* remove all bitplanes */
RemoveBitMap(Window);
}
}
/****************************************************************************
* RemoveBitMap(Window) - Remove allocated rasters in the BitMap structure. *
* *
* Input: *
* Window - Window with bitmap- *
* Output: *
* none *
****************************************************************************/
VOID RemoveBitMap(Window)
struct WindowData *const Window;
{
struct BitMap *const Bm = &Window->Bm;
UWORD i;
/* remove all allocated rasters */
for (i = 0; i < Bm->Depth; i++)
if (Bm->Planes[i])
FreeRaster(Bm->Planes[i],(LONG)Window->Width,(LONG)Window->Height);
Window->BitMapOk = FALSE;
}