LISTING 3 StrReq.c Program Including StringsRequest Function /************************************************************************** * * * StrReq.c -- (C) Copyright 1988, by Randy Finch * * * * This program may be FREELY DISTRIBUTED as long as this copyright * * notice remains intact. It is NOT PUBLIC DOMAIN. This code cannot * * be sold without the permission of Randy Finch. * * * * The function StringsRequest will create a requester with a user * * specified number of string gadgets. * * * **************************************************************************/ /*------------------- INCLUDE FILES ----------------------*/ #include #include #include #include /*-------------------- DEFINES ---------------------*/ #define OKGADGET 1 #define CANCELGADGET 2 #define LEFTMARGIN 10 #define RIGHTMARGIN 10 #define SPACER 5 #define CHARWIDTH 8 #define TOPMARGIN 15 #define BOTTOMMARGIN 15 #define PIXPERENTRY 15 #define MINSRWIDTH 130 /*---------------- GLOBAL VARIABLES ----------------*/ struct Remember *RememIntuiText = NULL; struct Remember *RememStringInfo = NULL; struct Remember *RememGadget = NULL; struct Remember *RememRequester = NULL; struct Remember *RememStringBuffer = NULL; struct Remember *RememUndoBuffer = NULL; /*----------------- ExitSR Function ------------------*/ void ExitSR() { if (RememIntuiText) FreeRemember(&RememIntuiText,TRUE); if (RememStringInfo) FreeRemember(&RememStringInfo,TRUE); if (RememGadget) FreeRemember(&RememGadget,TRUE); if (RememStringBuffer) FreeRemember(&RememStringBuffer,TRUE); if (RememUndoBuffer) FreeRemember(&RememUndoBuffer,TRUE); if (RememRequester) FreeRemember(&RememRequester,TRUE); } /* ExitSR */ /*----------------- MaxInArray Function ---------------*/ WORD MaxInArray(num, array) UBYTE num; WORD array[]; { UBYTE i; WORD max; max = MAX(array[0], array[1]); for (i = 2; i < num; ++i) max = MAX(array[i], max); return(max); } /* MaxInarray */ /*-------------------- MaxStrLenInArray -----------------*/ WORD MaxStrLenInArray(num, strings) UBYTE num; STRPTR strings[]; { UBYTE i; WORD max; max = MAX(strlen(strings[0]),strlen(strings[1])); for (i = 2; i < num; ++i) max = MAX(strlen(strings[i]),max); return(max); } /* MaxStrLenInArray */ /*---------------- StringsRequest FUNCTION ------------------------*/ BOOL StringsRequest(HeaderText, NumEntrys, BoxWidth, Titles, DefText, MaxLenDefText, TypeDefText, window) STRPTR HeaderText; UBYTE NumEntrys; WORD BoxWidth[]; STRPTR Titles[]; STRPTR DefText[]; WORD MaxLenDefText[]; WORD TypeDefText[]; struct Window *window; { /* Local variables */ WORD WidestBox; WORD WidestTitle; WORD WidestText; WORD WidestEntry; WORD SRWidth; WORD SRHeight; UBYTE i; STRPTR CurStrBufPointer; STRPTR UndoBufPointer; ULONG class; ULONG choice; struct Remember *StrBufPointer; struct Remember *ITextPointer; struct Remember *SInfoPointer; struct Remember *GPointer; struct Requester *ReqPointer; struct IntuiText *CurITextPointer; struct StringInfo *CurSInfoPointer; struct Gadget *CurGPointer; struct Gadget *LastGPointer; struct IntuiMessage *message; struct Gadget *gadget; /* Text Attribute */ static struct TextAttr plain8 = { (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; /* Header Text */ static struct IntuiText HeaderIText = { 2, 1, JAM2, 4, 3, &plain8, NULL, NULL }; /* OK Gadget */ static SHORT OKPoints[] = { -3,10, -3,-2, 51,-2, 51,10, -3,10, -2,11, 52,11, 52,-1 }; static struct Border OKBorder = { 0,0, 0,1,JAM1, 8, &OKPoints[0], NULL }; static struct IntuiText OKText = { 0,1,JAM2, 0,0, &plain8, " OK ", NULL }; static struct Gadget OKGadget = { NULL, 10,-14, 48,8, GADGHCOMP | GRELBOTTOM, GADGIMMEDIATE | ENDGADGET, BOOLGADGET | REQGADGET, (APTR) &OKBorder, NULL, &OKText, 0, NULL, OKGADGET, NULL }; /* Cancel Gadget */ static struct IntuiText CancelTxt = { 0,1,JAM2, 0,0, &plain8, "CANCEL", NULL }; static struct Gadget CancelGadg = { &OKGadget, -58,-14, 48,8, GADGHCOMP | GRELBOTTOM | GRELRIGHT, GADGIMMEDIATE | ENDGADGET, BOOLGADGET | REQGADGET, (APTR) &OKBorder, NULL, &CancelTxt, 0, NULL, CANCELGADGET, NULL }; static WORD SRPoints[] = { 2, 1, 128, 1, 128, 29, 2, 29, 2, 1, 2, 12, 128, 12, 128, 17, 2, 17 }; static struct Border SRBorder = { 0, 0, 0, 1, JAM1, 9, &SRPoints[0], NULL }; /*------------- Body of Function --------------*/ /* Initialize some variables */ HeaderIText.IText = HeaderText; WidestText = MaxInArray(NumEntrys, MaxLenDefText); WidestBox = MaxInArray(NumEntrys, BoxWidth); WidestEntry = MIN(WidestText, WidestBox); WidestTitle = MaxStrLenInArray(NumEntrys, Titles); SRWidth = LEFTMARGIN + RIGHTMARGIN + SPACER + (WidestEntry + WidestTitle) * CHARWIDTH; SRWidth = MAX(SRWidth, MINSRWIDTH); SRHeight = TOPMARGIN + BOTTOMMARGIN + NumEntrys * PIXPERENTRY; /* Set up Border structure points to match size of requester */ SRPoints[2] = SRPoints[4] = SRPoints[12] = SRPoints[14] = SRWidth - 3; SRPoints[5] = SRPoints[7] = SRHeight - 2; SRPoints[15] = SRPoints[17] = SRHeight - 20; /* Allocate memory for all IntuiText, StringInfo, Gadget, Requester, StrBuf, and UndoBuf structures */ for (i = 0; i < NumEntrys; ++i) { if ( ! AllocRemember(&RememIntuiText, sizeof(struct IntuiText), MEMF_CLEAR) || ! AllocRemember(&RememStringInfo, sizeof(struct StringInfo), MEMF_CLEAR) || ! AllocRemember(&RememGadget, sizeof(struct Gadget), MEMF_CLEAR) || ! AllocRemember(&RememStringBuffer, WidestText + 1, MEMF_CLEAR) ) { ExitSR(); return(FALSE); } } if ( ! AllocRemember(&RememRequester, sizeof(struct Requester), MEMF_CLEAR) || ! AllocRemember(&RememUndoBuffer, WidestText + 1, MEMF_CLEAR) ) { ExitSR(); return(FALSE); } ReqPointer = (struct Requester *) RememRequester->Memory; UndoBufPointer = (STRPTR) RememUndoBuffer->Memory; /* Initialize IntuiText structures */ ITextPointer = RememIntuiText; for (i = 0; i < NumEntrys; ++i) { CurITextPointer = (struct IntuiText *) ITextPointer->Memory; CurITextPointer->FrontPen = 0; CurITextPointer->BackPen = 1; CurITextPointer->DrawMode = JAM2; CurITextPointer->LeftEdge = -strlen(Titles[i]) * CHARWIDTH - SPACER; CurITextPointer->TopEdge = 0; CurITextPointer->ITextFont = &plain8; CurITextPointer->IText = Titles[i]; CurITextPointer->NextText = NULL; ITextPointer = ITextPointer->NextRemember; } /* Initialize StringInfo structures */ SInfoPointer = RememStringInfo; StrBufPointer = RememStringBuffer; for (i = 0; i < NumEntrys; ++i) { CurSInfoPointer = (struct StringInfo *) SInfoPointer->Memory; CurStrBufPointer = (STRPTR) StrBufPointer->Memory; CurSInfoPointer->Buffer = CurStrBufPointer; CurSInfoPointer->UndoBuffer = UndoBufPointer; CurSInfoPointer->BufferPos = 0; CurSInfoPointer->MaxChars = MaxLenDefText[i]; CurSInfoPointer->DispPos = 0; /* Other items maintained by Intuition */ strcpy(CurStrBufPointer, DefText[i]); SInfoPointer = SInfoPointer->NextRemember; StrBufPointer = StrBufPointer->NextRemember; } /* Initialize Gadgets */ LastGPointer = NULL; GPointer = RememGadget; ITextPointer = RememIntuiText; SInfoPointer = RememStringInfo; for (i = 0; i < NumEntrys; ++i) { CurGPointer = (struct Gadget *) GPointer->Memory; CurITextPointer = (struct IntuiText *) ITextPointer->Memory; CurSInfoPointer = (struct StringInfo *) SInfoPointer->Memory; CurGPointer->NextGadget = LastGPointer; CurGPointer->LeftEdge = -RIGHTMARGIN - WidestEntry * CHARWIDTH; CurGPointer->TopEdge = TOPMARGIN + i * PIXPERENTRY; CurGPointer->Width = BoxWidth[i] * CHARWIDTH; CurGPointer->Height = 8; CurGPointer->Flags = GADGHCOMP | GRELRIGHT; CurGPointer->Activation = TypeDefText[i]; CurGPointer->GadgetType = STRGADGET | REQGADGET; CurGPointer->GadgetRender = NULL; CurGPointer->SelectRender = NULL; CurGPointer->GadgetText = CurITextPointer; CurGPointer->MutualExclude = 0; CurGPointer->SpecialInfo = (APTR) CurSInfoPointer; CurGPointer->GadgetID = NULL; CurGPointer->UserData = NULL; LastGPointer = CurGPointer; GPointer = GPointer->NextRemember; ITextPointer = ITextPointer->NextRemember; SInfoPointer = SInfoPointer->NextRemember; } /* Set OKGadget NextGadget Pointer */ OKGadget.NextGadget = LastGPointer; /* Center Header Text */ HeaderIText.LeftEdge = (SRWidth-IntuiTextLength(&HeaderIText))/2; /* Initialize Requester */ InitRequester(ReqPointer); ReqPointer->LeftEdge = 10; ReqPointer->TopEdge = 12; ReqPointer->Width = SRWidth; ReqPointer->Height = SRHeight; ReqPointer->ReqGadget = &CancelGadg; ReqPointer->ReqText = &HeaderIText; ReqPointer->BackFill = 1; ReqPointer->Flags = 0; ReqPointer->ReqBorder = &SRBorder; if ( ! Request(ReqPointer, window)) { ExitSR(); return(FALSE); } RefreshGadgets(&CancelGadg, window, ReqPointer); /* Wait for Intuimessage */ class = GADGETDOWN; choice = CANCELGADGET; while (class != REQCLEAR) { if ((message = (struct IntuiMessage *) GetMsg(window->UserPort)) == 0L) { Wait(1L << window->UserPort->mp_SigBit); continue; } class = message->Class; gadget = (struct Gadget *) message->IAddress; ReplyMsg(message); if (class == GADGETDOWN) choice = gadget->GadgetID; } /* Handle OK and CANCEL */ if (choice == OKGADGET) { SInfoPointer = RememStringInfo; for (i = 0; i < NumEntrys; ++i) { CurSInfoPointer = (struct StringInfo *) SInfoPointer->Memory; strcpy(DefText[i], CurSInfoPointer->Buffer); SInfoPointer = SInfoPointer->NextRemember; } } ExitSR(); return(TRUE); } /* StringsRequester */