home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * Copyright (C) 1994 Charles P. Peterson *
- * 4007 Enchanted Sun, San Antonio, Texas 78244-1254 *
- * Email: Charles_P_Peterson@fcircus.sat.tx.us *
- * *
- * This is free software with NO WARRANTY. *
- * See gfft.c, or run program itself, for details. *
- * Support is available for a fee. *
- ***************************************************************************
- *
- * Program: gfft--General FFT analysis
- * File: wbtools.c
- * Purpose: workbench GUI toolkit for GFFT
- * Author: Charles Peterson (CPP)
- * History: 19-Nov-1993 CPP; Created.
- * 4-Aug-94 CPP (1.04); Filenames may contain spaces
- * 14-Dec-94 CPP (1.16); Fix message indicator for >4 colors
- * 14-Dec-94 CPP (1.17); Fix button gadgets for >4 colors
- * 5-Jan-95 CPP (1.18); Use system default font if possible
- * 17-Jan-95 CPP (1.20); Size shells nicely
- * 26-Jan-95 CPP (1.26); Allow largest possible font size
- * 27-Jan-95 CPP (1.27); Report window open failure
- * 28-Jan-95 CPP (1.29); Labeled radio buttons
- * 28-Jan-95 CPP (1.30); Tall action buttons
- * 6-Feb-95 CPP (1.31); Progress requester gadgets
- * 6-Feb-95 CPP (1.32); Render to window while requester on
- * 10-Feb-95 CPP (1.34); Thicker requester borders
- *
- * Comments: Workbench GUI. Amiga Dependent!
- * There may be other toolkits. Mine is intended to be
- * compatible with all releases of AmigaDOS, be fairly
- * simple, and have a 3d-like look. I've had to make
- * some small compromises: non-toggle gadgets only
- * have their borders change when selected (the only good way
- * to get around this is to have multiple images...with about
- * an order of magnitude increase in complexity...or by using
- * BOOPSI, which is fairly complicated itself and 2.0+
- * dependent, or use MUI, which would not only necessitate
- * a complete re-write but also would introduce some copyright
- * inconsistencies. So, my rationalization anyway is that
- * there is no _perfect_ choice, and the only better choices
- * would take much more of my time to implement. I haven't
- * made enough money on it so far to justify that.
- */
-
- #ifdef AMIGA
- #define GUI_DEBUG
-
- #include <stdio.h> /* sprintf() */
- #include <string.h>
- /*
- * Amiga includes
- */
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <workbench/workbench.h>
- #include <workbench/icon.h>
- #include <workbench/startup.h>
- #include <intuition/intuition.h>
- #include <intuition/sghooks.h>
- #include <clib/intuition_protos.h>
- #include <clib/exec_protos.h>
- #include <proto/icon.h>
- #include <proto/dos.h>
- #include <dos/dos.h>
- #include <libraries/asl.h>
- #include <clib/asl_protos.h>
- #include <graphics/text.h>
- #include <clib/graphics_protos.h>
- #include <graphics/gfxmacros.h> /* BNDRYOFF */
- #include <proto/graphics.h> /* GfxBase */
- #include <graphics/gfxbase.h>
-
- #include "gfft.h"
- #include "wbench.h"
- #include "settings.h"
-
- #define USE_MAX_ROWS_FOR_FONT_CHECK
-
- /*
- * Dialogue Window parameters...pretty good guesses for 2.0 and 1.3
- * reset later (some require drawinfo to be available for reset)
- */
- #define SHINE_PEN_20 2
- #define SHADOW_PEN_20 1
- #define SHINE_PEN_13 1
- #define SHADOW_PEN_13 2
- #define TEXT_PEN 1 /* Seems to work well under both 2.0 and 1.3 */
- #define FILL_TEXT_PEN 2 /* ditto; hmmn, I like better than 2.0 default */
- #define FILL_PEN 3
- #define BACKGROUND_PEN 0 /* almost guaranteed now, but may be updated */
-
- #define DEFAULT_SCREEN_DEPTH 2
- #define DEFAULT_SCREEN_FONT_HEIGHT 8
- #define DEFAULT_FONT_HEIGHT 8
- #define DEFAULT_FONT_WIDTH 8
-
- #define FONT_COLUMNS_REQUIRED 80
- #define FONT_ROWS_REQUIRED 24
-
- #define DEFAULT_SHELL_WIDTH 640
- #define DEFAULT_SHELL_HEIGHT 200
-
-
- #define WINDOW_LEFT 0 /* Same as right edge */
- #define WINDOW_TOP 0 /* Allow for WB title & click area above */
-
- #define FIRST_WINDOW_BUTTON_LEFT 12
- #define FIRST_WINDOW_BUTTON_TOP 6
-
- #define FIRST_REQUESTER_BUTTON_LEFT 12
- #define FIRST_REQUESTER_BUTTON_TOP 6
-
- #define BUTTON_SIDE_EDGE (Font_Width)
-
- #define BUTTON_TOP_EDGE 3 /* Inside button to text; same as bottom edge*/
- #define BUTTON_TOP_SPACE 2 /* Vertical space between buttons */
-
- /*
- * Use the following when possible
- */
-
- #define BUTTON_WIDTH(WIDTH) ((WIDTH) * Font_Width + 2 * BUTTON_SIDE_EDGE)
-
- #define BUTTON_HEIGHT (Font_Height + 2 * BUTTON_TOP_EDGE)
- #define BUTTON_SPACING (BUTTON_HEIGHT + BUTTON_TOP_SPACE)
- #define BUTTON_TOP(row) (first_button_top + row * BUTTON_SPACING)
-
- #define WINDOW_HEIGHT(max_rows) (BUTTON_TOP(max_rows) + \
- BUTTON_TOP_SPACE) /* for the bottom edge */
-
- struct TextAttr FontA = {
- "topaz.font",
- DEFAULT_FONT_HEIGHT,
- NULL,
- NULL
- };
-
- struct TextAttr *FontAp = &FontA;
-
- struct TextFont *fontp = NULL; /* Set if system default font used */
-
- static short shine_pen = SHINE_PEN_20;
- static short shadow_pen = SHADOW_PEN_20;
- static short text_pen = TEXT_PEN;
- static short fill_pen = FILL_PEN;
- static short fill_text_pen = FILL_TEXT_PEN;
- static short background_pen = BACKGROUND_PEN;
-
- short Screen_Font_Height = DEFAULT_SCREEN_FONT_HEIGHT;
- short Font_Height = DEFAULT_FONT_HEIGHT;
- short Font_Width = DEFAULT_FONT_WIDTH;
- static short screen_depth = DEFAULT_SCREEN_DEPTH;
-
- static short first_button_left = FIRST_WINDOW_BUTTON_LEFT;
- static short first_button_top = FIRST_WINDOW_BUTTON_TOP +
- DEFAULT_FONT_HEIGHT;
- static short max_rows = 0;
- static int gadget_type_mode = NULL;
- static struct IntuiText *next_textp = NULL;
- static struct Gadget *next_gadgetp = NULL;
- static struct Requester *current_requesterp = NULL;
-
- #define REQUESTER_STACK_DEPTH 10
- static struct Requester *requester_stack[REQUESTER_STACK_DEPTH] =
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
- static int requester_stack_index = 0;
-
-
- struct Library *IntuitionBase = NULL;
- BOOLEAN Old_Intuition = FALSE;
- short Max_Columns = 0;
-
- int Shell_Width = DEFAULT_SHELL_WIDTH;
- int Shell_Height = DEFAULT_SHELL_HEIGHT;
-
-
- extern struct Library *AslBase; /* from filereq.c */
- extern struct FileRequester *File_Requesterp;
-
-
- static struct Gadget *text_button__new (char *text, short tcol, short trow);
-
- void open_libraries (void)
- {
- /*
- * Intuition is currently the only library for which we need to know
- * version number, hence, we have to open it explicitly.
- */
- if (!IntuitionBase)
- {
- IntuitionBase = OpenLibrary ("intuition.library", 37);
- if (IntuitionBase == NULL)
- {
- Old_Intuition = TRUE;
- IntuitionBase = OpenLibrary ("intuition.library", 0);
- if (IntuitionBase == NULL)
- {
- error_message (CANT_OPEN_INTUITION);
- gabort (EXIT_FAILURE);
- }
- }
- }
- }
-
- void setup_window_defaults (int max_rows)
- {
- struct Screen *screen;
- struct DrawInfo *draw_info;
-
- if (Old_Intuition)
- {
- shine_pen = SHINE_PEN_13; /* These usually work for 1.3... */
- shadow_pen = SHADOW_PEN_13; /* Should do this better someday */
- /* everything else is defaulted */
- }
- else /* Ok, Rev 37 or greater, get pens and fonts */
- {
- if (screen = LockPubScreen (NULL))
- {
- if (draw_info = GetScreenDrawInfo (screen))
- {
- /* vars not used outside this block */
- char *system_default_font_name;
- short system_default_font_height;
- short system_default_font_width;
- short screen_width;
- short screen_height;
- short save_font_height;
-
- shine_pen = draw_info->dri_Pens[SHINEPEN];
- shadow_pen = draw_info->dri_Pens[SHADOWPEN];
- text_pen = draw_info->dri_Pens[TEXTPEN];
- fill_pen = draw_info->dri_Pens[FILLPEN];
- fill_text_pen = draw_info->dri_Pens[FILLTEXTPEN];
- background_pen = draw_info->dri_Pens[BACKGROUNDPEN];
- screen_depth = draw_info->dri_Depth;
- screen_width = screen->Width;
- screen_height = screen->Height;
- Screen_Font_Height =
- draw_info->dri_Font->tf_YSize;
- first_button_top = FIRST_WINDOW_BUTTON_TOP +
- Screen_Font_Height;
- /*
- * Get system default font (always monospaced) info...
- * (Maybe if I make some money on this, I'll rewrite to
- * use the screen font (which might be proportional).
- * Test to see that font permits max_rows and
- * FONT_COLUMNS_REQUIRED
- * before using (otherwise, we're defaulting to TOPAZ 8).
- */
- system_default_font_name =
- GfxBase->DefaultFont->tf_Message.mn_Node.ln_Name;
- system_default_font_height =
- GfxBase->DefaultFont->tf_YSize;
- system_default_font_width =
- GfxBase->DefaultFont->tf_XSize;
-
- save_font_height = Font_Height;
- Font_Height = system_default_font_height;
-
- if (!Topaz &&
-
- #ifndef FORCE_FONT
- #ifndef USE_MAX_ROWS_FOR_FONT_CHECK
- (screen_height / system_default_font_height >=
- FONT_ROWS_REQUIRED) &&
- #else
- (WINDOW_HEIGHT(max_rows) <= screen_height) &&
- #endif
- #endif
- (screen_width / system_default_font_width >=
- FONT_COLUMNS_REQUIRED))
- {
- FontA.ta_Name = system_default_font_name;
- FontA.ta_YSize = system_default_font_height;
-
- Font_Height = system_default_font_height;
- Font_Width = system_default_font_width;
-
- fontp = GfxBase->DefaultFont;
-
- /* Looks nicer without resetting shell height, upped later if needed */
-
- Shell_Width = FONT_COLUMNS_REQUIRED *
- system_default_font_width;
- }
- else
- {
- Font_Height = save_font_height;
-
- Shell_Height = FONT_ROWS_REQUIRED *
- system_default_font_height;
-
- Shell_Width = FONT_COLUMNS_REQUIRED *
- system_default_font_width;
-
- if (Shell_Height > screen_height)
- Shell_Height = screen_height;
-
- if (Shell_Width > screen_width)
- Shell_Width = screen_width;
- }
- FreeScreenDrawInfo (screen, draw_info);
- }
- UnlockPubScreen (NULL, screen);
- }
- }
- }
-
- void close_amiga_stuff (void)
- {
- if (IntuitionBase)
- {
- CloseLibrary (IntuitionBase);
- IntuitionBase = NULL;
- }
- if (File_Requesterp)
- {
- FreeAslRequest(File_Requesterp);
- File_Requesterp = NULL;
- }
- if (AslBase)
- {
- CloseLibrary(AslBase);
- AslBase = NULL;
- }
- }
-
-
- void gadget__begin (int gadget_type_flag)
- {
- gadget_type_mode = gadget_type_flag;
- Max_Columns = 0;
- max_rows = 0;
- next_textp = NULL;
- next_gadgetp = NULL;
-
- if (gadget_type_mode == GTYP_REQGADGET)
- {
- first_button_left = FIRST_REQUESTER_BUTTON_LEFT;
- first_button_top = FIRST_REQUESTER_BUTTON_TOP;
- }
- else
- {
- first_button_left = FIRST_WINDOW_BUTTON_LEFT;
- first_button_top = FIRST_WINDOW_BUTTON_TOP + Screen_Font_Height;
- }
- }
-
- struct Border *requester_border__new (short height, short width,
- short top_pen, short bottom_pen)
- {
- struct Border *rborder;
- struct Border *nborder;
-
- rborder = border__new (height-1, width-1, top_pen, bottom_pen);
-
- nborder = rborder->NextBorder->NextBorder = border__new
- (height-3, width-3, top_pen, bottom_pen);
-
- nborder->LeftEdge += 1;
- nborder->TopEdge += 1;
- nborder->NextBorder->LeftEdge += 1;
- nborder->NextBorder->TopEdge += 1;
-
- nborder = nborder->NextBorder->NextBorder = border__new
- (height-5, width-5, top_pen, bottom_pen);
-
- nborder->LeftEdge += 2;
- nborder->TopEdge += 2;
- nborder->NextBorder->LeftEdge += 2;
- nborder->NextBorder->TopEdge += 2;
-
- return rborder;
- }
-
-
- struct Border *button_border__new (short width, short top_pen,
- short bottom_pen)
- {
-
- struct Border *bborder;
-
- bborder = border__new (BUTTON_HEIGHT-1, width-1, top_pen, bottom_pen);
- return bborder;
- }
-
-
- struct Border *border__new (short height, short width, short top_pen,
- short bottom_pen)
- {
- short *xy_pairs_u, *xy_pairs_l;
- struct Border *border_u, *border_l;
-
- xy_pairs_u = gcalloc (6, sizeof (short), NOTHING_SPECIAL);
- xy_pairs_l = gcalloc (6, sizeof (short), NOTHING_SPECIAL);
- border_u = gcalloc (1, sizeof (struct Border), NOTHING_SPECIAL);
- border_l = gcalloc (1, sizeof (struct Border), NOTHING_SPECIAL);
-
- xy_pairs_u[0] = 0;
- xy_pairs_u[1] = height;
- xy_pairs_u[2] = 0;
- xy_pairs_u[3] = 0;
- xy_pairs_u[4] = width;
- xy_pairs_u[5] = 0;
-
- xy_pairs_l[0] = 1; /* Looks a little nicer, I think, than 0 */
- xy_pairs_l[1] = height;
- xy_pairs_l[2] = width;
- xy_pairs_l[3] = height;
- xy_pairs_l[4] = width;
- xy_pairs_l[5] = 0;
-
- border_u->LeftEdge = 0;
- border_u->TopEdge = 0;
- border_u->XY = xy_pairs_u;
- border_u->FrontPen = top_pen;
- border_u->DrawMode = JAM1;
- border_u->NextBorder = border_l;
- border_u->Count = 3;
-
- border_l->LeftEdge = 0;
- border_l->TopEdge = 0;
- border_l->XY = xy_pairs_l;
- border_l->FrontPen = bottom_pen;
- border_l->DrawMode = JAM1;
- border_l->NextBorder = NULL;
- border_l->Count = 3;
-
- return border_u;
- }
-
-
- struct Gadget *progress_gadget__new (short length, short tcol, short trow)
- {
- struct Gadget *gadgetp;
-
- gadgetp = message_gadget__new (length, tcol, trow);
- gadgetp->UserData = NULL;
-
- return gadgetp;
- }
-
- void progress_gadget__clear (struct Gadget *gadgetp, struct Window *windowp)
- {
- gadgetp->UserData = NULL;
- if (gadgetp->GadgetText)
- message_gadget__write (gadgetp, NullString, windowp);
- }
-
- void progress_gadget__update (struct Gadget *gadgetp,
- int percentage,
- struct Window *windowp)
- {
- struct RastPort *rport;
- UBYTE save_apen;
- struct Requester *requesterp;
- int last_percentage = (int) gadgetp->UserData;
-
- if (percentage == -1 || last_percentage == -1)
- {
- if (last_percentage == -1) return;
- message_gadget__write (gadgetp, "Unable to measure progress...",
- windowp);
- gadgetp->UserData = (APTR) -1;
- return;
- }
-
- if (last_percentage >= percentage) return;
- if (percentage > 100 ) percentage = 100;
- gadgetp->UserData = (APTR) percentage;
-
- if (windowp)
- {
- short x1, y1, x2, y2;
-
- x1 = gadgetp->LeftEdge + 3;
- y1 = gadgetp->TopEdge + 2;
-
- x2 = x1 + (gadgetp->Width - 7) * (percentage/100.0);
- y2 = y1 + gadgetp->Height - 5;
-
- RemoveGadget (windowp, gadgetp);
-
- requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- SetAPen (rport, (UBYTE) fill_pen);
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
- }
-
-
- struct Gadget *message_gadget__new (short length, short tcol, short trow)
- {
- struct Gadget *mgadgetp;
-
- mgadgetp = gadget__new (length, tcol, trow);
- mgadgetp->Flags = GFLG_GADGHNONE;
- mgadgetp->Activation = NULL;
- mgadgetp->GadgetRender = button_border__new (BUTTON_WIDTH (length),
- shadow_pen, shine_pen);
- mgadgetp->GadgetText = NULL;
- return mgadgetp;
- }
-
- struct Gadget *labeled_radio_button__new
- (char *label, char *text, short tcol, short trow)
- {
- short button_offset = strlen (label) + 2;
- struct Gadget *gadgetp = radio_button__new (text, tcol + button_offset,
- trow);
- gadgetp->GadgetText->NextText = button_text__new (label);
- gadgetp->GadgetText->NextText->LeftEdge -= BUTTON_SIDE_EDGE*2 +
- strlen (label) * Font_Width;
-
- return gadgetp;
- }
-
- struct Gadget *radio_button__new (char *text, short tcol, short trow)
- {
- struct Gadget *gadgetp;
-
- gadgetp = text_button__new (text, tcol, trow);
-
- gadgetp->SelectRender = button_border__new (BUTTON_WIDTH(strlen (text)),
- shadow_pen, shine_pen);
- gadgetp->Flags = GFLG_GADGHIMAGE;
- gadgetp->Activation &= ~GACT_RELVERIFY;
- gadgetp->Activation &= ~TOGGLESELECT;
- gadgetp->Activation |= GADGIMMEDIATE;
- return gadgetp;
- }
-
- struct Gadget *tall_action_button__new (char *text, short tcol, short trow)
- {
- struct Gadget *gadgetp;
- struct Border *borderp;
-
- gadgetp = action_button__new (text, tcol, trow);
-
- /*
- * Add extra borders to make button appear taller
- */
- if (screen_depth > 1)
- {
- borderp = (struct Border *) gadgetp->GadgetRender;
- borderp->NextBorder->NextBorder = button_border__new
- (BUTTON_WIDTH(strlen (text)), shine_pen,
- shadow_pen);
-
- borderp = borderp->NextBorder->NextBorder;
- borderp->XY[1] += 1;
- #if FALSE
- borderp->XY[0] += 1;
- borderp->XY[2] += 1;
- borderp->XY[3] += 1;
- borderp->XY[4] += -1;
- borderp->XY[5] += 1;
- #endif
-
- borderp = borderp->NextBorder;
- borderp->XY[0] += 0;
- borderp->XY[1] += 1;
- borderp->XY[2] += 1;
- borderp->XY[3] += 1;
- borderp->XY[4] += 1;
- borderp->XY[5] += 1;
-
- borderp = (struct Border *) gadgetp->SelectRender;
- borderp->NextBorder->NextBorder = button_border__new
- (BUTTON_WIDTH(strlen (text)), shadow_pen,
- shine_pen);
-
- borderp = borderp->NextBorder->NextBorder;
- borderp->XY[1] += 1;
- #if FALSE
- borderp->XY[0] += 1;
- borderp->XY[2] += 1;
- borderp->XY[3] += 1;
- borderp->XY[4] += -1;
- borderp->XY[5] += 1;
- #endif
-
- borderp = borderp->NextBorder;
- borderp->XY[0] += 0;
- borderp->XY[1] += 1;
- borderp->XY[2] += 1;
- borderp->XY[3] += 1;
- borderp->XY[4] += 1;
- borderp->XY[5] += 1;
-
- }
- return gadgetp;
- }
-
-
-
- struct Gadget *action_button__new (char *text, short tcol, short trow)
- {
- struct Gadget *gadgetp;
-
- gadgetp = text_button__new (text, tcol, trow);
- if (screen_depth > 1)
- {
- gadgetp->SelectRender = button_border__new
- (BUTTON_WIDTH(strlen (text)), shadow_pen, shine_pen);
- gadgetp->Flags = GFLG_GADGHIMAGE;
- }
- return gadgetp;
- }
-
- static struct Gadget *text_button__new (char *text, short tcol, short trow)
- {
- struct Gadget *gadgetp;
-
- gadgetp = gadget__new (strlen (text), tcol, trow);
- gadgetp->GadgetText = button_text__new (text);
- return gadgetp;
- }
-
- struct Gadget *gadget__new (short length, short tcol, short trow)
- {
- struct Gadget *gadgetp;
- short local_max_column = length + tcol;
-
- if (local_max_column > Max_Columns) Max_Columns = local_max_column;
- if (trow + 1 > max_rows) max_rows = trow + 1;
-
- gadgetp = gcalloc (1, sizeof (struct Gadget), NOTHING_SPECIAL);
-
- gadgetp->NextGadget = next_gadgetp;
- next_gadgetp = gadgetp;
-
- gadgetp->LeftEdge = first_button_left + tcol * Font_Width;
- gadgetp->TopEdge = first_button_top + trow * BUTTON_SPACING;
- gadgetp->Width = BUTTON_WIDTH (length);
- gadgetp->Height = BUTTON_HEIGHT;
- gadgetp->Activation = GACT_RELVERIFY;
- gadgetp->GadgetType = GTYP_BOOLGADGET | gadget_type_mode;
- gadgetp->GadgetRender = button_border__new (BUTTON_WIDTH (length),
- shine_pen, shadow_pen);
- gadgetp->SelectRender = NULL;
- gadgetp->Flags = GFLG_GADGHCOMP;
- gadgetp->GadgetText = NULL;
- gadgetp->MutualExclude = NULL;
- gadgetp->SpecialInfo = NULL;
- gadgetp->GadgetID = NULL;
- gadgetp->UserData = NULL;
- return gadgetp;
- }
-
-
- struct StringInfo *string_info__new (short max_chars, short vis_chars)
- {
- struct StringInfo *string_info;
-
- string_info = gcalloc (1, sizeof (struct StringInfo), NOTHING_SPECIAL);
-
- string_info->Buffer = gcalloc (1, max_chars+1, NOTHING_SPECIAL);
- string_info->MaxChars = max_chars+1;
- string_info->UndoBuffer = NULL;
- string_info->BufferPos = 0;
- string_info->DispPos = 0;
- string_info->CTop = BUTTON_TOP_EDGE;
- string_info->CLeft = BUTTON_SIDE_EDGE;
- string_info->DispCount = vis_chars;
-
-
- if (fontp)
- {
- struct StringExtend *string_extendp =
- gcalloc (1, sizeof (struct StringExtend), NOTHING_SPECIAL);
-
- string_extendp->Font = fontp;
- string_extendp->Pens[0] = text_pen;
- string_extendp->Pens[1] = background_pen;
- string_extendp->ActivePens[0] = text_pen;
- string_extendp->ActivePens[1] = background_pen;
-
- string_info->Extension = string_extendp;
-
- }
-
- return string_info;
- }
-
-
- struct Gadget *string_gadget__new (char *prompt, char *initial_name,
- short max_chars,
- short length, short tcol,
- short trow)
- {
- struct Gadget *string_gadgetp;
- struct Border *borderp;
- struct Border *bottomp;
- short *bottom_xy;
- short right_text_offset, right_border_offset;
- short container_length, container_tcol;
-
- /*
- * (Damn! Intuition doesn't allow user offset for string gadget container
- * offsets within overall gadget area, so must do it manually.)
- */
- container_length = length - (strlen (prompt) + 2);
- container_tcol = tcol + (strlen (prompt) + 2);
-
- string_gadgetp = gadget__new (container_length, container_tcol, trow);
-
- string_gadgetp->GadgetType = GTYP_STRGADGET | gadget_type_mode;
- string_gadgetp->Activation |= GADGIMMEDIATE;
-
- if (fontp) string_gadgetp->Flags |= GFLG_STRINGEXTEND;
-
- string_gadgetp->SpecialInfo = string_info__new (max_chars, length-4);
-
- string_gadgetp->GadgetText = button_text__new (prompt);
-
- right_border_offset = BUTTON_SIDE_EDGE;
- right_text_offset = BUTTON_SIDE_EDGE*2 + strlen (prompt) *
- Font_Width + right_border_offset;
-
- string_gadgetp->GadgetText->LeftEdge -= right_text_offset;
-
- string_gadgetp->LeftEdge += right_border_offset;
- borderp = (struct Border *) string_gadgetp->GadgetRender;
- borderp->XY[0] -= right_border_offset;
- borderp->XY[2] -= right_border_offset;
- borderp->XY[4] -= right_border_offset;
- borderp = borderp->NextBorder;
- borderp->XY[0] -= right_border_offset;
- borderp->XY[2] -= right_border_offset;
- borderp->XY[4] -= right_border_offset;
- string_gadgetp->Width -= right_border_offset + BUTTON_SIDE_EDGE;
-
- string_gadgetp->TopEdge += BUTTON_TOP_EDGE;
- string_gadgetp->GadgetText->TopEdge -= BUTTON_TOP_EDGE;
- borderp = (struct Border *) string_gadgetp->GadgetRender;
- borderp->XY[1] -= BUTTON_TOP_EDGE;
- borderp->XY[3] -= BUTTON_TOP_EDGE;
- borderp->XY[5] -= BUTTON_TOP_EDGE;
- borderp = borderp->NextBorder;
- borderp->XY[1] -= BUTTON_TOP_EDGE;
- borderp->XY[3] -= BUTTON_TOP_EDGE;
- borderp->XY[5] -= BUTTON_TOP_EDGE;
- string_gadgetp->Height -= BUTTON_TOP_EDGE * 2;
- /*
- * Add "bottom line"
- */
- bottomp = gcalloc (1, sizeof (struct Border), NOTHING_SPECIAL);
- bottom_xy = gcalloc (4, sizeof (short), NOTHING_SPECIAL);
-
- bottom_xy[0] = 0;
- bottom_xy[1] = Font_Height;
- bottom_xy[2] = container_length * Font_Width;
- bottom_xy[3] = Font_Height;
-
- bottomp->LeftEdge = 0;
- bottomp->TopEdge = 0;
- bottomp->XY = bottom_xy;
- bottomp->FrontPen = shadow_pen;
- bottomp->DrawMode = JAM1;
- bottomp->NextBorder = NULL;
- bottomp->Count = 2;
-
- borderp->NextBorder = bottomp;
-
- if (initial_name)
- {
- struct StringInfo *string_info = string_gadgetp->SpecialInfo;
- strcpy (string_info->Buffer, initial_name);
- }
-
- return string_gadgetp;
- }
-
-
- struct IntuiText *requester_text__new (char *text, short tcol, short trow)
- {
- struct IntuiText *textst;
- short local_max_column = tcol + strlen (text);
-
- if (local_max_column > Max_Columns) Max_Columns = local_max_column;
- if (trow + 1 > max_rows) max_rows = trow + 1;
-
- textst = button_text__new (text);
- textst->LeftEdge = first_button_left + BUTTON_SIDE_EDGE +
- tcol * Font_Width;
- textst->TopEdge = BUTTON_TOP_EDGE + BUTTON_TOP(trow);
- textst->NextText = next_textp;
- next_textp = textst;
-
- return textst;
- }
-
- struct IntuiText *button_text__new (char *text)
- {
- struct IntuiText *textst;
-
- textst = gcalloc (1, sizeof (struct IntuiText), NOTHING_SPECIAL);
-
- textst->FrontPen = text_pen;
- textst->BackPen = background_pen;
- textst->DrawMode = JAM1;
- textst->LeftEdge = BUTTON_SIDE_EDGE;
- textst->TopEdge = BUTTON_TOP_EDGE;
- textst->ITextFont = FontAp;
- /* textst->ITextFont = NULL; This gives screen font, may be prop font */
- textst->IText = text;
- textst->NextText = NULL;
- return textst;
- }
-
- void refresh_gadget (struct Gadget *gadgetp, struct Window *windowp)
- {
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- RefreshGList (gadgetp, windowp, requesterp, 1);
- }
-
- void toggle_button__toggle (struct Gadget *gadgetp,
- char *(*on_function)(char *arg),
- char *(*off_function)(char *arg),
- struct Window *windowp)
- {
- if (!(gadgetp->Flags & GFLG_SELECTED))
- {
- (*off_function) (NullString);
- }
- else
- {
- (*on_function) (NullString);
- }
- }
-
- void radio_button__toggle (struct Gadget *gadgetp,
- char *(*on_function)(char *arg),
- char *(*off_function)(char *arg),
- struct Window *windowp)
- {
- /*
- * Must do imagery here for radio buttons
- */
- if (gadgetp->Flags & GFLG_SELECTED)
- {
- (*off_function) (NullString);
- radio_button__out (gadgetp, windowp);
- }
- else
- {
- (*on_function) (NullString);
- radio_button__in (gadgetp, windowp);
- }
- }
-
- char *string_gadget__apply (struct Gadget *string_gadgetp,
- char *(*apply_function)(char *arg))
- {
- struct StringInfo *string_infop =
- string_gadgetp->SpecialInfo;
- char *buffer = string_infop->Buffer;
- buffer[string_infop->NumChars] = '\0';
- (*apply_function) (buffer);
- return buffer;
- }
-
- /*
- * (1.04) Names in requesters may include spaces, so
- * must be quoted
- */
- char *name_string_gadget__apply (struct Gadget *string_gadgetp,
- char *(*apply_function)(char *arg))
- {
- char *enquote_buffer;
- struct StringInfo *string_infop =
- string_gadgetp->SpecialInfo;
- char *buffer = string_infop->Buffer;
- buffer[string_infop->NumChars] = '\0';
-
- if (!string_infop->NumChars)
- {
- (*apply_function) (buffer); /* Null String; don't enquote */
- }
- else
- {
- enquote_buffer = gmalloc (string_infop->NumChars + 8,
- NOTHING_SPECIAL);
- sprintf (enquote_buffer, "\"%s\"", buffer);
- (*apply_function) (enquote_buffer);
- gfree (enquote_buffer);
- }
- return buffer;
- }
-
- void string_gadget__reset (struct Gadget *string_gadgetp,
- char *new_string,
- struct Window *windowp)
- {
- struct StringInfo *string_infop =
- string_gadgetp->SpecialInfo;
- char *buffer = string_infop->Buffer;
- int string_length = 0;
- if (!new_string || (string_length = strlen (new_string)) <= 0)
- {
- buffer[0] = '\0';
- }
- else
- {
- strcpy (buffer, new_string);
- }
- string_infop->NumChars = string_length;
- refresh_gadget (string_gadgetp, windowp);
- }
-
-
- void message_requester (struct Window *windowp, char *message_text)
- {
- extern char *Got_It_S;
- struct IntuiText *mtextp = button_text__new (message_text);
- struct IntuiText *got_it_textp = button_text__new (Got_It_S);
-
- if (Old_Intuition)
- {
- mtextp->DrawMode = JAM2 | INVERSVID;
- got_it_textp->DrawMode = JAM2 | INVERSVID;
- }
-
- AutoRequest (windowp, mtextp, NULL, got_it_textp,
- IDCMP_GADGETDOWN,
- IDCMP_GADGETDOWN, 640, 50);
-
- gfree (mtextp);
- gfree (got_it_textp);
- }
-
- /*
- * I have decided NOT to follow the guidelines for 'mutually exclusive'
- * gadgets on page 140 of the Amiga Rom Kernel Reference Manual, Third
- * Edition, which specifically advise against this combination (mutually
- * exclusive gadgets using 'complementing'--though I don't really use
- * 'complementing' here anymore--I use explicit colors to be compatible with
- * larger numbers of colors).
- *
- * However, I have chosen instead to follow the guidelines for 'Updating
- * a Gadget's Imagery' on pages 129-130. Before a radio_button is
- * refreshed in either selected or unselected state, the background
- * behind it is restored ("cleared") with RectFill. I do this very
- * carefully as you will see.
- *
- * This concept has been extended to cover other features, such as
- * gadget disable and enable, which I couldn't get to work before.
- *
- * This should be acceptable and stable with future released of Intuition.
- * At least, there is some hope. And it works with 1.2-2.1 for sure.
- *
- * It now even handles requester gadgets properly.
- */
-
- void radio_button__in (struct Gadget *gadgetp, struct Window *windowp)
- {
- struct RastPort *rport;
- short x1, y1, x2, y2;
- UBYTE save_apen; /* I preserve this one, dunno if necessary */
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- if (windowp)
- {
- /* if (!(gadgetp->Flags & GFLG_SELECTED)) /* pushing my luck too far*/
- {
- RemoveGadget (windowp, gadgetp);
- gadgetp->Flags |= GFLG_SELECTED;
- gadgetp->GadgetText->FrontPen = fill_text_pen;
- gadgetp->GadgetText->BackPen = fill_pen;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- SetAPen (rport, (UBYTE) fill_pen);
- SetDrMd (rport, JAM1);
- SetAfPt (rport, NULL, 0);
- SetWrMsk (rport, (UBYTE) 0xff);
- BNDRYOFF (rport);
- x1 = gadgetp->LeftEdge;
- y1 = gadgetp->TopEdge;
- x2 = x1 + gadgetp->Width - 1;
- y2 = y1 + gadgetp->Height - 1;
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
- }
- else /* if (!windowp) */
- {
- gadgetp->Flags |= GFLG_SELECTED;
- }
- }
-
- void radio_button__out (struct Gadget *gadgetp, struct Window *windowp)
- {
- struct RastPort *rport;
- short x1, y1, x2, y2;
- UBYTE save_apen; /* I preserve this one, dunno if necessary */
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- if (windowp)
- {
- if (gadgetp->Flags & GFLG_SELECTED)
- {
- RemoveGadget (windowp, gadgetp);
- gadgetp->Flags &= ~GFLG_SELECTED;
- gadgetp->GadgetText->FrontPen = text_pen;
- gadgetp->GadgetText->BackPen = background_pen;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- SetAPen (rport, (UBYTE) background_pen);
- SetDrMd (rport, JAM1);
- SetAfPt (rport, NULL, 0);
- SetWrMsk (rport, (UBYTE) 0xff);
- BNDRYOFF (rport);
- x1 = gadgetp->LeftEdge;
- y1 = gadgetp->TopEdge;
- x2 = x1 + gadgetp->Width - 1;
- y2 = y1 + gadgetp->Height - 1;
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
- }
- else /* if (!windowp) */
- {
- gadgetp->Flags &= ~GFLG_SELECTED;
- }
- }
-
- void gadget__disable (struct Gadget *gadgetp, struct Window *windowp)
- {
- struct RastPort *rport;
- short x1, y1, x2, y2;
- UBYTE save_apen; /* I preserve this one, dunno if necessary */
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- if (gadgetp->Flags & GFLG_DISABLED) return;
-
- if (!windowp)
- {
- gadgetp->Flags |= GFLG_DISABLED;
- return;
- }
-
- RemoveGadget (windowp, gadgetp);
- gadgetp->Flags |= GFLG_DISABLED;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- if (gadgetp->Flags & GFLG_SELECTED)
- {
- SetAPen (rport, (UBYTE) fill_pen);
- }
- else
- {
- SetAPen (rport, (UBYTE) background_pen);
- }
- SetDrMd (rport, JAM1);
- SetAfPt (rport, NULL, 0);
- SetWrMsk (rport, (UBYTE) 0xff);
- BNDRYOFF (rport);
- x1 = gadgetp->LeftEdge;
- y1 = gadgetp->TopEdge;
- x2 = x1 + gadgetp->Width - 1;
- y2 = y1 + gadgetp->Height - 1;
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
-
- void gadget__enable (struct Gadget *gadgetp, struct Window *windowp)
- {
- struct RastPort *rport;
- short x1, y1, x2, y2;
- UBYTE save_apen; /* I preserve this one, dunno if necessary */
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- if (!(gadgetp->Flags & GFLG_DISABLED)) return;
-
- if (!windowp)
- {
- gadgetp->Flags |= GFLG_DISABLED;
- return;
- }
-
- /* Yes, of course, OnGadget isn't smart enough for border gadgets */
-
- RemoveGadget (windowp, gadgetp);
- gadgetp->Flags &= ~GFLG_DISABLED;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- if (gadgetp->Flags & GFLG_SELECTED)
- {
- SetAPen (rport, (UBYTE) fill_pen);
- }
- else
- {
- SetAPen (rport, (UBYTE) background_pen);
- }
- SetDrMd (rport, JAM1);
- SetAfPt (rport, NULL, 0);
- SetWrMsk (rport, (UBYTE) 0xff);
- BNDRYOFF (rport);
- x1 = gadgetp->LeftEdge;
- y1 = gadgetp->TopEdge;
- x2 = x1 + gadgetp->Width - 1;
- y2 = y1 + gadgetp->Height - 1;
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
-
-
- void message_gadget__write (struct Gadget *gadgetp, char *message, struct
- Window *windowp)
- {
- struct RastPort *rport;
- UBYTE save_apen; /* I preserve this one, dunno if necessary */
- struct Requester *requesterp =
- (gadgetp->GadgetType & GTYP_REQGADGET) ?
- current_requesterp :
- NULL;
-
- if (windowp) RemoveGadget (windowp, gadgetp);
-
- if (gadgetp->GadgetText) gfree (gadgetp->GadgetText);
- if (!message || !strlen(message))
- {
- gadgetp->GadgetText = NULL;
- }
- else
- {
- gadgetp->GadgetText = button_text__new (message);
- }
-
- /* gadgetp->GadgetText->FrontPen = fill_text_pen; */
-
- if (windowp)
- {
- short x1, y1, x2, y2;
-
- x1 = gadgetp->LeftEdge;
- y1 = gadgetp->TopEdge;
- x2 = x1 + gadgetp->Width - 1;
- y2 = y1 + gadgetp->Height - 1;
-
- rport = (requesterp) ?
- requesterp->ReqLayer->rp :
- windowp->RPort;
-
- save_apen = rport->FgPen;
-
- SetAPen (rport, (UBYTE) background_pen);
-
- RectFill (rport, x1, y1, x2, y2);
-
- SetAPen (rport, (UBYTE) save_apen);
-
- AddGList (windowp, gadgetp, -1, 1, requesterp);
- refresh_gadget (gadgetp, windowp);
- }
- }
-
- struct Window *window__new (char *title)
- {
- struct NewWindow new_window; /* parameter structure to create window */
- struct Window *windowp = NULL;
- short height = WINDOW_HEIGHT (max_rows);
-
- short width = (Max_Columns * Font_Width) +
- (2 * (FIRST_WINDOW_BUTTON_LEFT + BUTTON_SIDE_EDGE));
-
- if (Shell_Height < height) Shell_Height = height;
- if (Shell_Width < width) Shell_Width = width;
-
- new_window.LeftEdge = WINDOW_LEFT;
- new_window.TopEdge = WINDOW_TOP;
- new_window.Height = height;
- new_window.Width = width;
- new_window.DetailPen = 0;
- new_window.BlockPen = 1;
- new_window.Title = title;
- new_window.Flags = SMART_REFRESH | ACTIVATE | WINDOWCLOSE |
- WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH;
- new_window.IDCMPFlags = IDCMP_CLOSEWINDOW | IDCMP_GADGETUP |
- IDCMP_GADGETDOWN | IDCMP_RAWKEY;
- if (Old_Intuition)
- {
- new_window.Type = WBENCHSCREEN;
- }
- else
- {
- new_window.Type = PUBLICSCREEN; /* It's the latest thing */
- }
- new_window.FirstGadget = next_gadgetp;
- new_window.Screen = NULL;
- new_window.BitMap = NULL;
- new_window.MinWidth = 0;
- new_window.MinHeight = 0;
- new_window.MaxWidth = 0;
- new_window.MaxHeight = 0;
-
- /* Try to open the window. Like the call to OpenLibrary(), if
- * the OpenWindow call is successful, it returns a pointer to
- * the structure for your new window. If the OpenWindow() call
- * fails, it returns a zero.
- */
- if ((windowp = (struct Window *) OpenWindow (&new_window)) == NULL )
- {
- error_message (WINDOW_OPEN_FAILED);
- gabort (EXIT_FAILURE);
- }
- return windowp;
- }
-
- struct Requester *requester__new (void)
- {
- struct Requester *requesterp;
- short height = (max_rows * (Font_Height + (2 * BUTTON_TOP_EDGE)))
- + ((max_rows - 1) * BUTTON_TOP_SPACE) +
- + (2 * FIRST_REQUESTER_BUTTON_TOP);
- short width = (Max_Columns * Font_Width) +
- (2 * (FIRST_REQUESTER_BUTTON_LEFT + BUTTON_SIDE_EDGE));
-
- requesterp = gmalloc (sizeof (struct Requester), NOTHING_SPECIAL);
- InitRequester (requesterp);
- requesterp->BackFill = background_pen;
- requesterp->ReqBorder = requester_border__new (height, width, shine_pen,
- shadow_pen);
- requesterp->Width = width;
- requesterp->Height = height;
- requesterp->RelLeft = 0;
- requesterp->RelTop = 0;
- requesterp->Flags = POINTREL;
- return requesterp;
- }
-
- BOOLEAN requester__display (struct Requester *rp, struct Window *wp)
- {
- if (Request (rp, wp))
- {
- if (++requester_stack_index >= REQUESTER_STACK_DEPTH)
- {
- error_message (REQUESTER_STACK_OVERFLOW);
- EndRequest (rp, wp);
- return FALSE;
- }
- requester_stack[requester_stack_index] = current_requesterp;
- current_requesterp = rp;
- return TRUE;
- }
- return FALSE;
- }
-
- void requester__remove (struct Requester *rp, struct Window *wp)
- {
- current_requesterp = requester_stack[requester_stack_index];
- if (requester_stack_index) requester_stack_index--;
-
- EndRequest (rp, wp);
- }
-
- BOOLEAN ignore_tooltype (char *tooltype)
- {
- if (!strncmp (tooltype, "TOOLPRI", 7)) return TRUE;
- if (!strncmp (tooltype, "STARTPRI", 8)) return TRUE;
- if (!strncmp (tooltype, "DONOTWAIT", 9)) return TRUE;
- if (!strncmp (tooltype, "FILETYPE", 8)) return TRUE;
- if (!strncmp (tooltype, "DUMMY", 5)) return TRUE;
- return FALSE;
- }
-
-
- #endif /* ifdef AMIGA */
-
-