/* * Control_panel.c -- opens a small window giving user general options. * $Revision: 1.3 */ #include "header.h" #include "prog-protos.h" #include /* Prototypes */ Prototype BOOL open_control_panel (struct HolePrefs *); Prototype void close_control_panel (void); /* Shared variables */ Prototype struct HolePanel *panel; Local struct Gadget *create_gadgets (struct NewGadget *); Local void refresh_window (void); Local BOOL initialise (void); /* Globals */ struct Gadget *glist = NULL; struct Screen *pubsc = NULL; struct HolePanel *panel = NULL; struct IBox *winsize = NULL; struct IBox *basbox; = NULL; struct RastPort *TextRP = NULL; struct TextFont *font = NULL; struct DisplayInfo *di = NULL; APTR *vi = NULL; /* VisualInfo */ /* Statics */ static const char *msg_ignoreprot = "Ignore Protection"; static const char *msg_confirm = "Confirm deletion"; static const char *msg_limit = "Delete Limit"; static const char *but_snapshot = "Snapshot"; static const char *but_unsnapshot = "UnSnapshot"; static const char *but_save = "Save"; static const char *but_use = "Use"; static const char *but_cancel = "Cancel"; static const char *but_quit = "Quit"; static const char *but_about = "About"; /* Fill patterns */ static const UWORD white_grey[] = { 0x0000, 0x0000, 0x9999, 0x9999, }; static const UWORD blue_grey[] = { 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, }; /* Functions */ /* General startup - returns TRUE if ok */ BOOL initialise (void) { unless (winsize = malloc (sizeof (struct IBox))) return (FALSE); unless (basbox = malloc (sizeof (struct IBox))) return (FALSE); unless (panel = malloc (sizeof (struct HolePanel))) return (FALSE); unless (pubsc = LockPubScreen ("Workbench")) return (FALSE); unless (TextRP = malloc (sizeof (struct RastPort))) return (FALSE); unless (di = malloc (sizeof (struct DisplayInfo))) return (FALSE); unless (GetDisplayInfoData (NULL, (UBYTE *)di, sizeof (struct DisplayInfo), DTAG_DISP, GetVPModeID (&(pubsc->ViewPort)))) return (FALSE); /* Open the font into a rastport so we can use TextLength() */ unless (font = OpenFont (pubsc->Font)) return (FALSE); InitRastPort (TextRP); SetFont (TextRP, font); vi = GetVisualInfo (pubsc, TAG_END); return (TRUE); } void close_control_panel (void) { if (panel && panel->window) CloseWindow (panel->window); if (glist) FreeGadgets (glist); if (vi) FreeVisualInfo (vi); if (font) CloseFont (font); if (di) free (di); if (TextRP) free (TextRP); if (pubsc) UnlockPubScreen (NULL, pubsc); if (panel) free (panel); if (basbox) free (basbox); if (winsize) free (winsize); /* Tell everyone that the panel has closed down */ panel = glist = vi = font = di = TextRP = pubsc = basbox = winsize = NULL; } BOOL open_control_panel (struct HolePrefs *prefs_p) { if (panel->window) /* If window is already opened */ { WindowToFront (panel->window); ActivateWindow (panel->window); return (TRUE); } unless (initialise()) goto fail; panel->prefs = *prefs_p; /* put initial preferences into HolePanel struct */ struct NewGadget ng; winsize->Left = pubsc->WBorLeft; /* border at left edge of window */ winsize->Top = pubsc->WBorTop + pubsc->Font->ta_YSize + 1; winsize->Width = pubsc->WBorRight + winsize->Left; winsize->Height = pubsc->WBorBottom + winsize->Top; ng.ng_TextAttr = pubsc->Font; ng.ng_VisualInfo = vi; unless (create_gadgets (&ng)) goto fail; /* Find position of mouse pointer, so window can open over it */ { ULONG IBaseLock = LockIBase (0); winsize->Left = IntuitionBase->MouseX - (winsize->Width / 2); winsize->Top = IntuitionBase->MouseY - (winsize->Height / 2); UnlockIBase (IBaseLock); } unless (panel->window = OpenWindowTags ( NULL, WA_Left, winsize->Left, WA_Top, winsize->Top, WA_Width, winsize->Width, WA_Height, winsize->Height, WA_MinWidth, winsize->Width, WA_MinHeight, winsize->Height, WA_RMBTrap, TRUE, WA_AutoAdjust, TRUE, WA_PubScreen, pubsc, WA_SmartRefresh, TRUE, WA_DepthGadget, TRUE, WA_IDCMP, IDCMP_GADGETUP, WA_DragBar, TRUE, WA_Activate, TRUE, WA_Title, "Black Hole Options", TAG_DONE) ) goto fail; AddGList (panel->window, glist, ((UWORD) -1), ((UWORD) -1), NULL); refresh_window(); RefreshGList (glist, panel->window, NULL, ((UWORD) -1)); GT_RefreshWindow (panel->window, NULL); /* Perform the GadTools initial refresh */ return (TRUE); fail: close_control_panel(); return (FALSE); } void refresh_window (void) { /* Fill window with nice white/grey stipple pattern */ SetAfPt (panel->window->RPort, white_grey, -1); /* set up rp for pattern fill */ RectFill (panel->window->RPort, pubsc->WBorLeft, pubsc->WBorTop + pubsc->Font->ta_YSize + 1, winsize->Width - pubsc->WBorRight -1, winsize->Height - pubsc->WBorBottom -1 ); /* Fill indented box with blue/grey pattern */ SetAfPt (panel->window->RPort, blue_grey, -1); RectFill (panel->window->RPort, basbox->Left, basbox->Top, basbox->Left + basbox->Width -1, basbox->Top + basbox->Height -1 ); DrawBevelBox (panel->window->RPort, basbox->Left, basbox->Top, basbox->Width, basbox->Height, GTBB_Recessed, TRUE, GT_VisualInfo, vi, TAG_DONE ); } /* Macro to shorten a lot of lines in the next function */ #define textlen(x) (TextLength (TextRP, (x), strlen (x))) struct Gadget *create_gadgets (struct NewGadget *ng) { struct Gadget *gad = NULL; int but_width, but_height, xspace, yspace; /* Work out size of buttons, making them square. */ but_height = (TextRP->TxHeight * 3)/2; /* 3/2 times font height */ but_width = (but_height * di->Resolution.y) / di->Resolution.x; xspace = but_width / 2; /* general spacing value */ yspace = but_height / 2; gad = CreateContext (&glist); winsize->Left += xspace; /* Top corner of winsize is where corner */ winsize->Top += yspace; /* of Quit button will go. */ /* Now set up the IBox struct for the 3D box that surrounds some options */ /* I am going to pray that the Snapshot/UnSnapshot line will be the largest! */ basbox->Left = winsize->Left; basbox->Top = winsize->Top + but_height + yspace; basbox->Width = textlen (but_snapshot) + textlen (but_unsnapshot); basbox->Width += (3 * xspace) + (2 * but_width); /* Standard settings for most gadgets */ ng->ng_Height = but_height; ng->ng_Flags = PLACETEXT_IN; /* Up in the corner on Piccalo, Quit! */ if (gad) { ng->ng_LeftEdge = winsize->Left; ng->ng_TopEdge = winsize->Top; ng->ng_Width = but_width + textlen (but_quit); ng->ng_GadgetText = but_quit; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_QUIT; } /* Over on the right on guitar, About. Oh yes and he's broken a string! */ if (gad) { ng->ng_Width = but_width + textlen (but_about); ng->ng_LeftEdge = winsize->Left + basbox->Width - ng->ng_Width; ng->ng_GadgetText = but_about; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_ABOUT; } /* The next three want the text to their right */ ng->ng_Flags = PLACETEXT_RIGHT; /* Delete Limit */ if (gad) { ng->ng_Width = textlen ("555") + but_width; ng->ng_LeftEdge = winsize->Left + xspace; ng->ng_TopEdge = winsize->Top + (2 * yspace) + but_height; ng->ng_GadgetText = msg_limit; if (gad = CreateGadget (INTEGER_KIND, gad, ng, GTIN_Number, panel->prefs.deletelimit, GTIN_MaxChars, 2, TAG_END )) { gad->UserData = (APTR)GAD_LIMIT; panel->gad_limit = gad; } } /* Then a line below, Confirm Deletion */ if (gad) /* has to read some fields from it, so it must exist */ { ng->ng_Width = but_width; ng->ng_TopEdge = yspace + gad->TopEdge + gad->Height; ng->ng_GadgetText = msg_confirm; if (gad = CreateGadget (CHECKBOX_KIND, gad, ng, GTCB_Checked, panel->prefs.confirm, TAG_END )) { gad->UserData = (APTR)GAD_CONFIRM; panel->gad_confirm = gad; } } /* Ignore Protection */ if (gad) { ng->ng_TopEdge = yspace + gad->TopEdge + gad->Height; ng->ng_GadgetText = msg_ignoreprot; if (gad = CreateGadget (CHECKBOX_KIND, gad, ng, GTCB_Checked, panel->prefs.ignore_prot, TAG_END )) { gad->UserData = (APTR)GAD_IGNORE; panel->gad_ignore_prot = gad; } } /* Go back to putting text inside the hitbox */ ng->ng_Flags = PLACETEXT_IN; /* UnSnapShot button */ if (gad) { ng->ng_TopEdge = yspace + gad->TopEdge + gad->Height; ng->ng_LeftEdge = winsize->Left + xspace; ng->ng_Width = but_width + textlen (but_unsnapshot); ng->ng_GadgetText = but_unsnapshot; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_UNSNAP; } /* Now on drums, Sammy the Snapshot button. */ if (gad) { ng->ng_LeftEdge = winsize->Left + (2 * xspace) + gad->Width; ng->ng_Width = but_width + textlen (but_snapshot); ng->ng_GadgetText = but_snapshot; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_SNAP; } if (gad) basbox->Height = gad->TopEdge + but_height + yspace - basbox->Top; /* And down below on Timpani, Save, Use and Cancel. Keep bonging, guys! */ if (gad) { int right_edge_save, left_edge_cancel; ng->ng_TopEdge = (2 * yspace) + gad->TopEdge + gad->Height; ng->ng_LeftEdge = winsize->Left; ng->ng_Width = but_width + textlen (but_save); ng->ng_GadgetText = but_save; right_edge_save = ng->ng_LeftEdge + ng->ng_Width; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_SAVE; ng->ng_Width = but_width + textlen (but_cancel); ng->ng_LeftEdge = winsize->Left + basbox->Width - ng->ng_Width; ng->ng_GadgetText = but_cancel; left_edge_cancel = ng->ng_LeftEdge; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_CANCEL; ng->ng_Width = but_width + textlen (but_use); ng->ng_LeftEdge = (right_edge_save + left_edge_cancel - ng->ng_Width) / 2; ng->ng_GadgetText = but_use; if (gad = CreateGadget (BUTTON_KIND, gad, ng, TAG_END)) gad->UserData = (APTR)GAD_USE; } /* Set up size of window itself */ winsize->Width += (2 * xspace); winsize->Width += basbox->Width; winsize->Height += (2 * but_height) + (4 * yspace); winsize->Height += basbox->Height; return (gad); } #undef textlen(x)