/********************************************************************/ /**** ****/ /**** ****/ /**** 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 #include #include #include #include #include #include #include #include #include #include /* 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); }