home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
l
/
l-coll1.zip
/
TOOLLIBR.ZOO
/
ToolLibrary
/
src
/
SimpleMenu.c
< prev
next >
Wrap
Text File
|
1990-11-02
|
11KB
|
393 lines
/********************************************************************/
/**** ****/
/**** ****/
/**** Program : SimpleMenu.c ****/
/**** ****/
/**** Version : 03.71 ****/
/**** ****/
/**** Erstversion : 14.03.1990 ****/
/**** ****/
/**** Letzte ─nderung : 08.08.1990 ****/
/**** ****/
/**** Compiliert mit : siehe MAKEFILE ****/
/**** ****/
/**** Gelinkt mit : siehe MAKEFILE ****/
/**** ****/
/********************************************************************/
/**** ****/
/**** ****/
/**** Copyright by Rⁿdiger Dreier ****/
/**** ****/
/**** ****/
/********************************************************************/
#include <exec/types.h>
#include <stdio.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <stdio.h>
#include <string.h>
/* Gibt Zeiger auf das letzte definierte Menu zurⁿck */
struct Menu * __asm LastMenu(register __a0 struct Menu *menu)
{
if(menu==NULL)return(NULL); /* Kein Menu definiert */
while(menu->NextMenu!=NULL)
{
menu=menu->NextMenu;
}
return(menu);
}
/* Gibt Zeiger auf das letzte definierte Item zurⁿck */
struct MenuItem * __asm LastItem(register __a0 struct Menu *menu)
{
struct MenuItem *item;
if(menu==NULL)return(NULL); /* Kein Menu definiert */
menu=LastMenu(menu); /* Der letzte MenuPunkt */
item=menu->FirstItem;
if(item==NULL)return(NULL); /* Kein Item */
while(item->NextItem!=NULL)
{
item=item->NextItem;
}
return(item); /* Das letzte Item */
}
/* Gibt Zeiger auf das letzte definierte SubItem zurⁿck */
struct MenuItem * __asm LastSub(register __a0 struct Menu *menu)
{
struct MenuItem *item,*sub;
if(menu==NULL)return(NULL); /* Kein Menu definiert */
item=LastItem(menu); /* Der letzte ItemPunkt */
sub=item->SubItem;
if(sub==NULL)return(NULL); /* Kein SubItem */
while(sub->NextItem!=NULL)
{
sub=sub->NextItem;
}
return(sub); /* Das letzte SubItem */
}
/* HΣngt ein Menu an */
struct Menu * __asm AddMenu(register __a0 struct Menu *menu,
register __a1 char *Titel,
register __d0 USHORT Flags)
{
struct Menu *newmenu,*lastmenu;
struct IntuiText Hilfe;
newmenu=AllocMem(sizeof(struct Menu),MEMF_CLEAR|MEMF_PUBLIC);
if(newmenu==NULL)return(NULL); /* Kein Speicher fⁿr Menu */
/* Den Speicher hab ich jetzt. Jetzt kann die Struktur */
/* gefⁿllt werden. */
lastmenu=LastMenu(menu);
if(lastmenu!=NULL)
{
/* Wenn schon ein Menu vorhanden, sonst 0 */
newmenu->LeftEdge=lastmenu->LeftEdge+lastmenu->Width;
lastmenu->NextMenu=newmenu;
}
newmenu->MenuName=Titel;
newmenu->Flags=Flags;
Hilfe.ITextFont=0;
Hilfe.IText=Titel;
newmenu->Width=(IntuiTextLength(&Hilfe)+8);
return(newmenu); /* Ist das erste Menu */
}
/* HΣngt ein Item an */
struct Item * __asm AddItem(register __a0 struct Menu *menu,
register __a1 char *Titel,
register __d0 USHORT Flags,
register __d1 char HotKey)
{
struct Menu *lastmenu;
struct MenuItem *newitem,*lastitem;
newitem=GetItem(menu,Titel,Flags,HotKey); /* Speicher fⁿr Item holen */
if(!newitem)return(NULL);
lastmenu=LastMenu(menu);
lastitem=LastItem(menu);
if(lastitem==NULL) /* Item in Liste einfⁿgen */
{
lastmenu->FirstItem=newitem;
}
else
{
lastitem->NextItem=newitem;
}
return(newitem);
}
/* HΣngt ein SubItem an */
struct Item * __asm AddSub(register __a0 struct Menu *menu,
register __a1 char *Titel,
register __d0 USHORT Flags,
register __d1 char HotKey)
{
struct MenuItem *newsub,*lastitem,*lastsub;
lastitem=LastItem(menu);
lastsub =LastSub(menu);
if(lastitem==NULL)return(NULL); /* Ohne Item kein SubItem */
newsub=GetItem(menu,Titel,Flags,HotKey); /* Speicher fⁿr Item holen */
if(newsub==NULL)return(NULL); /* Kein Speicher fⁿr Item */
if(lastsub==NULL) /* Item in Liste einfⁿgen */
{
lastitem->SubItem=newsub;
}
else
{
lastsub->NextItem=newsub;
}
return(newsub);
}
/* Holt und fⁿllt dem Speicher fⁿr ein Item oder SubItem */
struct MenuItem * __asm GetItem(register __a0 struct Menu *menu,
register __a1 char *Titel,
register __d0 USHORT Flags,
register __d1 char HotKey)
{
struct IntuiText *newtext;
struct MenuItem *newitem;
SHORT addwidth=0;
if(menu==NULL)return(NULL); /* Ohne Menu kein Item */
if(Titel==NULL)return(NULL); /* Ohne Text oder Grafik kein Item */
newitem=AllocMem(sizeof(struct MenuItem),MEMF_CLEAR|MEMF_PUBLIC);
if(newitem==NULL)return(NULL); /* Kein Speicher fⁿr Menu */
if(Titel&&(Flags&ITEMTEXT))
{
/* Nur, wenn keine Grafik */
newtext=AllocMem(sizeof(struct IntuiText),MEMF_CLEAR|MEMF_PUBLIC);
if(newtext==NULL)
{
/* Kein Speicher fⁿr IntuiText */
FreeMem(newitem,sizeof(struct MenuItem));
return(NULL);
}
/* Den Speicher hab ich jetzt. Jetzt k÷nnen die Strukturen */
/* gefⁿllt werden. */
if(menu->FirstItem)
{
newtext->FrontPen=((struct IntuiText *)menu->FirstItem->ItemFill)->FrontPen;
newtext->BackPen =((struct IntuiText *)menu->FirstItem->ItemFill)->BackPen;
newtext->DrawMode=((struct IntuiText *)menu->FirstItem->ItemFill)->DrawMode;
}
else
{
newtext->FrontPen=2; /* BackPen = 0 */
newtext->DrawMode=JAM1;
}
newtext->IText=Titel;
newtext->LeftEdge=3;
}
if(Flags&COMMSEQ)addwidth=40; /* reicht fⁿr Standart-Symbol */
if(Flags&ITEMTEXT)
{
newitem->ItemFill=(APTR)newtext;
newitem->Width=IntuiTextLength(newtext)+addwidth+7;
}
else
{
newitem->ItemFill=(APTR)Titel;
newitem->Width=addwidth+((struct Image *)Titel)->Width+((struct Image *)Titel)->LeftEdge;
newitem->Height=((struct Image *)Titel)->Height+((struct Image *)Titel)->TopEdge;
}
newitem->Flags=Flags;
newitem->Command=HotKey;
return(newitem);
}
/* Gibt den ganzen Speicher wieder frei */
VOID __asm ClearMenu(register __a0 struct Menu *menu)
{
struct MenuItem *item,*sub;
if(menu==NULL)return;
while(menu)
{
item=menu->FirstItem;
while(item)
{
sub=item->SubItem;
while(sub)
{
sub=FreeItem(sub);
}
item=FreeItem(item);
}
menu=FreeMenu(menu);
}
}
struct MenuItem * __asm FreeItem(register __a0 struct MenuItem *item)
{
struct MenuItem *next=item->NextItem;
if((item->Flags&ITEMTEXT))FreeMem(item->ItemFill,sizeof(struct IntuiText));
FreeMem(item,sizeof(struct MenuItem));
return(next);
}
struct Menu * __asm FreeMenu(register __a0 struct Menu *menu)
{
struct Menu *next=menu->NextMenu;
FreeMem(menu,sizeof(struct Menu));
return(next);
}
/* Gleicht die H÷he der Items an, je nach Font im RastPort */
VOID __asm NewSetMenuStrip(register __a1 struct Window *Window,
register __a0 struct Menu *menu)
{
struct MenuItem *item,*sub;
struct Menu *MENU;
SHORT hoehe,topedges,topedgei,maxwidthi,maxwidths,diff,v;
if(menu==NULL)return; /* Notausgang */
MENU=menu; /* Merken */
hoehe=Window->RPort->TxHeight; /* Fonth÷he */
v=Window->WScreen->Height-16; /* H÷he des Screen */
while(menu)
{
item=menu->FirstItem;
if(item)topedgei=item->TopEdge;
while(item)
{
sub=item->SubItem;
if(sub)topedges=5;
while(sub)
{
/* Subs einpassen */
sub->TopEdge=topedges;
if(sub->Height==NULL)
{
sub->Height=hoehe;
topedges+=hoehe;
}
else
{
topedges+=sub->Height;
}
sub=sub->NextItem;
if(!sub)
{
diff=v-topedges-topedgei;
/* Hier wird kontrolliert, ob die SubItems zu weit nach unten reichen */
/* Wenn dies der Fall ist, werden sie nach oben verschoben. */
/* Es wird NICHT geprⁿft, ob sie dadurch zu weit nach oben reichen. */
/* Der Vergleichswert von 240 gilt fⁿr eine Screen mit 256 Zeichen. */
if(diff<0)
{
sub=item->SubItem;
while(sub)
{
sub->TopEdge+=diff;
sub=sub->NextItem;
}
}
}
}
/* Items einpassen */
item->TopEdge=topedgei;
if(item->Height==NULL)
{
item->Height=hoehe;
topedgei+=hoehe;
}
else
{
topedgei+=item->Height;
}
item=item->NextItem;
}
menu=menu->NextMenu;
}
menu=MENU;
while(menu)
{
maxwidthi=menu->Width;
item=menu->FirstItem;
while(item)
{
/* 1. Pass: maxwidth feststellen */
maxwidths=0;
sub=item->SubItem;
while(sub)
{
/* 1. Pass: maxwidth feststellen */
maxwidths=max(sub->Width,maxwidths);
sub=sub->NextItem;
}
sub=item->SubItem;
while(sub)
{
/* 2. Pass: maxwidth einsetzen */
sub->Width=maxwidths;
sub=sub->NextItem;
}
/* Items einpassen */
maxwidthi=max(item->Width,maxwidthi);
item=item->NextItem;
}
item=menu->FirstItem;
while(item)
{
/* 2. Pass: maxwidth einsetzen */
item->Width=maxwidthi;
sub=item->SubItem;
while(sub)
{
/* In der Hoffnung, da▀ jedes Item mind. */
/* 5 Pixel breit ist.... */
sub->LeftEdge=max(maxwidthi/2,maxwidthi-sub->Width/2);
sub=sub->NextItem;
}
item=item->NextItem;
}
menu=menu->NextMenu;
}
SetMenuStrip(Window,MENU);
}